同步更新:重构路由、服务模块,更新前端构建
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
import os
|
||||
from datetime import timedelta
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
|
||||
# 尝试加载.env文件(如果存在)
|
||||
# Bug fix: 添加警告日志,避免静默失败
|
||||
@@ -48,6 +49,33 @@ def get_secret_key():
|
||||
return new_key
|
||||
|
||||
|
||||
def _derive_base_url_from_full_url(url: str, fallback: str) -> str:
|
||||
"""从完整 URL 推导出 base_url(scheme://netloc)。"""
|
||||
try:
|
||||
parsed = urlsplit(str(url or "").strip())
|
||||
if parsed.scheme and parsed.netloc:
|
||||
return f"{parsed.scheme}://{parsed.netloc}"
|
||||
except Exception:
|
||||
pass
|
||||
return fallback
|
||||
|
||||
|
||||
def _derive_sibling_url(full_url: str, filename: str, fallback: str) -> str:
|
||||
"""把 full_url 的最后路径段替换为 filename(忽略 query/fragment)。"""
|
||||
try:
|
||||
parsed = urlsplit(str(full_url or "").strip())
|
||||
if not parsed.scheme or not parsed.netloc:
|
||||
return fallback
|
||||
path = parsed.path or "/"
|
||||
if path.endswith("/"):
|
||||
new_path = path + filename
|
||||
else:
|
||||
new_path = path.rsplit("/", 1)[0] + "/" + filename
|
||||
return urlunsplit((parsed.scheme, parsed.netloc, new_path, "", ""))
|
||||
except Exception:
|
||||
return fallback
|
||||
|
||||
|
||||
class Config:
|
||||
"""应用配置基类"""
|
||||
|
||||
@@ -93,6 +121,7 @@ class Config:
|
||||
|
||||
# ==================== 浏览器配置 ====================
|
||||
SCREENSHOTS_DIR = os.environ.get('SCREENSHOTS_DIR', '截图')
|
||||
COOKIES_DIR = os.environ.get('COOKIES_DIR', 'data/cookies')
|
||||
|
||||
# ==================== 并发控制配置 ====================
|
||||
MAX_CONCURRENT_GLOBAL = int(os.environ.get('MAX_CONCURRENT_GLOBAL', '2'))
|
||||
@@ -102,6 +131,11 @@ class Config:
|
||||
MAX_LOGS_PER_USER = int(os.environ.get('MAX_LOGS_PER_USER', '100'))
|
||||
MAX_TOTAL_LOGS = int(os.environ.get('MAX_TOTAL_LOGS', '1000'))
|
||||
|
||||
# ==================== 内存/缓存清理配置 ====================
|
||||
USER_ACCOUNTS_EXPIRE_SECONDS = int(os.environ.get('USER_ACCOUNTS_EXPIRE_SECONDS', '3600'))
|
||||
BATCH_TASK_EXPIRE_SECONDS = int(os.environ.get('BATCH_TASK_EXPIRE_SECONDS', '21600')) # 默认6小时
|
||||
PENDING_RANDOM_EXPIRE_SECONDS = int(os.environ.get('PENDING_RANDOM_EXPIRE_SECONDS', '7200')) # 默认2小时
|
||||
|
||||
# ==================== 验证码配置 ====================
|
||||
MAX_CAPTCHA_ATTEMPTS = int(os.environ.get('MAX_CAPTCHA_ATTEMPTS', '5'))
|
||||
CAPTCHA_EXPIRE_SECONDS = int(os.environ.get('CAPTCHA_EXPIRE_SECONDS', '300'))
|
||||
@@ -117,6 +151,12 @@ class Config:
|
||||
# ==================== 知识管理平台配置 ====================
|
||||
ZSGL_LOGIN_URL = os.environ.get('ZSGL_LOGIN_URL', 'https://postoa.aidunsoft.com/admin/login.aspx')
|
||||
ZSGL_INDEX_URL_PATTERN = os.environ.get('ZSGL_INDEX_URL_PATTERN', 'index.aspx')
|
||||
ZSGL_BASE_URL = os.environ.get('ZSGL_BASE_URL') or _derive_base_url_from_full_url(ZSGL_LOGIN_URL, 'https://postoa.aidunsoft.com')
|
||||
ZSGL_INDEX_URL = os.environ.get('ZSGL_INDEX_URL') or _derive_sibling_url(
|
||||
ZSGL_LOGIN_URL,
|
||||
ZSGL_INDEX_URL_PATTERN,
|
||||
f"{ZSGL_BASE_URL}/admin/{ZSGL_INDEX_URL_PATTERN}",
|
||||
)
|
||||
MAX_CONCURRENT_CONTEXTS = int(os.environ.get('MAX_CONCURRENT_CONTEXTS', '100'))
|
||||
|
||||
# ==================== 服务器配置 ====================
|
||||
|
||||
Reference in New Issue
Block a user