更新Company页面的UI为FUI风格

This commit is contained in:
2025-12-19 15:53:46 +08:00
parent 6776e1d557
commit 7fd1dc34f4

152
app.py
View File

@@ -217,6 +217,30 @@ def get_target_and_prev_trading_day(event_datetime):
# 应用启动时加载交易日数据
load_trading_days()
def is_trading_hours():
"""
判断当前是否在交易时间段内
交易时间:交易日的 9:00-15:00含午休时间因为事件可能在午休发布
Returns:
bool: True 表示在交易时间段False 表示非交易时间
"""
now = datetime.now()
today = now.date()
current_time = now.time()
# 判断今天是否为交易日
if today not in trading_days_set:
return False
# 判断是否在 9:00-15:00 之间
market_open = dt_time(9, 0)
market_close = dt_time(15, 0)
return market_open <= current_time <= market_close
engine = create_engine(
"mysql+pymysql://root:Zzl33818!@127.0.0.1:3306/stock?charset=utf8mb4",
echo=False,
@@ -300,6 +324,105 @@ def delete_verification_code(key):
print(f"📦 验证码存储: Redis, 过期时间: {VERIFICATION_CODE_EXPIRE}")
# ============ 事件列表 Redis 缓存(智能 TTL 策略) ============
EVENTS_CACHE_PREFIX = "events:cache:"
EVENTS_CACHE_TTL_TRADING = 20 # 交易时间缓存 TTL
EVENTS_CACHE_TTL_NON_TRADING = 600 # 非交易时间缓存 TTL10分钟
def generate_events_cache_key(args_dict):
"""
根据请求参数生成缓存 Key
使用 MD5 哈希保证 key 长度固定且唯一
Args:
args_dict: 请求参数字典
Returns:
str: 缓存 key格式为 events:cache:{md5_hash}
"""
import hashlib
# 过滤掉空值,并排序保证顺序一致
filtered_params = {k: v for k, v in sorted(args_dict.items())
if v is not None and v != '' and v != 'all'}
# 生成参数字符串并计算 MD5
params_str = json.dumps(filtered_params, sort_keys=True)
params_hash = hashlib.md5(params_str.encode()).hexdigest()
return f"{EVENTS_CACHE_PREFIX}{params_hash}"
def get_events_cache(cache_key):
"""
从 Redis 获取事件列表缓存
Args:
cache_key: 缓存 key
Returns:
dict or None: 缓存的响应数据,如果不存在或出错返回 None
"""
try:
cached = redis_client.get(cache_key)
if cached:
return json.loads(cached)
return None
except Exception as e:
print(f"❌ Redis 获取事件缓存失败: {e}")
return None
def set_events_cache(cache_key, data):
"""
将事件列表数据存入 Redis 缓存
根据是否在交易时间自动选择 TTL
Args:
cache_key: 缓存 key
data: 要缓存的响应数据
Returns:
bool: 是否成功
"""
try:
# 根据交易时间选择 TTL
ttl = EVENTS_CACHE_TTL_TRADING if is_trading_hours() else EVENTS_CACHE_TTL_NON_TRADING
redis_client.setex(cache_key, ttl, json.dumps(data, ensure_ascii=False))
return True
except Exception as e:
print(f"❌ Redis 存储事件缓存失败: {e}")
return False
def clear_events_cache():
"""
清除所有事件列表缓存
用于事件数据更新后主动刷新缓存
"""
try:
# 使用 SCAN 命令迭代删除,避免 KEYS 命令阻塞
cursor = 0
deleted_count = 0
while True:
cursor, keys = redis_client.scan(cursor, match=f"{EVENTS_CACHE_PREFIX}*", count=100)
if keys:
redis_client.delete(*keys)
deleted_count += len(keys)
if cursor == 0:
break
if deleted_count > 0:
print(f"🗑️ 已清除 {deleted_count} 个事件缓存")
return deleted_count
except Exception as e:
print(f"❌ 清除事件缓存失败: {e}")
return 0
print(f"📦 事件列表缓存: 交易时间 {EVENTS_CACHE_TTL_TRADING}s / 非交易时间 {EVENTS_CACHE_TTL_NON_TRADING}s")
# ============ 微信登录 Session 管理Redis 存储,支持多进程) ============
WECHAT_SESSION_EXPIRE = 300 # Session 过期时间5分钟
WECHAT_SESSION_PREFIX = "wechat_session:"
@@ -10517,8 +10640,26 @@ def get_stock_list():
def api_get_events():
"""
获取事件列表API - 支持筛选、排序、分页,兼容前端调用
Redis 缓存策略:
- 交易时间(交易日 9:00-15:00缓存 20 秒
- 非交易时间:缓存 10 分钟
"""
try:
# ==================== Redis 缓存检查 ====================
# 获取所有请求参数用于生成缓存 key
cache_params = dict(request.args)
cache_key = generate_events_cache_key(cache_params)
# 尝试从缓存获取
cached_response = get_events_cache(cache_key)
if cached_response:
# 添加缓存命中标记(可选,用于调试)
cached_response['_cached'] = True
cached_response['_cache_ttl'] = EVENTS_CACHE_TTL_TRADING if is_trading_hours() else EVENTS_CACHE_TTL_NON_TRADING
return jsonify(cached_response)
# ==================== 缓存未命中,执行数据库查询 ====================
# 分页参数
page = max(1, request.args.get('page', 1, type=int))
per_page = min(100, max(1, request.args.get('per_page', 10, type=int)))
@@ -10776,7 +10917,9 @@ def api_get_events():
if search_query:
applied_filters['search_query'] = search_query
applied_filters['search_type'] = search_type
return jsonify({
# 构建响应数据
response_data = {
'success': True,
'data': {
'events': events_data,
@@ -10793,7 +10936,12 @@ def api_get_events():
'total_count': paginated.total
}
}
})
}
# ==================== 存入 Redis 缓存 ====================
set_events_cache(cache_key, response_data)
return jsonify(response_data)
except Exception as e:
app.logger.error(f"获取事件列表出错: {str(e)}", exc_info=True)
return jsonify({