fix
This commit is contained in:
136
app.py
136
app.py
@@ -97,38 +97,6 @@ def get_trading_day_near_date(target_date):
|
|||||||
return trading_days[-1] if trading_days else None
|
return trading_days[-1] if trading_days else None
|
||||||
|
|
||||||
|
|
||||||
def get_previous_trading_day(target_date):
|
|
||||||
"""
|
|
||||||
获取指定日期的上一个交易日
|
|
||||||
如果目标日期不是交易日,先找到对应的交易日,然后返回前一个交易日
|
|
||||||
"""
|
|
||||||
if not trading_days:
|
|
||||||
load_trading_days()
|
|
||||||
|
|
||||||
if not trading_days:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 如果目标日期是datetime,转换为date
|
|
||||||
if isinstance(target_date, datetime):
|
|
||||||
target_date = target_date.date()
|
|
||||||
|
|
||||||
# 确保目标日期是交易日
|
|
||||||
if target_date not in trading_days_set:
|
|
||||||
target_date = get_trading_day_near_date(target_date)
|
|
||||||
if not target_date:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 查找上一个交易日
|
|
||||||
try:
|
|
||||||
index = trading_days.index(target_date)
|
|
||||||
if index > 0:
|
|
||||||
return trading_days[index - 1]
|
|
||||||
else:
|
|
||||||
return None # 没有上一个交易日
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
# 应用启动时加载交易日数据
|
# 应用启动时加载交易日数据
|
||||||
load_trading_days()
|
load_trading_days()
|
||||||
|
|
||||||
@@ -2634,13 +2602,9 @@ def get_wechat_qrcode():
|
|||||||
# 生成唯一state参数
|
# 生成唯一state参数
|
||||||
state = uuid.uuid4().hex
|
state = uuid.uuid4().hex
|
||||||
|
|
||||||
print(f"🆕 [QRCODE] 生成新的微信二维码, state={state[:8]}...")
|
|
||||||
|
|
||||||
# URL编码回调地址
|
# URL编码回调地址
|
||||||
redirect_uri = urllib.parse.quote_plus(WECHAT_REDIRECT_URI)
|
redirect_uri = urllib.parse.quote_plus(WECHAT_REDIRECT_URI)
|
||||||
|
|
||||||
print(f"🔗 [QRCODE] 回调地址: {WECHAT_REDIRECT_URI}")
|
|
||||||
|
|
||||||
# 构建微信授权URL
|
# 构建微信授权URL
|
||||||
wechat_auth_url = (
|
wechat_auth_url = (
|
||||||
f"https://open.weixin.qq.com/connect/qrconnect?"
|
f"https://open.weixin.qq.com/connect/qrconnect?"
|
||||||
@@ -2658,8 +2622,6 @@ def get_wechat_qrcode():
|
|||||||
'wechat_unionid': None
|
'wechat_unionid': None
|
||||||
}
|
}
|
||||||
|
|
||||||
print(f"✅ [QRCODE] session 已存储, 当前总数: {len(wechat_qr_sessions)}")
|
|
||||||
|
|
||||||
return jsonify({"code":0,
|
return jsonify({"code":0,
|
||||||
"data":
|
"data":
|
||||||
{
|
{
|
||||||
@@ -2723,8 +2685,6 @@ def check_wechat_scan():
|
|||||||
del wechat_qr_sessions[session_id]
|
del wechat_qr_sessions[session_id]
|
||||||
return jsonify({'status': 'expired'}), 200
|
return jsonify({'status': 'expired'}), 200
|
||||||
|
|
||||||
print(f"📡 [CHECK] session_id: {session_id[:8]}..., status: {session['status']}, user_info: {session.get('user_info')}")
|
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'status': session['status'],
|
'status': session['status'],
|
||||||
'user_info': session.get('user_info'),
|
'user_info': session.get('user_info'),
|
||||||
@@ -2783,17 +2743,12 @@ def wechat_callback():
|
|||||||
|
|
||||||
# 验证state
|
# 验证state
|
||||||
if state not in wechat_qr_sessions:
|
if state not in wechat_qr_sessions:
|
||||||
print(f"❌ [CALLBACK] state 不在 wechat_qr_sessions 中: {state[:8]}...")
|
|
||||||
print(f" 当前 sessions: {list(wechat_qr_sessions.keys())}")
|
|
||||||
return redirect('/auth/signin?error=session_expired')
|
return redirect('/auth/signin?error=session_expired')
|
||||||
|
|
||||||
session_data = wechat_qr_sessions[state]
|
session_data = wechat_qr_sessions[state]
|
||||||
|
|
||||||
print(f"✅ [CALLBACK] 找到 session_data, mode={session_data.get('mode')}")
|
|
||||||
|
|
||||||
# 检查过期
|
# 检查过期
|
||||||
if time.time() > session_data['expires']:
|
if time.time() > session_data['expires']:
|
||||||
print(f"❌ [CALLBACK] session 已过期")
|
|
||||||
del wechat_qr_sessions[state]
|
del wechat_qr_sessions[state]
|
||||||
return redirect('/auth/signin?error=session_expired')
|
return redirect('/auth/signin?error=session_expired')
|
||||||
|
|
||||||
@@ -2822,8 +2777,6 @@ def wechat_callback():
|
|||||||
print(f"❌ 获取微信用户信息失败: openid={token_data['openid']}")
|
print(f"❌ 获取微信用户信息失败: openid={token_data['openid']}")
|
||||||
return redirect('/auth/signin?error=userinfo_failed')
|
return redirect('/auth/signin?error=userinfo_failed')
|
||||||
|
|
||||||
print(f"✅ [CALLBACK] 获取用户信息成功, nickname={user_info.get('nickname', 'N/A')}")
|
|
||||||
|
|
||||||
# 查找或创建用户 / 或处理绑定
|
# 查找或创建用户 / 或处理绑定
|
||||||
openid = token_data['openid']
|
openid = token_data['openid']
|
||||||
unionid = user_info.get('unionid') or token_data.get('unionid')
|
unionid = user_info.get('unionid') or token_data.get('unionid')
|
||||||
@@ -2874,8 +2827,7 @@ def wechat_callback():
|
|||||||
user = User.query.filter_by(wechat_open_id=openid).first()
|
user = User.query.filter_by(wechat_open_id=openid).first()
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
# 创建新用户(自动注册)
|
# 创建新用户
|
||||||
is_new_user = True
|
|
||||||
# 先清理微信昵称
|
# 先清理微信昵称
|
||||||
raw_nickname = user_info.get('nickname', '微信用户')
|
raw_nickname = user_info.get('nickname', '微信用户')
|
||||||
# 创建临时用户实例以使用清理方法
|
# 创建临时用户实例以使用清理方法
|
||||||
@@ -2925,22 +2877,8 @@ def wechat_callback():
|
|||||||
session_item['user_info'] = {'user_id': user.id}
|
session_item['user_info'] = {'user_id': user.id}
|
||||||
print(f"✅ 微信扫码状态已更新: {session_item['status']}, user_id: {user.id}")
|
print(f"✅ 微信扫码状态已更新: {session_item['status']}, user_id: {user.id}")
|
||||||
|
|
||||||
# 返回一个简单的成功页面(前端轮询会检测到状态变化)
|
# 直接跳转到首页
|
||||||
return '''
|
return redirect('/home')
|
||||||
<html>
|
|
||||||
<head><title>授权成功</title></head>
|
|
||||||
<body>
|
|
||||||
<h2>微信授权成功</h2>
|
|
||||||
<p>请返回原页面继续操作...</p>
|
|
||||||
<script>
|
|
||||||
// 尝试关闭窗口(如果是弹窗的话)
|
|
||||||
setTimeout(function() {
|
|
||||||
window.close();
|
|
||||||
}, 1000);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
''', 200
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"❌ 微信登录失败: {e}")
|
print(f"❌ 微信登录失败: {e}")
|
||||||
@@ -2966,16 +2904,16 @@ def login_with_wechat():
|
|||||||
return jsonify({'success': False, 'error': 'session_id不能为空'}), 400
|
return jsonify({'success': False, 'error': 'session_id不能为空'}), 400
|
||||||
|
|
||||||
# 验证session
|
# 验证session
|
||||||
wechat_session = wechat_qr_sessions.get(session_id)
|
session = wechat_qr_sessions.get(session_id)
|
||||||
if not wechat_session:
|
if not session:
|
||||||
return jsonify({'success': False, 'error': '会话不存在或已过期'}), 400
|
return jsonify({'success': False, 'error': '会话不存在或已过期'}), 400
|
||||||
|
|
||||||
# 检查session状态
|
# 检查session状态
|
||||||
if wechat_session['status'] not in ['login_success', 'register_success']:
|
if session['status'] not in ['login_ready', 'register_ready']:
|
||||||
return jsonify({'success': False, 'error': '会话状态无效'}), 400
|
return jsonify({'success': False, 'error': '会话状态无效'}), 400
|
||||||
|
|
||||||
# 检查是否有用户信息
|
# 检查是否有用户信息
|
||||||
user_info = wechat_session.get('user_info')
|
user_info = session.get('user_info')
|
||||||
if not user_info or not user_info.get('user_id'):
|
if not user_info or not user_info.get('user_id'):
|
||||||
return jsonify({'success': False, 'error': '用户信息不完整'}), 400
|
return jsonify({'success': False, 'error': '用户信息不完整'}), 400
|
||||||
|
|
||||||
@@ -2987,33 +2925,18 @@ def login_with_wechat():
|
|||||||
# 更新最后登录时间
|
# 更新最后登录时间
|
||||||
user.update_last_seen()
|
user.update_last_seen()
|
||||||
|
|
||||||
# 设置 Flask session
|
# 清除session
|
||||||
session.permanent = True
|
|
||||||
session['user_id'] = user.id
|
|
||||||
session['username'] = user.username
|
|
||||||
session['logged_in'] = True
|
|
||||||
session['wechat_login'] = True # 标记是微信登录
|
|
||||||
|
|
||||||
# Flask-Login 登录
|
|
||||||
login_user(user, remember=True)
|
|
||||||
|
|
||||||
# 判断是否为新用户
|
|
||||||
is_new_user = user_info.get('is_new_user', False)
|
|
||||||
|
|
||||||
# 清除 wechat_qr_sessions
|
|
||||||
del wechat_qr_sessions[session_id]
|
del wechat_qr_sessions[session_id]
|
||||||
|
|
||||||
# 生成登录响应
|
# 生成登录响应
|
||||||
response_data = {
|
response_data = {
|
||||||
'success': True,
|
'success': True,
|
||||||
'message': '注册成功' if is_new_user else '登录成功',
|
'message': '登录成功' if session['status'] == 'login_ready' else '注册并登录成功',
|
||||||
'isNewUser': is_new_user,
|
|
||||||
'user': {
|
'user': {
|
||||||
'id': user.id,
|
'id': user.id,
|
||||||
'username': user.username,
|
'username': user.username,
|
||||||
'nickname': user.nickname or user.username,
|
'nickname': user.nickname or user.username,
|
||||||
'email': user.email,
|
'email': user.email,
|
||||||
'phone': user.phone,
|
|
||||||
'avatar_url': user.avatar_url,
|
'avatar_url': user.avatar_url,
|
||||||
'has_wechat': True,
|
'has_wechat': True,
|
||||||
'wechat_open_id': user.wechat_open_id,
|
'wechat_open_id': user.wechat_open_id,
|
||||||
@@ -6627,9 +6550,6 @@ def api_get_events():
|
|||||||
event_status = request.args.get('status', 'active')
|
event_status = request.args.get('status', 'active')
|
||||||
importance = request.args.get('importance', 'all')
|
importance = request.args.get('importance', 'all')
|
||||||
|
|
||||||
# 交易日筛选参数
|
|
||||||
tday = request.args.get('tday') # 交易日,格式:YYYY-MM-DD 或 YYYY/M/D
|
|
||||||
|
|
||||||
# 日期筛选参数
|
# 日期筛选参数
|
||||||
start_date = request.args.get('start_date')
|
start_date = request.args.get('start_date')
|
||||||
end_date = request.args.get('end_date')
|
end_date = request.args.get('end_date')
|
||||||
@@ -6715,41 +6635,7 @@ def api_get_events():
|
|||||||
text(f"JSON_SEARCH(keywords, 'one', '%{search_query}%') IS NOT NULL")
|
text(f"JSON_SEARCH(keywords, 'one', '%{search_query}%') IS NOT NULL")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if recent_days:
|
||||||
# 交易日筛选逻辑
|
|
||||||
if tday:
|
|
||||||
from datetime import datetime, timedelta, time
|
|
||||||
try:
|
|
||||||
# 解析交易日参数,支持 YYYY-MM-DD 和 YYYY/M/D 格式
|
|
||||||
if '/' in tday:
|
|
||||||
target_tday = datetime.strptime(tday, '%Y/%m/%d').date()
|
|
||||||
else:
|
|
||||||
target_tday = datetime.strptime(tday, '%Y-%m-%d').date()
|
|
||||||
|
|
||||||
# 获取该交易日的上一个交易日
|
|
||||||
prev_tday = get_previous_trading_day(target_tday)
|
|
||||||
|
|
||||||
if prev_tday:
|
|
||||||
# 计算时间范围:[前一个交易日 15:00, 当前交易日 15:00]
|
|
||||||
start_datetime = datetime.combine(prev_tday, time(15, 0, 0))
|
|
||||||
end_datetime = datetime.combine(target_tday, time(15, 0, 0))
|
|
||||||
|
|
||||||
query = query.filter(
|
|
||||||
Event.created_at >= start_datetime,
|
|
||||||
Event.created_at <= end_datetime
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# 如果没有上一个交易日,则筛选当天的事件
|
|
||||||
start_datetime = datetime.combine(target_tday, time(0, 0, 0))
|
|
||||||
end_datetime = datetime.combine(target_tday, time(15, 0, 0))
|
|
||||||
query = query.filter(
|
|
||||||
Event.created_at >= start_datetime,
|
|
||||||
Event.created_at <= end_datetime
|
|
||||||
)
|
|
||||||
except (ValueError, TypeError) as e:
|
|
||||||
# 日期格式错误,忽略该参数
|
|
||||||
app.logger.warning(f"无效的交易日参数: {tday}, 错误: {e}")
|
|
||||||
elif recent_days:
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
cutoff_date = datetime.now() - timedelta(days=recent_days)
|
cutoff_date = datetime.now() - timedelta(days=recent_days)
|
||||||
query = query.filter(Event.created_at >= cutoff_date)
|
query = query.filter(Event.created_at >= cutoff_date)
|
||||||
@@ -6855,8 +6741,6 @@ def api_get_events():
|
|||||||
applied_filters['type'] = event_type
|
applied_filters['type'] = event_type
|
||||||
if importance != 'all':
|
if importance != 'all':
|
||||||
applied_filters['importance'] = importance
|
applied_filters['importance'] = importance
|
||||||
if tday:
|
|
||||||
applied_filters['tday'] = tday
|
|
||||||
if start_date:
|
if start_date:
|
||||||
applied_filters['start_date'] = start_date
|
applied_filters['start_date'] = start_date
|
||||||
if end_date:
|
if end_date:
|
||||||
|
|||||||
Reference in New Issue
Block a user