更新Company页面的UI为FUI风格
This commit is contained in:
152
app.py
152
app.py
@@ -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 # 非交易时间缓存 TTL(秒,10分钟)
|
||||
|
||||
|
||||
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({
|
||||
|
||||
Reference in New Issue
Block a user