Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a576b04cf |
@@ -9,6 +9,8 @@ import logging
|
|||||||
|
|
||||||
from src.config import config
|
from src.config import config
|
||||||
from src.logging_config import get_logger
|
from src.logging_config import get_logger
|
||||||
|
from src.retry import retry, retry_on_exception
|
||||||
|
from src.error_handler import NetworkError, ConfigurationError
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
@@ -33,7 +35,7 @@ class ConfluenceClient:
|
|||||||
self.token = token or config.CONFLUENCE_TOKEN
|
self.token = token or config.CONFLUENCE_TOKEN
|
||||||
|
|
||||||
if not self.base_url or not self.token:
|
if not self.base_url or not self.token:
|
||||||
raise ConfluenceClientError("Confluence配置不完整,请检查环境变量")
|
raise ConfigurationError("Confluence配置不完整,请检查环境变量")
|
||||||
|
|
||||||
self.headers = {
|
self.headers = {
|
||||||
'Authorization': f'Bearer {self.token}',
|
'Authorization': f'Bearer {self.token}',
|
||||||
@@ -47,6 +49,11 @@ class ConfluenceClient:
|
|||||||
|
|
||||||
logger.debug(f"Confluence客户端初始化完成,基础URL: {self.base_url}")
|
logger.debug(f"Confluence客户端初始化完成,基础URL: {self.base_url}")
|
||||||
|
|
||||||
|
@retry_on_exception(
|
||||||
|
exception_type=requests.exceptions.RequestException,
|
||||||
|
max_attempts=3,
|
||||||
|
delay=2.0
|
||||||
|
)
|
||||||
def fetch_content(self, content_id: str, expand: str = 'body.storage') -> Dict[str, Any]:
|
def fetch_content(self, content_id: str, expand: str = 'body.storage') -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
获取页面内容
|
获取页面内容
|
||||||
@@ -60,7 +67,7 @@ class ConfluenceClient:
|
|||||||
|
|
||||||
异常:
|
异常:
|
||||||
ConfluenceClientError: API调用失败
|
ConfluenceClientError: API调用失败
|
||||||
requests.exceptions.RequestException: 网络请求失败
|
NetworkError: 网络请求失败
|
||||||
"""
|
"""
|
||||||
url = f'{self.base_url}/content/{content_id}'
|
url = f'{self.base_url}/content/{content_id}'
|
||||||
params = {'expand': expand}
|
params = {'expand': expand}
|
||||||
@@ -78,12 +85,12 @@ class ConfluenceClient:
|
|||||||
status_code = e.response.status_code if e.response else '未知'
|
status_code = e.response.status_code if e.response else '未知'
|
||||||
error_msg = f"Confluence API HTTP错误: {status_code}, URL: {url}"
|
error_msg = f"Confluence API HTTP错误: {status_code}, URL: {url}"
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
raise ConfluenceClientError(error_msg) from e
|
raise NetworkError(error_msg) from e
|
||||||
|
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
error_msg = f"Confluence API 网络错误: {e}"
|
error_msg = f"Confluence API 网络错误: {e}"
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
raise ConfluenceClientError(error_msg) from e
|
raise NetworkError(error_msg) from e
|
||||||
|
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
error_msg = f"Confluence API 响应解析失败: {e}"
|
error_msg = f"Confluence API 响应解析失败: {e}"
|
||||||
|
|||||||
BIN
src/data/daily_logs.db
Normal file
BIN
src/data/daily_logs.db
Normal file
Binary file not shown.
@@ -8,6 +8,7 @@ from datetime import datetime
|
|||||||
|
|
||||||
from src.database.base import DatabaseBase
|
from src.database.base import DatabaseBase
|
||||||
from src.logging_config import get_logger
|
from src.logging_config import get_logger
|
||||||
|
from src.error_handler import DatabaseError, ValidationError, validate_input, handle_errors
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
@@ -88,6 +89,10 @@ class DailyLogsDatabase(DatabaseBase):
|
|||||||
# 创建索引
|
# 创建索引
|
||||||
cursor.execute('CREATE INDEX IF NOT EXISTS idx_date ON daily_handover_logs(date)')
|
cursor.execute('CREATE INDEX IF NOT EXISTS idx_date ON daily_handover_logs(date)')
|
||||||
cursor.execute('CREATE INDEX IF NOT EXISTS idx_ship ON daily_handover_logs(ship_name)')
|
cursor.execute('CREATE INDEX IF NOT EXISTS idx_ship ON daily_handover_logs(ship_name)')
|
||||||
|
# 创建复合索引优化常用查询
|
||||||
|
cursor.execute('CREATE INDEX IF NOT EXISTS idx_date_shift ON daily_handover_logs(date, shift)')
|
||||||
|
cursor.execute('CREATE INDEX IF NOT EXISTS idx_date_ship ON daily_handover_logs(date, ship_name)')
|
||||||
|
cursor.execute('CREATE INDEX IF NOT EXISTS idx_date_shift_ship ON daily_handover_logs(date, shift, ship_name)')
|
||||||
|
|
||||||
# 创建未统计月报数据表
|
# 创建未统计月报数据表
|
||||||
cursor.execute('''
|
cursor.execute('''
|
||||||
@@ -163,8 +168,20 @@ class DailyLogsDatabase(DatabaseBase):
|
|||||||
|
|
||||||
返回:
|
返回:
|
||||||
是否成功
|
是否成功
|
||||||
|
|
||||||
|
异常:
|
||||||
|
ValidationError: 输入验证失败
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
# 验证输入
|
||||||
|
validate_input(
|
||||||
|
date=log.get('date'),
|
||||||
|
ship_name=log.get('ship_name'),
|
||||||
|
teu=log.get('teu'),
|
||||||
|
twenty_feet=log.get('twenty_feet'),
|
||||||
|
forty_feet=log.get('forty_feet')
|
||||||
|
)
|
||||||
|
|
||||||
query = '''
|
query = '''
|
||||||
INSERT OR REPLACE INTO daily_handover_logs
|
INSERT OR REPLACE INTO daily_handover_logs
|
||||||
(date, shift, ship_name, teu, efficiency, vehicles, twenty_feet, forty_feet, created_at)
|
(date, shift, ship_name, teu, efficiency, vehicles, twenty_feet, forty_feet, created_at)
|
||||||
@@ -180,13 +197,15 @@ class DailyLogsDatabase(DatabaseBase):
|
|||||||
logger.debug(f"插入记录: {log['date']} {log['shift']} {log['ship_name']}")
|
logger.debug(f"插入记录: {log['date']} {log['shift']} {log['ship_name']}")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
except ValidationError:
|
||||||
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"插入记录失败: {e}, 记录: {log}")
|
logger.error(f"插入记录失败: {e}, 记录: {log}")
|
||||||
return False
|
raise DatabaseError(f"插入记录失败: {e}") from e
|
||||||
|
|
||||||
def insert_many(self, logs: List[Dict[str, Any]]) -> int:
|
def insert_many(self, logs: List[Dict[str, Any]]) -> int:
|
||||||
"""
|
"""
|
||||||
批量插入
|
批量插入(使用 executemany 优化性能)
|
||||||
|
|
||||||
参数:
|
参数:
|
||||||
logs: 日志记录列表
|
logs: 日志记录列表
|
||||||
@@ -194,14 +213,34 @@ class DailyLogsDatabase(DatabaseBase):
|
|||||||
返回:
|
返回:
|
||||||
成功插入的数量
|
成功插入的数量
|
||||||
"""
|
"""
|
||||||
count = 0
|
if not logs:
|
||||||
for log in logs:
|
logger.warning("批量插入:日志列表为空")
|
||||||
if self.insert(log):
|
return 0
|
||||||
count += 1
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
query = '''
|
||||||
|
INSERT OR REPLACE INTO daily_handover_logs
|
||||||
|
(date, shift, ship_name, teu, efficiency, vehicles, twenty_feet, forty_feet, created_at)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
|
||||||
|
'''
|
||||||
|
|
||||||
|
params_list = [
|
||||||
|
(
|
||||||
|
log['date'], log['shift'], log['ship_name'],
|
||||||
|
log.get('teu'), log.get('efficiency'), log.get('vehicles'),
|
||||||
|
log.get('twenty_feet'), log.get('forty_feet')
|
||||||
|
)
|
||||||
|
for log in logs
|
||||||
|
]
|
||||||
|
|
||||||
|
count = self.execute_many(query, params_list)
|
||||||
logger.info(f"批量插入完成,成功 {count}/{len(logs)} 条记录")
|
logger.info(f"批量插入完成,成功 {count}/{len(logs)} 条记录")
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"批量插入失败: {e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
def query_by_date(self, date: str) -> List[Dict[str, Any]]:
|
def query_by_date(self, date: str) -> List[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
按日期查询
|
按日期查询
|
||||||
@@ -387,6 +426,100 @@ class DailyLogsDatabase(DatabaseBase):
|
|||||||
logger.error(f"减少未统计数据失败: {e}")
|
logger.error(f"减少未统计数据失败: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def exclude_actual_teu(self, date: str, ship_name: str, teu: int,
|
||||||
|
twenty_feet: int = 0, forty_feet: int = 0,
|
||||||
|
reason: str = '') -> bool:
|
||||||
|
"""
|
||||||
|
直接剔除部分实际作业量
|
||||||
|
|
||||||
|
参数:
|
||||||
|
date: 日期字符串,格式 "2025-12-30"
|
||||||
|
ship_name: 船名
|
||||||
|
teu: 要剔除的TEU数量
|
||||||
|
twenty_feet: 要剔除的20尺箱量
|
||||||
|
forty_feet: 要剔除的40尺箱量
|
||||||
|
reason: 剔除原因
|
||||||
|
|
||||||
|
返回:
|
||||||
|
是否成功
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 1. 首先检查该船只在指定日期是否存在
|
||||||
|
logs = self.query_by_date(date)
|
||||||
|
ship_exists = any(log['ship_name'] == ship_name for log in logs)
|
||||||
|
|
||||||
|
if not ship_exists:
|
||||||
|
logger.warning(f"船只 {ship_name} 在 {date} 不存在,仍将添加剔除记录")
|
||||||
|
|
||||||
|
# 2. 插入剔除记录到手动调整表
|
||||||
|
exclude_success = self.insert_manual_adjustment(
|
||||||
|
date=date,
|
||||||
|
ship_name=ship_name,
|
||||||
|
teu=teu,
|
||||||
|
twenty_feet=twenty_feet,
|
||||||
|
forty_feet=forty_feet,
|
||||||
|
adjustment_type='exclude',
|
||||||
|
note=f"直接剔除实际作业量",
|
||||||
|
reason=reason,
|
||||||
|
status='processed'
|
||||||
|
)
|
||||||
|
|
||||||
|
if exclude_success:
|
||||||
|
logger.info(f"直接剔除实际作业量: {date} {ship_name} {teu}TEU")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.error(f"直接剔除实际作业量失败: {date} {ship_name} {teu}TEU")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"直接剔除实际作业量失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def exclude_teu_by_amount(self, teu: int, twenty_feet: int = 0, forty_feet: int = 0, reason: str = '') -> bool:
|
||||||
|
"""
|
||||||
|
单独剔除TEU数量(不需要船名和日期)
|
||||||
|
直接剔除指定数量的TEU,不关联到具体船只和日期
|
||||||
|
|
||||||
|
参数:
|
||||||
|
teu: 要剔除的TEU数量
|
||||||
|
twenty_feet: 要剔除的20尺箱量
|
||||||
|
forty_feet: 要剔除的40尺箱量
|
||||||
|
reason: 剔除原因
|
||||||
|
|
||||||
|
返回:
|
||||||
|
是否成功
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 使用当前日期作为默认日期
|
||||||
|
default_date = datetime.now().strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
# 使用通用船名标识
|
||||||
|
default_ship_name = '通用剔除'
|
||||||
|
|
||||||
|
# 插入剔除记录到手动调整表
|
||||||
|
exclude_success = self.insert_manual_adjustment(
|
||||||
|
date=default_date,
|
||||||
|
ship_name=default_ship_name,
|
||||||
|
teu=teu,
|
||||||
|
twenty_feet=twenty_feet,
|
||||||
|
forty_feet=forty_feet,
|
||||||
|
adjustment_type='exclude',
|
||||||
|
note=f"单独剔除TEU数量",
|
||||||
|
reason=reason,
|
||||||
|
status='processed'
|
||||||
|
)
|
||||||
|
|
||||||
|
if exclude_success:
|
||||||
|
logger.info(f"单独剔除TEU数量: {teu}TEU")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.error(f"单独剔除TEU数量失败: {teu}TEU")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"单独剔除TEU数量失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
def delete_unaccounted(self, year_month: str) -> bool:
|
def delete_unaccounted(self, year_month: str) -> bool:
|
||||||
"""
|
"""
|
||||||
删除指定月份的未统计数据
|
删除指定月份的未统计数据
|
||||||
@@ -497,6 +630,22 @@ class DailyLogsDatabase(DatabaseBase):
|
|||||||
'''
|
'''
|
||||||
return self.execute_query(query, (date, adjustment_type))
|
return self.execute_query(query, (date, adjustment_type))
|
||||||
|
|
||||||
|
def get_monthly_adjustments(self, year_month: str) -> List[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
获取指定月份的所有调整数据
|
||||||
|
|
||||||
|
参数:
|
||||||
|
year_month: 年月字符串,格式 "YYYY-MM"
|
||||||
|
|
||||||
|
返回:
|
||||||
|
手动调整数据列表
|
||||||
|
"""
|
||||||
|
query = '''
|
||||||
|
SELECT * FROM manual_adjustments
|
||||||
|
WHERE date LIKE ? ORDER BY created_at DESC
|
||||||
|
'''
|
||||||
|
return self.execute_query(query, (f'{year_month}%',))
|
||||||
|
|
||||||
def get_cross_month_adjustments(self, source_date: str = None, target_date: str = None,
|
def get_cross_month_adjustments(self, source_date: str = None, target_date: str = None,
|
||||||
status: str = None) -> List[Dict[str, Any]]:
|
status: str = None) -> List[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
|
|||||||
348
src/error_handler.py
Normal file
348
src/error_handler.py
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
统一错误处理模块
|
||||||
|
提供自定义异常类和错误处理装饰器
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
from functools import wraps
|
||||||
|
from typing import Callable, Any, Optional, Type
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from src.logging_config import get_logger
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class OrbitInError(Exception):
|
||||||
|
"""OrbitIn 基础异常类"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationError(OrbitInError):
|
||||||
|
"""验证错误"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigurationError(OrbitInError):
|
||||||
|
"""配置错误"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseError(OrbitInError):
|
||||||
|
"""数据库错误"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkError(OrbitInError):
|
||||||
|
"""网络错误"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ParsingError(OrbitInError):
|
||||||
|
"""解析错误"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ReportError(OrbitInError):
|
||||||
|
"""报表生成错误"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def handle_errors(
|
||||||
|
default_return: Any = None,
|
||||||
|
reraise: bool = False,
|
||||||
|
log_level: int = logging.ERROR,
|
||||||
|
exception_types: Optional[tuple] = None
|
||||||
|
) -> Callable:
|
||||||
|
"""
|
||||||
|
错误处理装饰器
|
||||||
|
|
||||||
|
参数:
|
||||||
|
default_return: 发生异常时返回的默认值
|
||||||
|
reraise: 是否重新抛出异常
|
||||||
|
log_level: 日志级别
|
||||||
|
exception_types: 要捕获的异常类型,None表示捕获所有异常
|
||||||
|
|
||||||
|
使用示例:
|
||||||
|
@handle_errors(default_return=None, reraise=False)
|
||||||
|
def my_function():
|
||||||
|
# 可能抛出异常的代码
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
def decorator(func: Callable) -> Callable:
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
# 检查是否需要捕获此异常
|
||||||
|
if exception_types and not isinstance(e, exception_types):
|
||||||
|
raise
|
||||||
|
|
||||||
|
# 记录日志
|
||||||
|
func_name = func.__name__
|
||||||
|
module = func.__module__
|
||||||
|
|
||||||
|
log_message = f"Error in {module}.{func_name}: {str(e)}"
|
||||||
|
|
||||||
|
if log_level == logging.DEBUG:
|
||||||
|
logger.debug(log_message, exc_info=True)
|
||||||
|
elif log_level == logging.INFO:
|
||||||
|
logger.info(log_message, exc_info=True)
|
||||||
|
elif log_level == logging.WARNING:
|
||||||
|
logger.warning(log_message, exc_info=True)
|
||||||
|
elif log_level == logging.ERROR:
|
||||||
|
logger.error(log_message, exc_info=True)
|
||||||
|
elif log_level == logging.CRITICAL:
|
||||||
|
logger.critical(log_message, exc_info=True)
|
||||||
|
else:
|
||||||
|
logger.error(log_message, exc_info=True)
|
||||||
|
|
||||||
|
# 决定是否重新抛出异常
|
||||||
|
if reraise:
|
||||||
|
raise
|
||||||
|
|
||||||
|
return default_return
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def validate_input(
|
||||||
|
date: Optional[str] = None,
|
||||||
|
ship_name: Optional[str] = None,
|
||||||
|
teu: Optional[int] = None,
|
||||||
|
twenty_feet: Optional[int] = None,
|
||||||
|
forty_feet: Optional[int] = None
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
验证输入参数
|
||||||
|
|
||||||
|
参数:
|
||||||
|
date: 日期字符串,格式 "YYYY-MM-DD"
|
||||||
|
ship_name: 船名
|
||||||
|
teu: TEU数量
|
||||||
|
twenty_feet: 20尺箱量
|
||||||
|
forty_feet: 40尺箱量
|
||||||
|
|
||||||
|
异常:
|
||||||
|
ValidationError: 验证失败
|
||||||
|
"""
|
||||||
|
if date is not None:
|
||||||
|
if not isinstance(date, str):
|
||||||
|
raise ValidationError(f"日期必须是字符串类型,实际类型: {type(date)}")
|
||||||
|
try:
|
||||||
|
datetime.strptime(date, '%Y-%m-%d')
|
||||||
|
except ValueError:
|
||||||
|
raise ValidationError(f"日期格式无效: {date},应为 YYYY-MM-DD")
|
||||||
|
|
||||||
|
if ship_name is not None:
|
||||||
|
if not isinstance(ship_name, str):
|
||||||
|
raise ValidationError(f"船名必须是字符串类型,实际类型: {type(ship_name)}")
|
||||||
|
if len(ship_name.strip()) == 0:
|
||||||
|
raise ValidationError("船名不能为空")
|
||||||
|
|
||||||
|
if teu is not None:
|
||||||
|
if not isinstance(teu, int):
|
||||||
|
raise ValidationError(f"TEU必须是整数类型,实际类型: {type(teu)}")
|
||||||
|
if teu < 0:
|
||||||
|
raise ValidationError(f"TEU数量不能为负数: {teu}")
|
||||||
|
|
||||||
|
if twenty_feet is not None:
|
||||||
|
if not isinstance(twenty_feet, int):
|
||||||
|
raise ValidationError(f"20尺箱量必须是整数类型,实际类型: {type(twenty_feet)}")
|
||||||
|
if twenty_feet < 0:
|
||||||
|
raise ValidationError(f"20尺箱量不能为负数: {twenty_feet}")
|
||||||
|
|
||||||
|
if forty_feet is not None:
|
||||||
|
if not isinstance(forty_feet, int):
|
||||||
|
raise ValidationError(f"40尺箱量必须是整数类型,实际类型: {type(forty_feet)}")
|
||||||
|
if forty_feet < 0:
|
||||||
|
raise ValidationError(f"40尺箱量不能为负数: {forty_feet}")
|
||||||
|
|
||||||
|
|
||||||
|
def safe_execute(
|
||||||
|
func: Callable,
|
||||||
|
*args,
|
||||||
|
default_return: Any = None,
|
||||||
|
log_error: bool = True,
|
||||||
|
**kwargs
|
||||||
|
) -> Any:
|
||||||
|
"""
|
||||||
|
安全执行函数
|
||||||
|
|
||||||
|
参数:
|
||||||
|
func: 要执行的函数
|
||||||
|
*args: 位置参数
|
||||||
|
default_return: 发生异常时返回的默认值
|
||||||
|
log_error: 是否记录错误日志
|
||||||
|
**kwargs: 关键字参数
|
||||||
|
|
||||||
|
返回:
|
||||||
|
函数执行结果或默认值
|
||||||
|
|
||||||
|
使用示例:
|
||||||
|
result = safe_execute(
|
||||||
|
some_function,
|
||||||
|
arg1, arg2,
|
||||||
|
default_return=None,
|
||||||
|
log_error=True
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
if log_error:
|
||||||
|
func_name = getattr(func, '__name__', 'unknown_function')
|
||||||
|
module = getattr(func, '__module__', 'unknown_module')
|
||||||
|
logger.error(f"Error in {module}.{func_name}: {e}", exc_info=True)
|
||||||
|
return default_return
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorContext:
|
||||||
|
"""错误上下文管理器"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
operation_name: str,
|
||||||
|
reraise: bool = False,
|
||||||
|
log_level: int = logging.ERROR
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
初始化错误上下文
|
||||||
|
|
||||||
|
参数:
|
||||||
|
operation_name: 操作名称
|
||||||
|
reraise: 是否重新抛出异常
|
||||||
|
log_level: 日志级别
|
||||||
|
"""
|
||||||
|
self.operation_name = operation_name
|
||||||
|
self.reraise = reraise
|
||||||
|
self.log_level = log_level
|
||||||
|
self.start_time = None
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.start_time = datetime.now()
|
||||||
|
logger.debug(f"开始执行: {self.operation_name}")
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
|
elapsed = (datetime.now() - self.start_time).total_seconds()
|
||||||
|
|
||||||
|
if exc_type is None:
|
||||||
|
logger.debug(f"成功完成: {self.operation_name} (耗时: {elapsed:.2f}s)")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 发生异常
|
||||||
|
log_message = f"执行失败: {self.operation_name} (耗时: {elapsed:.2f}s) - {exc_val}"
|
||||||
|
|
||||||
|
if self.log_level == logging.DEBUG:
|
||||||
|
logger.debug(log_message, exc_info=(exc_type, exc_val, exc_tb))
|
||||||
|
elif self.log_level == logging.INFO:
|
||||||
|
logger.info(log_message, exc_info=(exc_type, exc_val, exc_tb))
|
||||||
|
elif self.log_level == logging.WARNING:
|
||||||
|
logger.warning(log_message, exc_info=(exc_type, exc_val, exc_tb))
|
||||||
|
elif self.log_level == logging.ERROR:
|
||||||
|
logger.error(log_message, exc_info=(exc_type, exc_val, exc_tb))
|
||||||
|
elif self.log_level == logging.CRITICAL:
|
||||||
|
logger.critical(log_message, exc_info=(exc_type, exc_val, exc_tb))
|
||||||
|
else:
|
||||||
|
logger.error(log_message, exc_info=(exc_type, exc_val, exc_tb))
|
||||||
|
|
||||||
|
# 决定是否抑制异常
|
||||||
|
return not self.reraise
|
||||||
|
|
||||||
|
|
||||||
|
def convert_exception(
|
||||||
|
from_exception: Type[Exception],
|
||||||
|
to_exception: Type[Exception],
|
||||||
|
message: Optional[str] = None
|
||||||
|
) -> Callable:
|
||||||
|
"""
|
||||||
|
异常转换装饰器
|
||||||
|
|
||||||
|
参数:
|
||||||
|
from_exception: 源异常类型
|
||||||
|
to_exception: 目标异常类型
|
||||||
|
message: 转换时的消息模板,可以使用 {original} 占位符
|
||||||
|
|
||||||
|
使用示例:
|
||||||
|
@convert_exception(ValueError, ValidationError, "验证失败: {original}")
|
||||||
|
def my_function():
|
||||||
|
# 可能抛出 ValueError 的代码
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
def decorator(func: Callable) -> Callable:
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except from_exception as e:
|
||||||
|
if message:
|
||||||
|
new_message = message.format(original=str(e))
|
||||||
|
else:
|
||||||
|
new_message = str(e)
|
||||||
|
raise to_exception(new_message) from e
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def log_execution_time(func: Callable) -> Callable:
|
||||||
|
"""
|
||||||
|
记录函数执行时间的装饰器
|
||||||
|
|
||||||
|
使用示例:
|
||||||
|
@log_execution_time
|
||||||
|
def my_function():
|
||||||
|
# 函数代码
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
start_time = datetime.now()
|
||||||
|
try:
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
elapsed = (datetime.now() - start_time).total_seconds()
|
||||||
|
logger.info(f"{func.__name__} 执行成功,耗时: {elapsed:.2f}s")
|
||||||
|
return result
|
||||||
|
except Exception as e:
|
||||||
|
elapsed = (datetime.now() - start_time).total_seconds()
|
||||||
|
logger.error(f"{func.__name__} 执行失败,耗时: {elapsed:.2f}s,错误: {e}")
|
||||||
|
raise
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# 测试代码
|
||||||
|
|
||||||
|
# 测试错误处理装饰器
|
||||||
|
@handle_errors(default_return="error", reraise=False)
|
||||||
|
def test_function():
|
||||||
|
raise ValueError("测试异常")
|
||||||
|
|
||||||
|
result = test_function()
|
||||||
|
print(f"测试函数返回: {result}")
|
||||||
|
|
||||||
|
# 测试输入验证
|
||||||
|
try:
|
||||||
|
validate_input(date="2025-12-30", ship_name="测试船", teu=100)
|
||||||
|
print("输入验证通过")
|
||||||
|
except ValidationError as e:
|
||||||
|
print(f"输入验证失败: {e}")
|
||||||
|
|
||||||
|
# 测试错误上下文管理器
|
||||||
|
try:
|
||||||
|
with ErrorContext("测试操作", reraise=True):
|
||||||
|
print("执行测试操作...")
|
||||||
|
raise RuntimeError("测试错误")
|
||||||
|
except RuntimeError as e:
|
||||||
|
print(f"捕获到错误: {e}")
|
||||||
|
|
||||||
|
# 测试异常转换
|
||||||
|
@convert_exception(ValueError, ValidationError, "验证失败: {original}")
|
||||||
|
def test_convert():
|
||||||
|
raise ValueError("原始错误")
|
||||||
|
|
||||||
|
try:
|
||||||
|
test_convert()
|
||||||
|
except ValidationError as e:
|
||||||
|
print(f"转换后的异常: {e}")
|
||||||
206
src/gui.py
206
src/gui.py
@@ -35,6 +35,70 @@ class OrbitInGUI:
|
|||||||
# 初始化日志器
|
# 初始化日志器
|
||||||
self.logger = get_logger(__name__)
|
self.logger = get_logger(__name__)
|
||||||
|
|
||||||
|
# 设置窗口图标为自定义图标
|
||||||
|
try:
|
||||||
|
# 使用外部图标文件
|
||||||
|
import os
|
||||||
|
# 构建图标文件路径
|
||||||
|
base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
icons_dir = os.path.join(base_path, 'icons')
|
||||||
|
|
||||||
|
# 支持多种图标格式,适应不同系统
|
||||||
|
icon_formats = ['container.png', 'container.gif', 'container.ico']
|
||||||
|
icon_path = None
|
||||||
|
|
||||||
|
# 查找可用的图标文件
|
||||||
|
for format in icon_formats:
|
||||||
|
test_path = os.path.join(icons_dir, format)
|
||||||
|
if os.path.exists(test_path):
|
||||||
|
icon_path = test_path
|
||||||
|
break
|
||||||
|
|
||||||
|
if icon_path:
|
||||||
|
# 检查文件扩展名,使用相应的方法
|
||||||
|
ext = os.path.splitext(icon_path)[1].lower()
|
||||||
|
|
||||||
|
if ext == '.ico':
|
||||||
|
try:
|
||||||
|
# Windows 系统使用 iconbitmap
|
||||||
|
self.root.iconbitmap(icon_path)
|
||||||
|
self.logger.info(f"使用 iconbitmap 设置图标成功: {icon_path}")
|
||||||
|
except Exception as e:
|
||||||
|
# 如果失败,尝试使用 iconphoto
|
||||||
|
try:
|
||||||
|
from tkinter import PhotoImage
|
||||||
|
icon = PhotoImage(file=icon_path)
|
||||||
|
self.root.iconphoto(True, icon)
|
||||||
|
self.logger.info(f"使用 iconphoto 设置图标成功: {icon_path}")
|
||||||
|
except Exception as e2:
|
||||||
|
self.logger.warning(f"设置图标失败: {e2}")
|
||||||
|
else:
|
||||||
|
# Linux/macOS 使用 iconphoto
|
||||||
|
try:
|
||||||
|
from tkinter import PhotoImage
|
||||||
|
icon = PhotoImage(file=icon_path)
|
||||||
|
self.root.iconphoto(True, icon)
|
||||||
|
self.logger.info(f"使用 iconphoto 设置图标成功: {icon_path}")
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.warning(f"设置图标失败: {e}")
|
||||||
|
else:
|
||||||
|
self.logger.warning(f"未找到图标文件,尝试使用内置图标")
|
||||||
|
# 如果图标文件不存在,尝试使用内置图标
|
||||||
|
try:
|
||||||
|
# 创建一个简单的集装箱样式图标
|
||||||
|
icon_data = '''
|
||||||
|
R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7
|
||||||
|
'''
|
||||||
|
from tkinter import PhotoImage
|
||||||
|
icon = PhotoImage(data=icon_data)
|
||||||
|
self.root.iconphoto(True, icon)
|
||||||
|
self.logger.info("使用内置图标")
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.warning(f"设置内置图标失败: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.warning(f"设置窗口图标失败: {e}")
|
||||||
|
# 继续执行,不影响其他功能
|
||||||
|
|
||||||
# 设置样式
|
# 设置样式
|
||||||
style = ttk.Style()
|
style = ttk.Style()
|
||||||
style.theme_use('clam')
|
style.theme_use('clam')
|
||||||
@@ -138,6 +202,20 @@ class OrbitInGUI:
|
|||||||
# 分隔线
|
# 分隔线
|
||||||
ttk.Separator(left_frame, orient=tk.HORIZONTAL).pack(fill=tk.X, pady=10)
|
ttk.Separator(left_frame, orient=tk.HORIZONTAL).pack(fill=tk.X, pady=10)
|
||||||
|
|
||||||
|
# 单独剔除TEU数量
|
||||||
|
ttk.Label(left_frame, text="单独剔除TEU:").pack(anchor=tk.W, pady=(10, 5))
|
||||||
|
|
||||||
|
btn_exclude_by_amount = ttk.Button(
|
||||||
|
left_frame,
|
||||||
|
text="单独剔除TEU数量",
|
||||||
|
command=self.show_exclude_by_amount_dialog,
|
||||||
|
width=20
|
||||||
|
)
|
||||||
|
btn_exclude_by_amount.pack(pady=5)
|
||||||
|
|
||||||
|
# 分隔线
|
||||||
|
ttk.Separator(left_frame, orient=tk.HORIZONTAL).pack(fill=tk.X, pady=10)
|
||||||
|
|
||||||
# Confluence页面ID管理
|
# Confluence页面ID管理
|
||||||
ttk.Label(left_frame, text="Confluence页面ID:").pack(anchor=tk.W, pady=(10, 5))
|
ttk.Label(left_frame, text="Confluence页面ID:").pack(anchor=tk.W, pady=(10, 5))
|
||||||
|
|
||||||
@@ -792,6 +870,11 @@ class OrbitInGUI:
|
|||||||
dialog = CrossMonthExcludeDialog(self.root, self)
|
dialog = CrossMonthExcludeDialog(self.root, self)
|
||||||
self.root.wait_window(dialog)
|
self.root.wait_window(dialog)
|
||||||
|
|
||||||
|
def show_exclude_by_amount_dialog(self):
|
||||||
|
"""显示单独提出TEU数量对话框"""
|
||||||
|
dialog = ExcludeByAmountDialog(self.root, self)
|
||||||
|
self.root.wait_window(dialog)
|
||||||
|
|
||||||
|
|
||||||
class AddDataDialog(tk.Toplevel):
|
class AddDataDialog(tk.Toplevel):
|
||||||
"""添加数据对话框"""
|
"""添加数据对话框"""
|
||||||
@@ -1660,6 +1743,129 @@ class CrossMonthExcludeDialog(tk.Toplevel):
|
|||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
class ExcludeByAmountDialog(tk.Toplevel):
|
||||||
|
"""单独剔除TEU数量对话框"""
|
||||||
|
|
||||||
|
def __init__(self, parent, gui):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.title("单独剔除TEU数量")
|
||||||
|
self.gui = gui
|
||||||
|
self.result = None
|
||||||
|
|
||||||
|
# 设置对话框大小和位置
|
||||||
|
self.geometry("450x320")
|
||||||
|
self.resizable(True, True)
|
||||||
|
|
||||||
|
# 使对话框模态
|
||||||
|
self.transient(parent)
|
||||||
|
self.grab_set()
|
||||||
|
|
||||||
|
# 创建输入字段
|
||||||
|
frame = ttk.Frame(self, padding="20")
|
||||||
|
frame.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
|
# 说明文本
|
||||||
|
ttk.Label(frame, text="单独剔除TEU数量(不需要船名和日期)", font=('', 10, 'bold')).grid(row=0, column=0, columnspan=2, sticky=tk.W, pady=10)
|
||||||
|
ttk.Label(frame, text="直接剔除指定数量的TEU,系统会自动处理日期和船名关联。", wraplength=350).grid(row=1, column=0, columnspan=2, sticky=tk.W, pady=5)
|
||||||
|
|
||||||
|
# TEU
|
||||||
|
ttk.Label(frame, text="TEU:").grid(row=2, column=0, sticky=tk.W, pady=10)
|
||||||
|
self.teu_var = tk.StringVar()
|
||||||
|
teu_entry = ttk.Entry(frame, textvariable=self.teu_var, width=15)
|
||||||
|
teu_entry.grid(row=2, column=1, sticky=tk.W, pady=10)
|
||||||
|
|
||||||
|
# 20尺箱量
|
||||||
|
ttk.Label(frame, text="20尺箱量:").grid(row=3, column=0, sticky=tk.W, pady=5)
|
||||||
|
self.twenty_var = tk.StringVar(value="0")
|
||||||
|
twenty_entry = ttk.Entry(frame, textvariable=self.twenty_var, width=15)
|
||||||
|
twenty_entry.grid(row=3, column=1, sticky=tk.W, pady=5)
|
||||||
|
|
||||||
|
# 40尺箱量
|
||||||
|
ttk.Label(frame, text="40尺箱量:").grid(row=4, column=0, sticky=tk.W, pady=5)
|
||||||
|
self.forty_var = tk.StringVar(value="0")
|
||||||
|
forty_entry = ttk.Entry(frame, textvariable=self.forty_var, width=15)
|
||||||
|
forty_entry.grid(row=4, column=1, sticky=tk.W, pady=5)
|
||||||
|
|
||||||
|
# 剔除原因
|
||||||
|
ttk.Label(frame, text="剔除原因:").grid(row=5, column=0, sticky=tk.W, pady=5)
|
||||||
|
self.reason_var = tk.StringVar(value="单独剔除TEU数量")
|
||||||
|
reason_entry = ttk.Entry(frame, textvariable=self.reason_var, width=30)
|
||||||
|
reason_entry.grid(row=5, column=1, sticky=tk.W, pady=5)
|
||||||
|
|
||||||
|
# 按钮
|
||||||
|
button_frame = ttk.Frame(frame)
|
||||||
|
button_frame.grid(row=6, column=0, columnspan=2, pady=20)
|
||||||
|
|
||||||
|
ttk.Button(button_frame, text="确定", command=self.on_ok).pack(side=tk.LEFT, padx=10)
|
||||||
|
ttk.Button(button_frame, text="取消", command=self.on_cancel).pack(side=tk.LEFT, padx=10)
|
||||||
|
|
||||||
|
# 绑定回车键
|
||||||
|
self.bind('<Return>', lambda e: self.on_ok())
|
||||||
|
self.bind('<Escape>', lambda e: self.on_cancel())
|
||||||
|
|
||||||
|
# 焦点设置
|
||||||
|
teu_entry.focus_set()
|
||||||
|
|
||||||
|
def on_ok(self):
|
||||||
|
"""确定按钮处理"""
|
||||||
|
try:
|
||||||
|
# 验证输入
|
||||||
|
teu_str = self.teu_var.get().strip()
|
||||||
|
twenty_str = self.twenty_var.get().strip()
|
||||||
|
forty_str = self.forty_var.get().strip()
|
||||||
|
reason = self.reason_var.get().strip()
|
||||||
|
|
||||||
|
if not teu_str:
|
||||||
|
messagebox.showerror("错误", "请输入TEU")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 验证数字
|
||||||
|
teu = int(teu_str)
|
||||||
|
twenty_feet = int(twenty_str) if twenty_str else 0
|
||||||
|
forty_feet = int(forty_str) if forty_str else 0
|
||||||
|
|
||||||
|
if teu <= 0:
|
||||||
|
messagebox.showerror("错误", "TEU必须大于0")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 保存结果
|
||||||
|
self.result = {
|
||||||
|
'teu': teu,
|
||||||
|
'twenty_feet': twenty_feet,
|
||||||
|
'forty_feet': forty_feet,
|
||||||
|
'reason': reason
|
||||||
|
}
|
||||||
|
|
||||||
|
# 处理结果
|
||||||
|
try:
|
||||||
|
db = DailyLogsDatabase()
|
||||||
|
success = db.exclude_teu_by_amount(
|
||||||
|
teu=teu,
|
||||||
|
twenty_feet=twenty_feet,
|
||||||
|
forty_feet=forty_feet,
|
||||||
|
reason=reason
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
self.gui.log_message(f"已单独剔除TEU数量: {teu}TEU")
|
||||||
|
# 刷新日报
|
||||||
|
self.gui.generate_today_report()
|
||||||
|
else:
|
||||||
|
self.gui.log_message("单独剔除TEU数量失败", is_error=True)
|
||||||
|
except Exception as e:
|
||||||
|
self.gui.log_message(f"单独剔除TEU数量时出错: {e}", is_error=True)
|
||||||
|
|
||||||
|
self.destroy()
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
messagebox.showerror("错误", "请输入有效的数字")
|
||||||
|
|
||||||
|
def on_cancel(self):
|
||||||
|
"""取消按钮处理"""
|
||||||
|
self.result = None
|
||||||
|
self.destroy()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""主函数"""
|
"""主函数"""
|
||||||
root = tk.Tk()
|
root = tk.Tk()
|
||||||
|
|||||||
1980
src/logs/2026-01/2026-01-27.log
Normal file
1980
src/logs/2026-01/2026-01-27.log
Normal file
File diff suppressed because it is too large
Load Diff
265
src/logs/2026-01/2026-01-28.log
Normal file
265
src/logs/2026-01/2026-01-28.log
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
2026-01-28 08:37:33 - root - INFO - logging_config.py:110 - 控制台日志级别: INFO
|
||||||
|
2026-01-28 08:37:33 - root - INFO - logging_config.py:111 - 文件日志级别: DEBUG
|
||||||
|
2026-01-28 08:37:33 - __main__ - INFO - gui.py:81 - 使用 iconphoto 设置图标成功: /home/admin1/文档/Orbitin/icons/container.png
|
||||||
|
2026-01-28 08:37:33 - __main__ - INFO - gui.py:692 - GUI启动,开始自动获取新数据...
|
||||||
|
2026-01-28 08:37:33 - __main__ - INFO - gui.py:705 - 正在刷新排班信息...
|
||||||
|
2026-01-28 08:37:33 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-28 08:37:33 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-28 08:37:33 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-28 08:37:33 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:33 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-28 08:37:33 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:33 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-28 08:37:33 - src.feishu.manager - INFO - manager.py:214 - 开始刷新未来 7 天的排班信息
|
||||||
|
2026-01-28 08:37:33 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-01-28 的排班信息...
|
||||||
|
2026-01-28 08:37:33 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-28 的排班信息 (格式: 01/28/1月28日)
|
||||||
|
2026-01-28 08:37:33 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-28 08:37:35 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7200秒
|
||||||
|
2026-01-28 08:37:35 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7200 秒后过期
|
||||||
|
2026-01-28 08:37:36 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-28 08:37:36 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:36 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-28 08:37:37 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-28 08:37:37 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月28日 解析表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:37 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-28 08:37:37 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-28 08:37:37 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月28日 -> 1月28日 (索引: 28)
|
||||||
|
2026-01-28 08:37:37 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:37 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:37 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-28
|
||||||
|
2026-01-28 08:37:37 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-28 的排班信息到数据库: 白班=梁启迟、汪钦良, 夜班=冯栋、刘炜彬、杨俊豪
|
||||||
|
2026-01-28 08:37:37 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-01-29 的排班信息...
|
||||||
|
2026-01-28 08:37:37 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-29 的排班信息 (格式: 01/29/1月29日)
|
||||||
|
2026-01-28 08:37:37 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-28 08:37:37 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-28 08:37:37 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:37 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-28 08:37:38 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-28 08:37:38 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月29日 解析表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:38 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-28 08:37:38 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-28 08:37:38 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月29日 -> 1月29日 (索引: 29)
|
||||||
|
2026-01-28 08:37:38 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:38 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:38 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-29
|
||||||
|
2026-01-28 08:37:38 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-29 的排班信息到数据库: 白班=汪钦良、牛晨, 夜班=冯栋、杨俊豪
|
||||||
|
2026-01-28 08:37:38 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-01-30 的排班信息...
|
||||||
|
2026-01-28 08:37:38 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-30 的排班信息 (格式: 01/30/1月30日)
|
||||||
|
2026-01-28 08:37:38 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7195秒
|
||||||
|
2026-01-28 08:37:38 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-28 08:37:38 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:38 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7195秒
|
||||||
|
2026-01-28 08:37:38 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-28 08:37:38 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月30日 解析表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:38 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-28 08:37:38 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-28 08:37:38 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月30日 -> 1月30日 (索引: 30)
|
||||||
|
2026-01-28 08:37:38 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:38 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:38 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-30
|
||||||
|
2026-01-28 08:37:38 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-30 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、杨俊豪
|
||||||
|
2026-01-28 08:37:38 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-01-31 的排班信息...
|
||||||
|
2026-01-28 08:37:38 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-31 的排班信息 (格式: 01/31/1月31日)
|
||||||
|
2026-01-28 08:37:38 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7195秒
|
||||||
|
2026-01-28 08:37:38 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-28 08:37:38 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:38 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7194秒
|
||||||
|
2026-01-28 08:37:39 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-28 08:37:39 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月31日 解析表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:39 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-28 08:37:39 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-28 08:37:39 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月31日 -> 1月31日 (索引: 31)
|
||||||
|
2026-01-28 08:37:39 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:39 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:39 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-31
|
||||||
|
2026-01-28 08:37:39 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-31 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、刘炜彬
|
||||||
|
2026-01-28 08:37:39 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-01 的排班信息...
|
||||||
|
2026-01-28 08:37:39 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-01 的排班信息 (格式: 02/01/2月1日)
|
||||||
|
2026-01-28 08:37:39 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7194秒
|
||||||
|
2026-01-28 08:37:39 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-28 08:37:39 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:39 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7194秒
|
||||||
|
2026-01-28 08:37:39 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-28 08:37:39 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月1日 解析表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:39 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-28 08:37:39 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-28 08:37:39 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-28 08:37:39 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月1日 -> 2月1日 (索引: 1)
|
||||||
|
2026-01-28 08:37:39 - src.feishu.manager - WARNING - manager.py:182 - 解析结果为空,2026-02-01 未保存到数据库
|
||||||
|
2026-01-28 08:37:39 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-02 的排班信息...
|
||||||
|
2026-01-28 08:37:39 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-02 的排班信息 (格式: 02/02/2月2日)
|
||||||
|
2026-01-28 08:37:39 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7193秒
|
||||||
|
2026-01-28 08:37:40 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-28 08:37:40 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:40 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7193秒
|
||||||
|
2026-01-28 08:37:40 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-28 08:37:40 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月2日 解析表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:40 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-28 08:37:40 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-28 08:37:40 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-28 08:37:40 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月2日 -> 2月2日 (索引: 2)
|
||||||
|
2026-01-28 08:37:40 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:40 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:40 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-02
|
||||||
|
2026-01-28 08:37:40 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-02 的排班信息到数据库: 白班=汪钦良, 夜班=
|
||||||
|
2026-01-28 08:37:40 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-03 的排班信息...
|
||||||
|
2026-01-28 08:37:40 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-03 的排班信息 (格式: 02/03/2月3日)
|
||||||
|
2026-01-28 08:37:40 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7192秒
|
||||||
|
2026-01-28 08:37:41 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-28 08:37:41 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:41 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7191秒
|
||||||
|
2026-01-28 08:37:42 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-28 08:37:42 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月3日 解析表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:42 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-28 08:37:42 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-28 08:37:42 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-28 08:37:42 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月3日 -> 2月3日 (索引: 3)
|
||||||
|
2026-01-28 08:37:42 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:42 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:42 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-03
|
||||||
|
2026-01-28 08:37:42 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-03 的排班信息到数据库: 白班=汪钦良, 夜班=
|
||||||
|
2026-01-28 08:37:42 - src.feishu.manager - INFO - manager.py:230 - 排班信息刷新完成,成功: 7, 失败: 0
|
||||||
|
2026-01-28 08:37:42 - __main__ - INFO - gui.py:710 - 排班信息刷新完成
|
||||||
|
2026-01-28 08:37:42 - __main__ - INFO - gui.py:726 - 正在尝试获取最新作业数据...
|
||||||
|
2026-01-28 08:37:42 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:42 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-28 08:37:42 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:42 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:42 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:42 - __main__ - INFO - gui.py:751 - 正在从 Confluence 获取 HTML...
|
||||||
|
2026-01-28 08:37:42 - src.confluence.client - DEBUG - client.py:50 - Confluence客户端初始化完成,基础URL: https://confluence.westwell-lab.com/rest/api
|
||||||
|
2026-01-28 08:37:42 - src.confluence.client - DEBUG - client.py:76 - 获取Confluence内容: 159049182
|
||||||
|
2026-01-28 08:37:43 - src.confluence.client - INFO - client.py:81 - 成功获取Confluence内容: 159049182
|
||||||
|
2026-01-28 08:37:43 - src.confluence.client - INFO - client.py:122 - 获取到Confluence HTML内容,长度: 78987 字符
|
||||||
|
2026-01-28 08:37:43 - __main__ - INFO - gui.py:757 - 获取成功,共 78987 字符
|
||||||
|
2026-01-28 08:37:43 - __main__ - INFO - gui.py:761 - 正在提取布局文本...
|
||||||
|
2026-01-28 08:37:43 - src.confluence.text - DEBUG - text.py:60 - 开始解析HTML,长度: 78987 字符
|
||||||
|
2026-01-28 08:37:43 - src.confluence.text - INFO - text.py:83 - HTML提取完成,输出长度: 17658 字符
|
||||||
|
2026-01-28 08:37:43 - __main__ - INFO - gui.py:767 - 正在解析日志数据...
|
||||||
|
2026-01-28 08:37:43 - src.confluence.log_parser - INFO - log_parser.py:390 - 解析转堆作业: 2026-01-02 白班 2TEU
|
||||||
|
2026-01-28 08:37:43 - src.confluence.log_parser - INFO - log_parser.py:209 - 日志解析完成,共 144 条记录
|
||||||
|
2026-01-28 08:37:43 - __main__ - INFO - gui.py:774 - 正在保存到数据库...
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:43 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:43 - src.database.daily_logs - INFO - daily_logs.py:237 - 批量插入完成,成功 144/144 条记录
|
||||||
|
2026-01-28 08:37:43 - __main__ - INFO - gui.py:778 - 已保存 144 条新记录
|
||||||
|
2026-01-28 08:37:43 - __main__ - INFO - gui.py:806 - 正在生成今日日报...
|
||||||
|
2026-01-28 08:37:43 - __main__ - INFO - gui.py:650 - 生成 2026-01-27 的日报...
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:43 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:43 - src.report - INFO - report.py:34 - 日报生成器初始化完成
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:43 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-28 08:37:43 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-28 08:37:43 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:43 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-28 08:37:43 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:43 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-28 08:37:43 - src.report - INFO - report.py:266 - 获取 2026-01-27 日报的班次人员,对应排班表日期: 2026-01-28
|
||||||
|
2026-01-28 08:37:43 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-28 的排班信息 (格式: 01/28/1月28日)
|
||||||
|
2026-01-28 08:37:43 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-28 08:37:44 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7191秒
|
||||||
|
2026-01-28 08:37:44 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7191 秒后过期
|
||||||
|
2026-01-28 08:37:46 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-28 08:37:46 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:46 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7188秒
|
||||||
|
2026-01-28 08:37:47 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-28 08:37:47 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月28日 解析表格: 2026年排班表
|
||||||
|
2026-01-28 08:37:47 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-28 08:37:47 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-28 08:37:47 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月28日 -> 1月28日 (索引: 28)
|
||||||
|
2026-01-28 08:37:47 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:37:47 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:37:47 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-28
|
||||||
|
2026-01-28 08:37:47 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-28 的排班信息到数据库: 白班=梁启迟、汪钦良, 夜班=冯栋、刘炜彬、杨俊豪
|
||||||
|
2026-01-28 08:37:47 - src.report - INFO - report.py:371 - 日报生成完成: 2026-01-27
|
||||||
|
2026-01-28 08:37:47 - __main__ - INFO - gui.py:667 - 日报生成完成: 2026-01-27
|
||||||
|
2026-01-28 08:37:47 - __main__ - INFO - gui.py:811 - 自动获取完成,GUI已就绪
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:331 - 开始获取数据...
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:12 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:360 - 使用页面ID映射: 2026-01-27 -> 159049182
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:365 - 正在从 Confluence 获取 HTML...
|
||||||
|
2026-01-28 08:39:12 - src.confluence.client - DEBUG - client.py:50 - Confluence客户端初始化完成,基础URL: https://confluence.westwell-lab.com/rest/api
|
||||||
|
2026-01-28 08:39:12 - src.confluence.client - DEBUG - client.py:76 - 获取Confluence内容: 159049182
|
||||||
|
2026-01-28 08:39:12 - src.confluence.client - INFO - client.py:81 - 成功获取Confluence内容: 159049182
|
||||||
|
2026-01-28 08:39:12 - src.confluence.client - INFO - client.py:122 - 获取到Confluence HTML内容,长度: 78990 字符
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:375 - 获取成功,共 78990 字符
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:379 - 正在提取布局文本...
|
||||||
|
2026-01-28 08:39:12 - src.confluence.text - DEBUG - text.py:60 - 开始解析HTML,长度: 78990 字符
|
||||||
|
2026-01-28 08:39:12 - src.confluence.text - INFO - text.py:83 - HTML提取完成,输出长度: 17661 字符
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:383 - 提取完成,共 17660 字符
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:387 - 正在解析日志数据...
|
||||||
|
2026-01-28 08:39:12 - src.confluence.log_parser - INFO - log_parser.py:390 - 解析转堆作业: 2026-01-02 白班 2TEU
|
||||||
|
2026-01-28 08:39:12 - src.confluence.log_parser - INFO - log_parser.py:209 - 日志解析完成,共 144 条记录
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:391 - 解析到 144 条记录
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:396 - 正在保存到数据库...
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:12 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:12 - src.database.daily_logs - INFO - daily_logs.py:237 - 批量插入完成,成功 144/144 条记录
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:400 - 已保存 144 条记录
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:405 - 数据库总计: 275 条记录, 53 艘船
|
||||||
|
2026-01-28 08:39:12 - __main__ - INFO - gui.py:650 - 生成 2026-01-27 的日报...
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:12 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:12 - src.report - INFO - report.py:34 - 日报生成器初始化完成
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:13 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:13 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:13 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:13 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:13 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:13 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-28 08:39:13 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-28 08:39:13 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-28 08:39:13 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:13 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-28 08:39:13 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:13 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-28 08:39:13 - src.report - INFO - report.py:266 - 获取 2026-01-27 日报的班次人员,对应排班表日期: 2026-01-28
|
||||||
|
2026-01-28 08:39:13 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-28 的排班信息 (格式: 01/28/1月28日)
|
||||||
|
2026-01-28 08:39:13 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-28 08:39:13 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7102秒
|
||||||
|
2026-01-28 08:39:13 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7102 秒后过期
|
||||||
|
2026-01-28 08:39:13 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-28 08:39:13 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-28 08:39:13 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7101秒
|
||||||
|
2026-01-28 08:39:14 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-28 08:39:14 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月28日 解析表格: 2026年排班表
|
||||||
|
2026-01-28 08:39:14 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-28 08:39:14 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-28 08:39:14 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月28日 -> 1月28日 (索引: 28)
|
||||||
|
2026-01-28 08:39:14 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-28 08:39:14 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-28 08:39:14 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-28
|
||||||
|
2026-01-28 08:39:14 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-28 的排班信息到数据库: 白班=梁启迟、汪钦良, 夜班=冯栋、刘炜彬、杨俊豪
|
||||||
|
2026-01-28 08:39:14 - src.report - INFO - report.py:371 - 日报生成完成: 2026-01-27
|
||||||
|
2026-01-28 08:39:14 - __main__ - INFO - gui.py:667 - 日报生成完成: 2026-01-27
|
||||||
|
2026-01-28 08:39:14 - __main__ - INFO - gui.py:414 - 数据获取完成
|
||||||
233
src/logs/2026-01/2026-01-29.log
Normal file
233
src/logs/2026-01/2026-01-29.log
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
2026-01-29 08:23:17 - root - INFO - logging_config.py:110 - 控制台日志级别: INFO
|
||||||
|
2026-01-29 08:23:17 - root - INFO - logging_config.py:111 - 文件日志级别: DEBUG
|
||||||
|
2026-01-29 08:23:18 - __main__ - INFO - gui.py:81 - 使用 iconphoto 设置图标成功: /home/admin1/文档/Orbitin/icons/container.png
|
||||||
|
2026-01-29 08:23:18 - __main__ - INFO - gui.py:692 - GUI启动,开始自动获取新数据...
|
||||||
|
2026-01-29 08:23:18 - __main__ - INFO - gui.py:705 - 正在刷新排班信息...
|
||||||
|
2026-01-29 08:23:18 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-29 08:23:18 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-29 08:23:18 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-29 08:23:18 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:18 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-29 08:23:18 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:18 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-29 08:23:18 - src.feishu.manager - INFO - manager.py:214 - 开始刷新未来 7 天的排班信息
|
||||||
|
2026-01-29 08:23:18 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-01-29 的排班信息...
|
||||||
|
2026-01-29 08:23:18 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-29 的排班信息 (格式: 01/29/1月29日)
|
||||||
|
2026-01-29 08:23:18 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-29 08:23:18 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7200秒
|
||||||
|
2026-01-29 08:23:18 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7200 秒后过期
|
||||||
|
2026-01-29 08:23:19 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-29 08:23:19 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:19 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7199秒
|
||||||
|
2026-01-29 08:23:19 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-29 08:23:19 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月29日 解析表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:19 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-29 08:23:19 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-29 08:23:19 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月29日 -> 1月29日 (索引: 29)
|
||||||
|
2026-01-29 08:23:19 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:19 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:19 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-29
|
||||||
|
2026-01-29 08:23:19 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-29 的排班信息到数据库: 白班=汪钦良、牛晨, 夜班=冯栋、杨俊豪
|
||||||
|
2026-01-29 08:23:19 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-01-30 的排班信息...
|
||||||
|
2026-01-29 08:23:19 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-30 的排班信息 (格式: 01/30/1月30日)
|
||||||
|
2026-01-29 08:23:19 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7198秒
|
||||||
|
2026-01-29 08:23:20 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-29 08:23:20 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:20 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7198秒
|
||||||
|
2026-01-29 08:23:20 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-29 08:23:20 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月30日 解析表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:20 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-29 08:23:20 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-29 08:23:20 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月30日 -> 1月30日 (索引: 30)
|
||||||
|
2026-01-29 08:23:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:20 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-30
|
||||||
|
2026-01-29 08:23:20 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-30 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、杨俊豪
|
||||||
|
2026-01-29 08:23:20 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-01-31 的排班信息...
|
||||||
|
2026-01-29 08:23:20 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-31 的排班信息 (格式: 01/31/1月31日)
|
||||||
|
2026-01-29 08:23:20 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7198秒
|
||||||
|
2026-01-29 08:23:20 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-29 08:23:20 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:20 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-29 08:23:20 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-29 08:23:20 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月31日 解析表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:20 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-29 08:23:20 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-29 08:23:20 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月31日 -> 1月31日 (索引: 31)
|
||||||
|
2026-01-29 08:23:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:20 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-31
|
||||||
|
2026-01-29 08:23:20 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-31 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、刘炜彬
|
||||||
|
2026-01-29 08:23:20 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-01 的排班信息...
|
||||||
|
2026-01-29 08:23:20 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-01 的排班信息 (格式: 02/01/2月1日)
|
||||||
|
2026-01-29 08:23:20 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-29 08:23:21 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-29 08:23:21 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:21 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-29 08:23:21 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-29 08:23:21 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月1日 解析表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:21 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-29 08:23:21 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-29 08:23:21 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-29 08:23:21 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月1日 -> 2月1日 (索引: 1)
|
||||||
|
2026-01-29 08:23:21 - src.feishu.manager - WARNING - manager.py:182 - 解析结果为空,2026-02-01 未保存到数据库
|
||||||
|
2026-01-29 08:23:21 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-02 的排班信息...
|
||||||
|
2026-01-29 08:23:21 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-02 的排班信息 (格式: 02/02/2月2日)
|
||||||
|
2026-01-29 08:23:21 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-29 08:23:21 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-29 08:23:21 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:21 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-29 08:23:22 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-29 08:23:22 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月2日 解析表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:22 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-29 08:23:22 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-29 08:23:22 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-29 08:23:22 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月2日 -> 2月2日 (索引: 2)
|
||||||
|
2026-01-29 08:23:22 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:22 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:22 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-02
|
||||||
|
2026-01-29 08:23:22 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-02 的排班信息到数据库: 白班=汪钦良, 夜班=
|
||||||
|
2026-01-29 08:23:22 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-03 的排班信息...
|
||||||
|
2026-01-29 08:23:22 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-03 的排班信息 (格式: 02/03/2月3日)
|
||||||
|
2026-01-29 08:23:22 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-29 08:23:22 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-29 08:23:22 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:22 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-29 08:23:22 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-29 08:23:22 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月3日 解析表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:22 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-29 08:23:22 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-29 08:23:22 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-29 08:23:22 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月3日 -> 2月3日 (索引: 3)
|
||||||
|
2026-01-29 08:23:22 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:22 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:22 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-03
|
||||||
|
2026-01-29 08:23:22 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-03 的排班信息到数据库: 白班=汪钦良, 夜班=
|
||||||
|
2026-01-29 08:23:22 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-04 的排班信息...
|
||||||
|
2026-01-29 08:23:22 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-04 的排班信息 (格式: 02/04/2月4日)
|
||||||
|
2026-01-29 08:23:22 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7195秒
|
||||||
|
2026-01-29 08:23:22 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-29 08:23:22 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:22 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7195秒
|
||||||
|
2026-01-29 08:23:23 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-29 08:23:23 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月4日 解析表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:23 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-29 08:23:23 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-29 08:23:23 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-29 08:23:23 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月4日 -> 2月4日 (索引: 4)
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:23 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-04
|
||||||
|
2026-01-29 08:23:23 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-04 的排班信息到数据库: 白班=汪钦良, 夜班=
|
||||||
|
2026-01-29 08:23:23 - src.feishu.manager - INFO - manager.py:230 - 排班信息刷新完成,成功: 7, 失败: 0
|
||||||
|
2026-01-29 08:23:23 - __main__ - INFO - gui.py:650 - 生成 2026-01-29 的日报...
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:23 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:23 - src.report - INFO - report.py:34 - 日报生成器初始化完成
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:23 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-29 08:23:23 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-29 08:23:23 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:23 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-29 08:23:23 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:23 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-29 08:23:23 - src.report - INFO - report.py:266 - 获取 2026-01-29 日报的班次人员,对应排班表日期: 2026-01-30
|
||||||
|
2026-01-29 08:23:23 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-30 的排班信息 (格式: 01/30/1月30日)
|
||||||
|
2026-01-29 08:23:23 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-29 08:23:23 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7195秒
|
||||||
|
2026-01-29 08:23:23 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7195 秒后过期
|
||||||
|
2026-01-29 08:23:23 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-29 08:23:23 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:23 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7194秒
|
||||||
|
2026-01-29 08:23:24 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-29 08:23:24 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月30日 解析表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:24 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-29 08:23:24 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-29 08:23:24 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月30日 -> 1月30日 (索引: 30)
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-30
|
||||||
|
2026-01-29 08:23:24 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-30 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、杨俊豪
|
||||||
|
2026-01-29 08:23:24 - src.report - INFO - report.py:371 - 日报生成完成: 2026-01-29
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:667 - 日报生成完成: 2026-01-29
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:710 - 排班信息刷新完成
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:726 - 正在尝试获取最新作业数据...
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:751 - 正在从 Confluence 获取 HTML...
|
||||||
|
2026-01-29 08:23:24 - src.confluence.client - DEBUG - client.py:50 - Confluence客户端初始化完成,基础URL: https://confluence.westwell-lab.com/rest/api
|
||||||
|
2026-01-29 08:23:24 - src.confluence.client - DEBUG - client.py:76 - 获取Confluence内容: 159049182
|
||||||
|
2026-01-29 08:23:24 - src.confluence.client - INFO - client.py:81 - 成功获取Confluence内容: 159049182
|
||||||
|
2026-01-29 08:23:24 - src.confluence.client - INFO - client.py:122 - 获取到Confluence HTML内容,长度: 81156 字符
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:757 - 获取成功,共 81156 字符
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:761 - 正在提取布局文本...
|
||||||
|
2026-01-29 08:23:24 - src.confluence.text - DEBUG - text.py:60 - 开始解析HTML,长度: 81156 字符
|
||||||
|
2026-01-29 08:23:24 - src.confluence.text - INFO - text.py:83 - HTML提取完成,输出长度: 18253 字符
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:767 - 正在解析日志数据...
|
||||||
|
2026-01-29 08:23:24 - src.confluence.log_parser - INFO - log_parser.py:390 - 解析转堆作业: 2026-01-02 白班 2TEU
|
||||||
|
2026-01-29 08:23:24 - src.confluence.log_parser - INFO - log_parser.py:209 - 日志解析完成,共 148 条记录
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:774 - 正在保存到数据库...
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.database.daily_logs - INFO - daily_logs.py:237 - 批量插入完成,成功 148/148 条记录
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:778 - 已保存 148 条新记录
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:806 - 正在生成今日日报...
|
||||||
|
2026-01-29 08:23:24 - __main__ - INFO - gui.py:650 - 生成 2026-01-28 的日报...
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.report - INFO - report.py:34 - 日报生成器初始化完成
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-29 08:23:24 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-29 08:23:24 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:24 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-29 08:23:24 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:24 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-29 08:23:24 - src.report - INFO - report.py:266 - 获取 2026-01-28 日报的班次人员,对应排班表日期: 2026-01-29
|
||||||
|
2026-01-29 08:23:24 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-29 的排班信息 (格式: 01/29/1月29日)
|
||||||
|
2026-01-29 08:23:24 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-29 08:23:24 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7194秒
|
||||||
|
2026-01-29 08:23:24 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7194 秒后过期
|
||||||
|
2026-01-29 08:23:25 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-29 08:23:25 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:25 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7193秒
|
||||||
|
2026-01-29 08:23:25 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-29 08:23:25 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月29日 解析表格: 2026年排班表
|
||||||
|
2026-01-29 08:23:25 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-29 08:23:25 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-29 08:23:25 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月29日 -> 1月29日 (索引: 29)
|
||||||
|
2026-01-29 08:23:25 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-29 08:23:25 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-29 08:23:25 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-29
|
||||||
|
2026-01-29 08:23:25 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-29 的排班信息到数据库: 白班=汪钦良、牛晨, 夜班=冯栋、杨俊豪
|
||||||
|
2026-01-29 08:23:25 - src.report - INFO - report.py:371 - 日报生成完成: 2026-01-28
|
||||||
|
2026-01-29 08:23:25 - __main__ - INFO - gui.py:667 - 日报生成完成: 2026-01-28
|
||||||
|
2026-01-29 08:23:25 - __main__ - INFO - gui.py:811 - 自动获取完成,GUI已就绪
|
||||||
234
src/logs/2026-01/2026-01-30.log
Normal file
234
src/logs/2026-01/2026-01-30.log
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
2026-01-30 08:29:07 - root - INFO - logging_config.py:110 - 控制台日志级别: INFO
|
||||||
|
2026-01-30 08:29:07 - root - INFO - logging_config.py:111 - 文件日志级别: DEBUG
|
||||||
|
2026-01-30 08:29:07 - __main__ - INFO - gui.py:81 - 使用 iconphoto 设置图标成功: /home/admin1/文档/Orbitin/icons/container.png
|
||||||
|
2026-01-30 08:29:09 - __main__ - INFO - gui.py:692 - GUI启动,开始自动获取新数据...
|
||||||
|
2026-01-30 08:29:09 - __main__ - INFO - gui.py:705 - 正在刷新排班信息...
|
||||||
|
2026-01-30 08:29:09 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-30 08:29:09 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-30 08:29:09 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-30 08:29:09 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:09 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-30 08:29:09 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:09 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-30 08:29:09 - src.feishu.manager - INFO - manager.py:214 - 开始刷新未来 7 天的排班信息
|
||||||
|
2026-01-30 08:29:09 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-01-30 的排班信息...
|
||||||
|
2026-01-30 08:29:09 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-30 的排班信息 (格式: 01/30/1月30日)
|
||||||
|
2026-01-30 08:29:09 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-30 08:29:09 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7200秒
|
||||||
|
2026-01-30 08:29:09 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7200 秒后过期
|
||||||
|
2026-01-30 08:29:10 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-30 08:29:10 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:10 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7198秒
|
||||||
|
2026-01-30 08:29:10 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-30 08:29:10 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月30日 解析表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:10 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-30 08:29:10 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-30 08:29:10 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月30日 -> 1月30日 (索引: 30)
|
||||||
|
2026-01-30 08:29:10 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:10 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:10 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-30
|
||||||
|
2026-01-30 08:29:10 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-30 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、杨俊豪
|
||||||
|
2026-01-30 08:29:10 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-01-31 的排班信息...
|
||||||
|
2026-01-30 08:29:10 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-31 的排班信息 (格式: 01/31/1月31日)
|
||||||
|
2026-01-30 08:29:10 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7198秒
|
||||||
|
2026-01-30 08:29:10 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-30 08:29:10 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:10 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7198秒
|
||||||
|
2026-01-30 08:29:11 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-30 08:29:11 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月31日 解析表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:11 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-30 08:29:11 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-30 08:29:11 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月31日 -> 1月31日 (索引: 31)
|
||||||
|
2026-01-30 08:29:11 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:11 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:11 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-31
|
||||||
|
2026-01-30 08:29:11 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-31 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、刘炜彬
|
||||||
|
2026-01-30 08:29:11 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-01 的排班信息...
|
||||||
|
2026-01-30 08:29:11 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-01 的排班信息 (格式: 02/01/2月1日)
|
||||||
|
2026-01-30 08:29:11 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-30 08:29:11 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-30 08:29:11 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:11 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-30 08:29:11 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-30 08:29:11 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月1日 解析表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:11 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-30 08:29:11 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-30 08:29:11 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-30 08:29:11 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月1日 -> 2月1日 (索引: 1)
|
||||||
|
2026-01-30 08:29:11 - src.feishu.manager - WARNING - manager.py:182 - 解析结果为空,2026-02-01 未保存到数据库
|
||||||
|
2026-01-30 08:29:11 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-02 的排班信息...
|
||||||
|
2026-01-30 08:29:11 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-02 的排班信息 (格式: 02/02/2月2日)
|
||||||
|
2026-01-30 08:29:11 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-30 08:29:12 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-30 08:29:12 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:12 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-30 08:29:12 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-30 08:29:12 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月2日 解析表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:12 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-30 08:29:12 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-30 08:29:12 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-30 08:29:12 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月2日 -> 2月2日 (索引: 2)
|
||||||
|
2026-01-30 08:29:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:12 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:12 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-02
|
||||||
|
2026-01-30 08:29:12 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-02 的排班信息到数据库: 白班=汪钦良, 夜班=
|
||||||
|
2026-01-30 08:29:12 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-03 的排班信息...
|
||||||
|
2026-01-30 08:29:12 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-03 的排班信息 (格式: 02/03/2月3日)
|
||||||
|
2026-01-30 08:29:12 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-30 08:29:12 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-30 08:29:12 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:12 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-30 08:29:12 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-30 08:29:12 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月3日 解析表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:12 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-30 08:29:12 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-30 08:29:12 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-30 08:29:12 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月3日 -> 2月3日 (索引: 3)
|
||||||
|
2026-01-30 08:29:12 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:12 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:12 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-03
|
||||||
|
2026-01-30 08:29:12 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-03 的排班信息到数据库: 白班=汪钦良, 夜班=
|
||||||
|
2026-01-30 08:29:12 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-04 的排班信息...
|
||||||
|
2026-01-30 08:29:12 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-04 的排班信息 (格式: 02/04/2月4日)
|
||||||
|
2026-01-30 08:29:12 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-30 08:29:13 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-30 08:29:13 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:13 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7195秒
|
||||||
|
2026-01-30 08:29:13 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-30 08:29:13 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月4日 解析表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:13 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-30 08:29:13 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-30 08:29:13 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-30 08:29:13 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月4日 -> 2月4日 (索引: 4)
|
||||||
|
2026-01-30 08:29:13 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:13 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:13 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-04
|
||||||
|
2026-01-30 08:29:13 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-04 的排班信息到数据库: 白班=汪钦良, 夜班=
|
||||||
|
2026-01-30 08:29:13 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-05 的排班信息...
|
||||||
|
2026-01-30 08:29:13 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-05 的排班信息 (格式: 02/05/2月5日)
|
||||||
|
2026-01-30 08:29:13 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7195秒
|
||||||
|
2026-01-30 08:29:13 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-30 08:29:13 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:13 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7195秒
|
||||||
|
2026-01-30 08:29:14 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-30 08:29:14 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月5日 解析表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:14 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-30 08:29:14 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-30 08:29:14 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-30 08:29:14 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月5日 -> 2月5日 (索引: 5)
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:14 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-05
|
||||||
|
2026-01-30 08:29:14 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-05 的排班信息到数据库: 白班=汪钦良, 夜班=
|
||||||
|
2026-01-30 08:29:14 - src.feishu.manager - INFO - manager.py:230 - 排班信息刷新完成,成功: 7, 失败: 0
|
||||||
|
2026-01-30 08:29:14 - __main__ - INFO - gui.py:650 - 生成 2026-01-30 的日报...
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:14 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:14 - src.report - INFO - report.py:34 - 日报生成器初始化完成
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:14 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-30 08:29:14 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-30 08:29:14 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:14 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-30 08:29:14 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:14 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-30 08:29:14 - src.report - INFO - report.py:266 - 获取 2026-01-30 日报的班次人员,对应排班表日期: 2026-01-31
|
||||||
|
2026-01-30 08:29:14 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-31 的排班信息 (格式: 01/31/1月31日)
|
||||||
|
2026-01-30 08:29:14 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-30 08:29:14 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7195秒
|
||||||
|
2026-01-30 08:29:14 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7195 秒后过期
|
||||||
|
2026-01-30 08:29:14 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-30 08:29:14 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:14 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7194秒
|
||||||
|
2026-01-30 08:29:15 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-30 08:29:15 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月31日 解析表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:15 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-30 08:29:15 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-30 08:29:15 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月31日 -> 1月31日 (索引: 31)
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-31
|
||||||
|
2026-01-30 08:29:15 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-31 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、刘炜彬
|
||||||
|
2026-01-30 08:29:15 - src.report - INFO - report.py:371 - 日报生成完成: 2026-01-30
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:667 - 日报生成完成: 2026-01-30
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:710 - 排班信息刷新完成
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:726 - 正在尝试获取最新作业数据...
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:751 - 正在从 Confluence 获取 HTML...
|
||||||
|
2026-01-30 08:29:15 - src.confluence.client - DEBUG - client.py:50 - Confluence客户端初始化完成,基础URL: https://confluence.westwell-lab.com/rest/api
|
||||||
|
2026-01-30 08:29:15 - src.confluence.client - DEBUG - client.py:76 - 获取Confluence内容: 159049182
|
||||||
|
2026-01-30 08:29:15 - src.confluence.client - INFO - client.py:81 - 成功获取Confluence内容: 159049182
|
||||||
|
2026-01-30 08:29:15 - src.confluence.client - INFO - client.py:122 - 获取到Confluence HTML内容,长度: 84056 字符
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:757 - 获取成功,共 84056 字符
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:761 - 正在提取布局文本...
|
||||||
|
2026-01-30 08:29:15 - src.confluence.text - DEBUG - text.py:60 - 开始解析HTML,长度: 84056 字符
|
||||||
|
2026-01-30 08:29:15 - src.confluence.text - INFO - text.py:83 - HTML提取完成,输出长度: 18944 字符
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:767 - 正在解析日志数据...
|
||||||
|
2026-01-30 08:29:15 - src.confluence.log_parser - INFO - log_parser.py:390 - 解析转堆作业: 2026-01-02 白班 2TEU
|
||||||
|
2026-01-30 08:29:15 - src.confluence.log_parser - INFO - log_parser.py:209 - 日志解析完成,共 154 条记录
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:774 - 正在保存到数据库...
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.database.daily_logs - INFO - daily_logs.py:237 - 批量插入完成,成功 154/154 条记录
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:778 - 已保存 154 条新记录
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:806 - 正在生成今日日报...
|
||||||
|
2026-01-30 08:29:15 - __main__ - INFO - gui.py:650 - 生成 2026-01-29 的日报...
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.report - INFO - report.py:34 - 日报生成器初始化完成
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-30 08:29:15 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-30 08:29:15 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:15 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-30 08:29:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:15 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-30 08:29:15 - src.report - INFO - report.py:266 - 获取 2026-01-29 日报的班次人员,对应排班表日期: 2026-01-30
|
||||||
|
2026-01-30 08:29:15 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-30 的排班信息 (格式: 01/30/1月30日)
|
||||||
|
2026-01-30 08:29:15 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-30 08:29:16 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7193秒
|
||||||
|
2026-01-30 08:29:16 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7193 秒后过期
|
||||||
|
2026-01-30 08:29:16 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-30 08:29:16 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:16 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7192秒
|
||||||
|
2026-01-30 08:29:16 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-30 08:29:16 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月30日 解析表格: 2026年排班表
|
||||||
|
2026-01-30 08:29:16 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-30 08:29:16 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-30 08:29:16 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月30日 -> 1月30日 (索引: 30)
|
||||||
|
2026-01-30 08:29:16 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-30 08:29:16 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-30 08:29:16 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-30
|
||||||
|
2026-01-30 08:29:16 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-30 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、杨俊豪
|
||||||
|
2026-01-30 08:29:16 - src.report - INFO - report.py:371 - 日报生成完成: 2026-01-29
|
||||||
|
2026-01-30 08:29:16 - __main__ - INFO - gui.py:667 - 日报生成完成: 2026-01-29
|
||||||
|
2026-01-30 08:29:16 - __main__ - INFO - gui.py:811 - 自动获取完成,GUI已就绪
|
||||||
239
src/logs/2026-01/2026-01-31.log
Normal file
239
src/logs/2026-01/2026-01-31.log
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
2026-01-31 08:25:13 - root - INFO - logging_config.py:110 - 控制台日志级别: INFO
|
||||||
|
2026-01-31 08:25:13 - root - INFO - logging_config.py:111 - 文件日志级别: DEBUG
|
||||||
|
2026-01-31 08:25:13 - __main__ - INFO - gui.py:81 - 使用 iconphoto 设置图标成功: /home/admin1/文档/Orbitin/icons/container.png
|
||||||
|
2026-01-31 08:25:14 - __main__ - INFO - gui.py:692 - GUI启动,开始自动获取新数据...
|
||||||
|
2026-01-31 08:25:14 - __main__ - INFO - gui.py:705 - 正在刷新排班信息...
|
||||||
|
2026-01-31 08:25:14 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-31 08:25:14 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-31 08:25:14 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-31 08:25:14 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:14 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-31 08:25:14 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:14 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-31 08:25:14 - src.feishu.manager - INFO - manager.py:214 - 开始刷新未来 7 天的排班信息
|
||||||
|
2026-01-31 08:25:14 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-01-31 的排班信息...
|
||||||
|
2026-01-31 08:25:14 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-31 的排班信息 (格式: 01/31/1月31日)
|
||||||
|
2026-01-31 08:25:14 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-31 08:25:14 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7200秒
|
||||||
|
2026-01-31 08:25:14 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7200 秒后过期
|
||||||
|
2026-01-31 08:25:15 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-31 08:25:15 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:15 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7199秒
|
||||||
|
2026-01-31 08:25:15 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-31 08:25:15 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月31日 解析表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:15 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-31 08:25:15 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-31 08:25:15 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月31日 -> 1月31日 (索引: 31)
|
||||||
|
2026-01-31 08:25:15 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:15 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:15 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-31
|
||||||
|
2026-01-31 08:25:15 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-31 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、刘炜彬
|
||||||
|
2026-01-31 08:25:15 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-01 的排班信息...
|
||||||
|
2026-01-31 08:25:15 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-01 的排班信息 (格式: 02/01/2月1日)
|
||||||
|
2026-01-31 08:25:15 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7198秒
|
||||||
|
2026-01-31 08:25:15 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-31 08:25:15 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:15 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7198秒
|
||||||
|
2026-01-31 08:25:16 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-31 08:25:16 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月1日 解析表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:16 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-31 08:25:16 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-31 08:25:16 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-31 08:25:16 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月1日 -> 2月1日 (索引: 1)
|
||||||
|
2026-01-31 08:25:16 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:16 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:16 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-01
|
||||||
|
2026-01-31 08:25:16 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-01 的排班信息到数据库: 白班=梁启迟、牛晨, 夜班=冯栋、刘炜彬
|
||||||
|
2026-01-31 08:25:16 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-02 的排班信息...
|
||||||
|
2026-01-31 08:25:16 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-02 的排班信息 (格式: 02/02/2月2日)
|
||||||
|
2026-01-31 08:25:16 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7198秒
|
||||||
|
2026-01-31 08:25:16 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-31 08:25:16 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:16 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-31 08:25:16 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-31 08:25:16 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月2日 解析表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:16 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-31 08:25:16 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-31 08:25:16 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-31 08:25:16 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月2日 -> 2月2日 (索引: 2)
|
||||||
|
2026-01-31 08:25:16 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:16 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:16 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-02
|
||||||
|
2026-01-31 08:25:16 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-02 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、刘炜彬、杨俊豪
|
||||||
|
2026-01-31 08:25:16 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-03 的排班信息...
|
||||||
|
2026-01-31 08:25:16 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-03 的排班信息 (格式: 02/03/2月3日)
|
||||||
|
2026-01-31 08:25:16 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-31 08:25:17 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-31 08:25:17 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:17 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7197秒
|
||||||
|
2026-01-31 08:25:17 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-31 08:25:17 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月3日 解析表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:17 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-31 08:25:17 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-31 08:25:17 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-31 08:25:17 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月3日 -> 2月3日 (索引: 3)
|
||||||
|
2026-01-31 08:25:17 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:17 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:17 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-03
|
||||||
|
2026-01-31 08:25:17 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-03 的排班信息到数据库: 白班=梁启迟、汪钦良, 夜班=刘炜彬、杨俊豪
|
||||||
|
2026-01-31 08:25:17 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-04 的排班信息...
|
||||||
|
2026-01-31 08:25:17 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-04 的排班信息 (格式: 02/04/2月4日)
|
||||||
|
2026-01-31 08:25:17 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-31 08:25:17 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-31 08:25:17 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:17 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-31 08:25:17 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-31 08:25:17 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月4日 解析表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:17 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-31 08:25:17 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-31 08:25:17 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-31 08:25:17 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月4日 -> 2月4日 (索引: 4)
|
||||||
|
2026-01-31 08:25:17 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:17 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:17 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-04
|
||||||
|
2026-01-31 08:25:17 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-04 的排班信息到数据库: 白班=梁启迟、汪钦良, 夜班=刘炜彬、杨俊豪
|
||||||
|
2026-01-31 08:25:17 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-05 的排班信息...
|
||||||
|
2026-01-31 08:25:17 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-05 的排班信息 (格式: 02/05/2月5日)
|
||||||
|
2026-01-31 08:25:17 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-31 08:25:18 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:18 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7196秒
|
||||||
|
2026-01-31 08:25:18 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月5日 解析表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:18 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-31 08:25:18 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-31 08:25:18 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-31 08:25:18 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月5日 -> 2月5日 (索引: 5)
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:18 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-05
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-05 的排班信息到数据库: 白班=汪钦良、牛晨, 夜班=冯栋、杨俊豪
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - DEBUG - manager.py:223 - 刷新 2026-02-06 的排班信息...
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-06 的排班信息 (格式: 02/06/2月6日)
|
||||||
|
2026-01-31 08:25:18 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7195秒
|
||||||
|
2026-01-31 08:25:18 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:18 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7195秒
|
||||||
|
2026-01-31 08:25:18 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月6日 解析表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:18 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-31 08:25:18 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-31 08:25:18 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-31 08:25:18 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月6日 -> 2月6日 (索引: 6)
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:18 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-06
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-06 的排班信息到数据库: 白班=汪钦良、牛晨, 夜班=冯栋、杨俊豪
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:230 - 排班信息刷新完成,成功: 7, 失败: 0
|
||||||
|
2026-01-31 08:25:18 - __main__ - INFO - gui.py:650 - 生成 2026-01-31 的日报...
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:18 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:18 - src.report - INFO - report.py:34 - 日报生成器初始化完成
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-31 08:25:18 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-31 08:25:18 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:18 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-31 08:25:18 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-31 08:25:18 - src.report - INFO - report.py:266 - 获取 2026-01-31 日报的班次人员,对应排班表日期: 2026-02-01
|
||||||
|
2026-01-31 08:25:18 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-02-01 的排班信息 (格式: 02/01/2月1日)
|
||||||
|
2026-01-31 08:25:19 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-31 08:25:19 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7195秒
|
||||||
|
2026-01-31 08:25:19 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7195 秒后过期
|
||||||
|
2026-01-31 08:25:19 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-31 08:25:19 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:19 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7194秒
|
||||||
|
2026-01-31 08:25:20 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-31 08:25:20 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 2月1日 解析表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:20 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-31 08:25:20 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-31 08:25:20 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 2月 (行: 14)
|
||||||
|
2026-01-31 08:25:20 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 2月1日 -> 2月1日 (索引: 1)
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-02-01
|
||||||
|
2026-01-31 08:25:20 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-02-01 的排班信息到数据库: 白班=梁启迟、牛晨, 夜班=冯栋、刘炜彬
|
||||||
|
2026-01-31 08:25:20 - src.report - INFO - report.py:371 - 日报生成完成: 2026-01-31
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:667 - 日报生成完成: 2026-01-31
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:710 - 排班信息刷新完成
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:726 - 正在尝试获取最新作业数据...
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:751 - 正在从 Confluence 获取 HTML...
|
||||||
|
2026-01-31 08:25:20 - src.confluence.client - DEBUG - client.py:50 - Confluence客户端初始化完成,基础URL: https://confluence.westwell-lab.com/rest/api
|
||||||
|
2026-01-31 08:25:20 - src.confluence.client - DEBUG - client.py:76 - 获取Confluence内容: 159049182
|
||||||
|
2026-01-31 08:25:20 - src.confluence.client - INFO - client.py:81 - 成功获取Confluence内容: 159049182
|
||||||
|
2026-01-31 08:25:20 - src.confluence.client - INFO - client.py:122 - 获取到Confluence HTML内容,长度: 86366 字符
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:757 - 获取成功,共 86366 字符
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:761 - 正在提取布局文本...
|
||||||
|
2026-01-31 08:25:20 - src.confluence.text - DEBUG - text.py:60 - 开始解析HTML,长度: 86366 字符
|
||||||
|
2026-01-31 08:25:20 - src.confluence.text - INFO - text.py:83 - HTML提取完成,输出长度: 19525 字符
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:767 - 正在解析日志数据...
|
||||||
|
2026-01-31 08:25:20 - src.confluence.log_parser - INFO - log_parser.py:390 - 解析转堆作业: 2026-01-02 白班 2TEU
|
||||||
|
2026-01-31 08:25:20 - src.confluence.log_parser - INFO - log_parser.py:209 - 日志解析完成,共 159 条记录
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:774 - 正在保存到数据库...
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.database.daily_logs - INFO - daily_logs.py:237 - 批量插入完成,成功 159/159 条记录
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:778 - 已保存 159 条新记录
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:806 - 正在生成今日日报...
|
||||||
|
2026-01-31 08:25:20 - __main__ - INFO - gui.py:650 - 生成 2026-01-30 的日报...
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.daily_logs - DEBUG - daily_logs.py:160 - 数据库表结构初始化完成
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.report - INFO - report.py:34 - 日报生成器初始化完成
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.feishu.manager - INFO - manager.py:53 - 使用飞书应用凭证自动获取token
|
||||||
|
2026-01-31 08:25:20 - src.feishu.client - DEBUG - client.py:56 - 飞书客户端初始化完成,基础URL: https://open.feishu.cn/open-apis/sheets/v3
|
||||||
|
2026-01-31 08:25:20 - src.feishu.client - DEBUG - client.py:57 - 使用应用ID: cli_a9d9... 如果配置
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:20 - src.database.schedules - DEBUG - schedules.py:71 - 排班数据库表结构初始化完成
|
||||||
|
2026-01-31 08:25:20 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:20 - src.feishu.manager - INFO - manager.py:41 - 飞书排班管理器初始化完成
|
||||||
|
2026-01-31 08:25:20 - src.report - INFO - report.py:266 - 获取 2026-01-30 日报的班次人员,对应排班表日期: 2026-01-31
|
||||||
|
2026-01-31 08:25:20 - src.feishu.manager - INFO - manager.py:138 - 获取 2026-01-31 的排班信息 (格式: 01/31/1月31日)
|
||||||
|
2026-01-31 08:25:20 - src.feishu.client - INFO - client.py:98 - 正在获取tenant_access_token,应用ID: cli_a9d9...
|
||||||
|
2026-01-31 08:25:20 - src.feishu.client - INFO - client.py:114 - 成功获取tenant_access_token,有效期: 7194秒
|
||||||
|
2026-01-31 08:25:20 - src.feishu.client - INFO - client.py:156 - token获取成功,将在 7194 秒后过期
|
||||||
|
2026-01-31 08:25:21 - src.feishu.client - INFO - client.py:203 - 获取到 7 个表格
|
||||||
|
2026-01-31 08:25:21 - src.feishu.manager - INFO - manager.py:90 - 找到2026年年度表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:21 - src.feishu.client - DEBUG - client.py:142 - token仍然有效,剩余时间: 7193秒
|
||||||
|
2026-01-31 08:25:21 - src.feishu.client - DEBUG - client.py:252 - 获取表格数据成功: R35cIj, 范围: A:AF
|
||||||
|
2026-01-31 08:25:21 - src.feishu.manager - INFO - manager.py:174 - 使用日期格式: 1月31日 解析表格: 2026年排班表
|
||||||
|
2026-01-31 08:25:21 - src.feishu.parser - INFO - parser.py:267 - 使用年度表格解析器: 2026年排班表
|
||||||
|
2026-01-31 08:25:21 - src.feishu.parser - DEBUG - parser.py:201 - 找到月份块: 1月 (行: 1)
|
||||||
|
2026-01-31 08:25:21 - src.feishu.parser - DEBUG - parser.py:108 - 找到日期列: 1月31日 -> 1月31日 (索引: 31)
|
||||||
|
2026-01-31 08:25:21 - src.database.base - DEBUG - base.py:57 - 数据库连接已建立: data/daily_logs.db
|
||||||
|
2026-01-31 08:25:21 - src.database.base - DEBUG - base.py:87 - 数据库连接已关闭
|
||||||
|
2026-01-31 08:25:21 - src.database.schedules - DEBUG - schedules.py:182 - 保存排班信息: 2026-01-31
|
||||||
|
2026-01-31 08:25:21 - src.feishu.manager - INFO - manager.py:180 - 已更新 2026-01-31 的排班信息到数据库: 白班=梁启迟、汪钦良、牛晨, 夜班=冯栋、刘炜彬
|
||||||
|
2026-01-31 08:25:21 - src.report - INFO - report.py:371 - 日报生成完成: 2026-01-30
|
||||||
|
2026-01-31 08:25:21 - __main__ - INFO - gui.py:667 - 日报生成完成: 2026-01-30
|
||||||
|
2026-01-31 08:25:21 - __main__ - INFO - gui.py:811 - 自动获取完成,GUI已就绪
|
||||||
1661
src/logs/2026-02/2026-02-01.log
Normal file
1661
src/logs/2026-02/2026-02-01.log
Normal file
File diff suppressed because it is too large
Load Diff
@@ -139,14 +139,52 @@ class DailyReportGenerator:
|
|||||||
if log.get('teu'):
|
if log.get('teu'):
|
||||||
daily_totals[d] += log['teu']
|
daily_totals[d] += log['teu']
|
||||||
|
|
||||||
|
# 计算当月天数(已过的天数)
|
||||||
|
current_date = datetime.strptime(date, '%Y-%m-%d')
|
||||||
|
if current_date.day == config.FIRST_DAY_OF_MONTH_SPECIAL:
|
||||||
|
days_passed = 1
|
||||||
|
else:
|
||||||
|
days_passed = current_date.day
|
||||||
|
|
||||||
# 获取当月所有日期的调整数据
|
# 获取当月所有日期的调整数据
|
||||||
total_adjustment_teu = 0
|
total_adjustment_teu = 0
|
||||||
adjustment_details: Dict[str, Dict[str, int]] = {}
|
adjustment_details: Dict[str, Dict[str, int]] = {}
|
||||||
|
|
||||||
# 获取当月所有日期的调整数据
|
# 直接获取整个月份的所有调整记录
|
||||||
for day in range(1, target_date.day + 1):
|
# 这样可以确保即使在生成日报之后执行的剔除操作也能影响当月实际作业量
|
||||||
|
if hasattr(self.db, 'get_monthly_adjustments'):
|
||||||
|
monthly_adjustments = self.db.get_monthly_adjustments(year_month)
|
||||||
|
|
||||||
|
# 按日期汇总调整数据
|
||||||
|
date_adjustments: Dict[str, int] = {}
|
||||||
|
for adj in monthly_adjustments:
|
||||||
|
adj_date = adj['date']
|
||||||
|
if adj_date not in date_adjustments:
|
||||||
|
date_adjustments[adj_date] = 0
|
||||||
|
if adj['adjustment_type'] == 'add':
|
||||||
|
date_adjustments[adj_date] += adj['teu']
|
||||||
|
elif adj['adjustment_type'] == 'exclude':
|
||||||
|
date_adjustments[adj_date] -= adj['teu']
|
||||||
|
|
||||||
|
# 计算总调整量并构建调整详情
|
||||||
|
for adj_date, adj_teu in date_adjustments.items():
|
||||||
|
if adj_teu != 0:
|
||||||
|
total_adjustment_teu += adj_teu
|
||||||
|
# 获取该日期的详细数据
|
||||||
|
if hasattr(self.db, 'get_daily_data_with_adjustments'):
|
||||||
|
daily_data = self.db.get_daily_data_with_adjustments(adj_date)
|
||||||
|
adjustment_details[adj_date] = {
|
||||||
|
'adjustment_teu': adj_teu,
|
||||||
|
'total_teu': daily_data.get('total_teu', 0)
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
# 降级处理:如果没有新方法,使用按天循环查询
|
||||||
|
days_in_month = target_date.day
|
||||||
|
if current_date.day == config.FIRST_DAY_OF_MONTH_SPECIAL:
|
||||||
|
days_in_month = 1
|
||||||
|
|
||||||
|
for day in range(1, days_in_month + 1):
|
||||||
day_str = f"{year_month}-{day:02d}"
|
day_str = f"{year_month}-{day:02d}"
|
||||||
if day_str <= date: # 只统计到指定日期
|
|
||||||
# 获取该日期的调整数据
|
# 获取该日期的调整数据
|
||||||
if hasattr(self.db, 'get_daily_data_with_adjustments'):
|
if hasattr(self.db, 'get_daily_data_with_adjustments'):
|
||||||
daily_data = self.db.get_daily_data_with_adjustments(day_str)
|
daily_data = self.db.get_daily_data_with_adjustments(day_str)
|
||||||
@@ -158,13 +196,6 @@ class DailyReportGenerator:
|
|||||||
'total_teu': daily_data.get('total_teu', 0)
|
'total_teu': daily_data.get('total_teu', 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
# 计算当月天数(已过的天数)
|
|
||||||
current_date = datetime.strptime(date, '%Y-%m-%d')
|
|
||||||
if current_date.day == config.FIRST_DAY_OF_MONTH_SPECIAL:
|
|
||||||
days_passed = 1
|
|
||||||
else:
|
|
||||||
days_passed = current_date.day
|
|
||||||
|
|
||||||
# 获取未统计数据
|
# 获取未统计数据
|
||||||
unaccounted = self.db.get_unaccounted(year_month)
|
unaccounted = self.db.get_unaccounted(year_month)
|
||||||
|
|
||||||
|
|||||||
356
src/retry.py
Normal file
356
src/retry.py
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
重试机制模块
|
||||||
|
提供重试装饰器和工具函数
|
||||||
|
"""
|
||||||
|
import time
|
||||||
|
import logging
|
||||||
|
from functools import wraps
|
||||||
|
from typing import Callable, Optional, Type, Tuple, Any
|
||||||
|
|
||||||
|
from src.logging_config import get_logger
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def retry(
|
||||||
|
max_attempts: int = 3,
|
||||||
|
delay: float = 1.0,
|
||||||
|
backoff_factor: float = 2.0,
|
||||||
|
exceptions: Optional[Tuple[Type[Exception], ...]] = None,
|
||||||
|
on_retry: Optional[Callable[[int, Exception], None]] = None
|
||||||
|
) -> Callable:
|
||||||
|
"""
|
||||||
|
重试装饰器
|
||||||
|
|
||||||
|
参数:
|
||||||
|
max_attempts: 最大重试次数
|
||||||
|
delay: 初始延迟时间(秒)
|
||||||
|
backoff_factor: 退避因子,每次重试延迟时间乘以该因子
|
||||||
|
exceptions: 要捕获的异常类型,None表示捕获所有异常
|
||||||
|
on_retry: 重试时的回调函数,参数为 (attempt, exception)
|
||||||
|
|
||||||
|
使用示例:
|
||||||
|
@retry(max_attempts=3, delay=2.0, backoff_factor=2.0)
|
||||||
|
def fetch_data():
|
||||||
|
# 可能失败的代码
|
||||||
|
pass
|
||||||
|
|
||||||
|
@retry(max_attempts=5, exceptions=(ConnectionError, TimeoutError))
|
||||||
|
def network_request():
|
||||||
|
# 网络请求代码
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
def decorator(func: Callable) -> Callable:
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs) -> Any:
|
||||||
|
last_exception = None
|
||||||
|
|
||||||
|
for attempt in range(max_attempts):
|
||||||
|
try:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
# 检查是否需要捕获此异常
|
||||||
|
if exceptions and not isinstance(e, exceptions):
|
||||||
|
raise
|
||||||
|
|
||||||
|
last_exception = e
|
||||||
|
|
||||||
|
# 如果是最后一次尝试,不再重试
|
||||||
|
if attempt == max_attempts - 1:
|
||||||
|
logger.error(
|
||||||
|
f"{func.__name__} 在 {max_attempts} 次尝试后仍然失败: {e}"
|
||||||
|
)
|
||||||
|
raise
|
||||||
|
|
||||||
|
# 计算延迟时间
|
||||||
|
current_delay = delay * (backoff_factor ** attempt)
|
||||||
|
|
||||||
|
logger.warning(
|
||||||
|
f"{func.__name__} 第 {attempt + 1} 次尝试失败: {e}, "
|
||||||
|
f"{current_delay:.2f}秒后重试..."
|
||||||
|
)
|
||||||
|
|
||||||
|
# 调用重试回调
|
||||||
|
if on_retry:
|
||||||
|
try:
|
||||||
|
on_retry(attempt + 1, e)
|
||||||
|
except Exception as callback_error:
|
||||||
|
logger.error(f"重试回调执行失败: {callback_error}")
|
||||||
|
|
||||||
|
# 等待
|
||||||
|
time.sleep(current_delay)
|
||||||
|
|
||||||
|
# 理论上不会到达这里,但为了类型检查
|
||||||
|
if last_exception:
|
||||||
|
raise last_exception
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def retry_with_exponential_backoff(
|
||||||
|
max_attempts: int = 3,
|
||||||
|
initial_delay: float = 1.0,
|
||||||
|
max_delay: float = 60.0
|
||||||
|
) -> Callable:
|
||||||
|
"""
|
||||||
|
使用指数退避的重试装饰器
|
||||||
|
|
||||||
|
参数:
|
||||||
|
max_attempts: 最大重试次数
|
||||||
|
initial_delay: 初始延迟时间(秒)
|
||||||
|
max_delay: 最大延迟时间(秒)
|
||||||
|
|
||||||
|
使用示例:
|
||||||
|
@retry_with_exponential_backoff(max_attempts=5, initial_delay=2.0)
|
||||||
|
def api_call():
|
||||||
|
# API调用代码
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
def decorator(func: Callable) -> Callable:
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs) -> Any:
|
||||||
|
last_exception = None
|
||||||
|
|
||||||
|
for attempt in range(max_attempts):
|
||||||
|
try:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
last_exception = e
|
||||||
|
|
||||||
|
if attempt == max_attempts - 1:
|
||||||
|
logger.error(
|
||||||
|
f"{func.__name__} 在 {max_attempts} 次尝试后仍然失败: {e}"
|
||||||
|
)
|
||||||
|
raise
|
||||||
|
|
||||||
|
# 计算延迟时间(指数退避,但不超过最大延迟)
|
||||||
|
current_delay = min(initial_delay * (2 ** attempt), max_delay)
|
||||||
|
|
||||||
|
logger.warning(
|
||||||
|
f"{func.__name__} 第 {attempt + 1} 次尝试失败: {e}, "
|
||||||
|
f"{current_delay:.2f}秒后重试..."
|
||||||
|
)
|
||||||
|
|
||||||
|
time.sleep(current_delay)
|
||||||
|
|
||||||
|
if last_exception:
|
||||||
|
raise last_exception
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def retry_on_exception(
|
||||||
|
exception_type: Type[Exception],
|
||||||
|
max_attempts: int = 3,
|
||||||
|
delay: float = 1.0
|
||||||
|
) -> Callable:
|
||||||
|
"""
|
||||||
|
只在特定异常时重试的装饰器
|
||||||
|
|
||||||
|
参数:
|
||||||
|
exception_type: 要捕获的异常类型
|
||||||
|
max_attempts: 最大重试次数
|
||||||
|
delay: 延迟时间(秒)
|
||||||
|
|
||||||
|
使用示例:
|
||||||
|
@retry_on_exception(ConnectionError, max_attempts=5, delay=2.0)
|
||||||
|
def fetch_data():
|
||||||
|
# 可能抛出 ConnectionError 的代码
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
def decorator(func: Callable) -> Callable:
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs) -> Any:
|
||||||
|
last_exception = None
|
||||||
|
|
||||||
|
for attempt in range(max_attempts):
|
||||||
|
try:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except exception_type as e:
|
||||||
|
last_exception = e
|
||||||
|
|
||||||
|
if attempt == max_attempts - 1:
|
||||||
|
logger.error(
|
||||||
|
f"{func.__name__} 在 {max_attempts} 次尝试后仍然失败: {e}"
|
||||||
|
)
|
||||||
|
raise
|
||||||
|
|
||||||
|
logger.warning(
|
||||||
|
f"{func.__name__} 第 {attempt + 1} 次尝试失败: {e}, "
|
||||||
|
f"{delay:.2f}秒后重试..."
|
||||||
|
)
|
||||||
|
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
if last_exception:
|
||||||
|
raise last_exception
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
class RetryContext:
|
||||||
|
"""重试上下文管理器"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
operation_name: str,
|
||||||
|
max_attempts: int = 3,
|
||||||
|
delay: float = 1.0,
|
||||||
|
backoff_factor: float = 2.0,
|
||||||
|
exceptions: Optional[Tuple[Type[Exception], ...]] = None
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
初始化重试上下文
|
||||||
|
|
||||||
|
参数:
|
||||||
|
operation_name: 操作名称
|
||||||
|
max_attempts: 最大重试次数
|
||||||
|
delay: 初始延迟时间(秒)
|
||||||
|
backoff_factor: 退避因子
|
||||||
|
exceptions: 要捕获的异常类型
|
||||||
|
"""
|
||||||
|
self.operation_name = operation_name
|
||||||
|
self.max_attempts = max_attempts
|
||||||
|
self.delay = delay
|
||||||
|
self.backoff_factor = backoff_factor
|
||||||
|
self.exceptions = exceptions
|
||||||
|
self.attempt = 0
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.attempt = 0
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
|
if exc_type is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 检查是否需要捕获此异常
|
||||||
|
if self.exceptions and not isinstance(exc_val, self.exceptions):
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.attempt += 1
|
||||||
|
|
||||||
|
# 如果超过最大尝试次数,不再重试
|
||||||
|
if self.attempt >= self.max_attempts:
|
||||||
|
logger.error(
|
||||||
|
f"{self.operation_name} 在 {self.max_attempts} 次尝试后仍然失败: {exc_val}"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 计算延迟时间
|
||||||
|
current_delay = self.delay * (self.backoff_factor ** (self.attempt - 1))
|
||||||
|
|
||||||
|
logger.warning(
|
||||||
|
f"{self.operation_name} 第 {self.attempt} 次尝试失败: {exc_val}, "
|
||||||
|
f"{current_delay:.2f}秒后重试..."
|
||||||
|
)
|
||||||
|
|
||||||
|
# 等待
|
||||||
|
time.sleep(current_delay)
|
||||||
|
|
||||||
|
# 抑制异常,继续重试
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def async_retry(
|
||||||
|
max_attempts: int = 3,
|
||||||
|
delay: float = 1.0,
|
||||||
|
backoff_factor: float = 2.0
|
||||||
|
) -> Callable:
|
||||||
|
"""
|
||||||
|
异步重试装饰器(用于异步函数)
|
||||||
|
|
||||||
|
参数:
|
||||||
|
max_attempts: 最大重试次数
|
||||||
|
delay: 初始延迟时间(秒)
|
||||||
|
backoff_factor: 退避因子
|
||||||
|
|
||||||
|
使用示例:
|
||||||
|
@async_retry(max_attempts=3, delay=2.0)
|
||||||
|
async def async_fetch_data():
|
||||||
|
# 异步代码
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
def decorator(func: Callable) -> Callable:
|
||||||
|
@wraps(func)
|
||||||
|
async def wrapper(*args, **kwargs) -> Any:
|
||||||
|
last_exception = None
|
||||||
|
|
||||||
|
for attempt in range(max_attempts):
|
||||||
|
try:
|
||||||
|
return await func(*args, **kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
last_exception = e
|
||||||
|
|
||||||
|
if attempt == max_attempts - 1:
|
||||||
|
logger.error(
|
||||||
|
f"{func.__name__} 在 {max_attempts} 次尝试后仍然失败: {e}"
|
||||||
|
)
|
||||||
|
raise
|
||||||
|
|
||||||
|
# 计算延迟时间
|
||||||
|
current_delay = delay * (backoff_factor ** attempt)
|
||||||
|
|
||||||
|
logger.warning(
|
||||||
|
f"{func.__name__} 第 {attempt + 1} 次尝试失败: {e}, "
|
||||||
|
f"{current_delay:.2f}秒后重试..."
|
||||||
|
)
|
||||||
|
|
||||||
|
# 异步等待
|
||||||
|
await asyncio.sleep(current_delay)
|
||||||
|
|
||||||
|
if last_exception:
|
||||||
|
raise last_exception
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# 测试代码
|
||||||
|
|
||||||
|
# 测试重试装饰器
|
||||||
|
call_count = 0
|
||||||
|
|
||||||
|
@retry(max_attempts=3, delay=0.1)
|
||||||
|
def test_retry():
|
||||||
|
global call_count
|
||||||
|
call_count += 1
|
||||||
|
print(f"调用次数: {call_count}")
|
||||||
|
if call_count < 3:
|
||||||
|
raise ValueError("测试异常")
|
||||||
|
return "成功"
|
||||||
|
|
||||||
|
result = test_retry()
|
||||||
|
print(f"测试结果: {result}")
|
||||||
|
|
||||||
|
# 测试重试上下文管理器
|
||||||
|
context_call_count = 0
|
||||||
|
|
||||||
|
def test_context_operation():
|
||||||
|
global context_call_count
|
||||||
|
context_call_count += 1
|
||||||
|
print(f"上下文调用次数: {context_call_count}")
|
||||||
|
if context_call_count < 3:
|
||||||
|
raise ValueError("测试异常")
|
||||||
|
return "成功"
|
||||||
|
|
||||||
|
with RetryContext("测试操作", max_attempts=3, delay=0.1):
|
||||||
|
result = test_context_operation()
|
||||||
|
print(f"上下文测试结果: {result}")
|
||||||
|
|
||||||
|
# 测试特定异常重试
|
||||||
|
@retry_on_exception(ValueError, max_attempts=3, delay=0.1)
|
||||||
|
def test_specific_exception():
|
||||||
|
raise ValueError("测试异常")
|
||||||
|
|
||||||
|
try:
|
||||||
|
test_specific_exception()
|
||||||
|
except ValueError as e:
|
||||||
|
print(f"特定异常测试: {e}")
|
||||||
Reference in New Issue
Block a user