准备对AI流式音频发回给前端的机制做较大的修改,先提交1个版本
This commit is contained in:
@@ -5,6 +5,7 @@ from contextlib import contextmanager
|
||||
from config import DATABASE_CONFIG
|
||||
from datetime import datetime,timedelta
|
||||
import logging
|
||||
from zoneinfo import ZoneInfo # Python 3.9+ 内置
|
||||
from typing import Union, List, Dict, Optional
|
||||
from tenacity import retry, stop_after_attempt, wait_fixed, retry_if_exception_type
|
||||
from dateutil.relativedelta import relativedelta
|
||||
@@ -415,6 +416,21 @@ def get_users(status: int = None, email: str = None, phone: str = None,openid: s
|
||||
|
||||
# 按用户ID获取用户
|
||||
def get_user_by_id(user_id: str):
|
||||
"""
|
||||
根据用户ID获取用户信息
|
||||
|
||||
功能说明:
|
||||
- 通过用户ID查询用户基本信息
|
||||
|
||||
参数说明:
|
||||
- user_id: 用户ID
|
||||
|
||||
返回:
|
||||
- 用户信息的字典,如果不存在则返回None
|
||||
|
||||
重要逻辑:
|
||||
- 直接查询用户表的所有字段
|
||||
"""
|
||||
sql = "SELECT * FROM rag_flow.users_info WHERE user_id = %s"
|
||||
result = execute_query(sql, (user_id,))
|
||||
return result[0] if result else None
|
||||
@@ -720,7 +736,7 @@ def update_order(order_id: str, update_data: dict) -> int:
|
||||
|
||||
from typing import Union, List, Dict, Optional
|
||||
|
||||
def get_order_by_id(order_id: str = None, user_id: str = None,combined = None) -> Union[Dict, List[Dict], None]:
|
||||
def get_order_by_id(order_id: str = None, user_id: str = None,combined:bool = False,museum_id:int = None) -> Union[Dict, List[Dict], None]:
|
||||
"""
|
||||
根据订单ID或用户ID查询订单信息
|
||||
|
||||
@@ -742,9 +758,25 @@ def get_order_by_id(order_id: str = None, user_id: str = None,combined = None) -
|
||||
- 使用参数化查询防止 SQL 注入
|
||||
- 当同时传入 order_id 和 user_id 时,优先使用 order_id
|
||||
"""
|
||||
if not order_id and not user_id:
|
||||
return None # 两个参数都未传入,直接返回 None
|
||||
sql_wo_condition= """
|
||||
# 无任何参数时返回 None
|
||||
if not any([order_id, user_id, museum_id]):
|
||||
return None
|
||||
# ========== 简单查询模式 ==========
|
||||
if not combined:
|
||||
# 优先使用 order_id 查询
|
||||
if order_id:
|
||||
sql = "SELECT * FROM subscription_orders WHERE order_id = %s"
|
||||
result = execute_query(sql, (order_id,))
|
||||
return result[0] if result and len(result) > 0 else None
|
||||
|
||||
# 使用 user_id 查询
|
||||
if user_id:
|
||||
sql = "SELECT * FROM subscription_orders WHERE user_id = %s"
|
||||
result = execute_query(sql, (user_id,))
|
||||
return result if result else []
|
||||
|
||||
# ========== 复杂查询模式 ==========
|
||||
base_sql= """
|
||||
SELECT
|
||||
o.order_id,
|
||||
o.user_id,
|
||||
@@ -774,25 +806,39 @@ def get_order_by_id(order_id: str = None, user_id: str = None,combined = None) -
|
||||
LEFT JOIN rag_flow.user_subscriptions us ON o.order_id = us.order_id
|
||||
LEFT JOIN rag_flow.mesum_overview mo ON ms.museum_id = mo.id
|
||||
"""
|
||||
# 优先使用 order_id 查询
|
||||
if order_id and not combined:
|
||||
sql = "SELECT * FROM subscription_orders WHERE order_id = %s"
|
||||
result = execute_query(sql, (order_id,))
|
||||
return result[0] if result and len(result) > 0 else None # 返回单个订单
|
||||
# 构建查询条件和参数
|
||||
conditions = []
|
||||
params = []
|
||||
|
||||
# 如果 order_id 不存在,使用 user_id 查询
|
||||
if user_id and not combined:
|
||||
sql = "SELECT * FROM subscription_orders WHERE user_id = %s"
|
||||
result = execute_query(sql, (user_id,))
|
||||
return result if result else [] # 返回所有订单(列表)
|
||||
if user_id and combined:
|
||||
sql = sql_wo_condition + f"\n WHERE o.user_id = %s"
|
||||
result = execute_query(sql, (user_id,))
|
||||
return result if result else [] # 返回所有订单(列表)
|
||||
if order_id and combined:
|
||||
sql = sql_wo_condition + f"\n WHERE o.order_id = %s"
|
||||
result = execute_query(sql, (order_id,))
|
||||
return result[0] if result and len(result) > 0 else None # 返回单个订单
|
||||
# 添加条件(按优先级)
|
||||
if order_id:
|
||||
conditions.append("o.order_id = %s")
|
||||
params.append(order_id)
|
||||
elif user_id:
|
||||
conditions.append("o.user_id = %s")
|
||||
params.append(user_id)
|
||||
|
||||
# 新增博物馆ID条件(可与其他条件组合)
|
||||
if museum_id:
|
||||
conditions.append("ms.museum_id = %s")
|
||||
params.append(museum_id)
|
||||
|
||||
# 构建完整SQL
|
||||
if conditions:
|
||||
where_clause = " WHERE " + " AND ".join(conditions)
|
||||
sql = base_sql + where_clause
|
||||
else:
|
||||
sql = base_sql
|
||||
|
||||
# 执行查询
|
||||
result = execute_query(sql, tuple(params))
|
||||
|
||||
# 处理返回结果
|
||||
if not result:
|
||||
return [] if user_id or museum_id else None
|
||||
|
||||
# 当有order_id时返回单个对象,否则返回列表
|
||||
return result[0] if order_id and not museum_id else result
|
||||
|
||||
def create_user_subscription(data: dict) -> int:
|
||||
"""
|
||||
@@ -875,27 +921,6 @@ def deactivate_previous_subscriptions(user_id: str, museum_subscription_id: str)
|
||||
return execute_query(sql, (user_id, museum_subscription_id), autocommit=True)
|
||||
|
||||
|
||||
def get_user_by_id(user_id: str) -> dict:
|
||||
"""
|
||||
根据用户ID获取用户信息
|
||||
|
||||
功能说明:
|
||||
- 通过用户ID查询用户基本信息
|
||||
|
||||
参数说明:
|
||||
- user_id: 用户ID
|
||||
|
||||
返回:
|
||||
- 用户信息的字典,如果不存在则返回None
|
||||
|
||||
重要逻辑:
|
||||
- 直接查询用户表的所有字段
|
||||
"""
|
||||
sql = "SELECT * FROM users_info WHERE user_id = %s"
|
||||
result = execute_query(sql, (user_id,))
|
||||
return result[0] if result else None
|
||||
|
||||
|
||||
def get_subscription_template_by_id(template_id: int) -> dict:
|
||||
"""
|
||||
根据模板ID获取订阅模板信息
|
||||
@@ -1175,6 +1200,75 @@ def check_user_subscription(user_id: str, museum_id: int) -> dict:
|
||||
return None
|
||||
|
||||
|
||||
def is_museum_free_period(museum_id: int) -> bool:
|
||||
"""
|
||||
检查博物馆当前是否处于免费时段
|
||||
|
||||
参数:
|
||||
- museum_id: 博物馆ID
|
||||
|
||||
返回:
|
||||
- True: 当前是免费时段
|
||||
- False: 当前不是免费时段
|
||||
"""
|
||||
# 查询博物馆的免费时段配置
|
||||
sql = """
|
||||
SELECT t.validity_type, t.valid_time_range, t.valid_week_days
|
||||
FROM museum_subscriptions ms
|
||||
JOIN subscription_templates t ON ms.template_id = t.id
|
||||
WHERE ms.museum_id = %s
|
||||
AND t.validity_type = 'free_interval'
|
||||
AND t.is_active = 1
|
||||
AND ms.is_active = 1
|
||||
LIMIT 1
|
||||
"""
|
||||
result = execute_query(sql, (museum_id,))
|
||||
if not result:
|
||||
return False
|
||||
|
||||
subscription = result[0]
|
||||
return is_subscription_valid(subscription)
|
||||
|
||||
|
||||
def get_user_valid_subscription(user_id: str, museum_id: int) -> bool:
|
||||
"""
|
||||
检查用户是否有有效的博物馆订阅
|
||||
|
||||
参数:
|
||||
- user_id: 用户ID
|
||||
- museum_id: 博物馆ID
|
||||
|
||||
返回:
|
||||
- True: 用户有有效订阅
|
||||
- False: 用户无有效订阅
|
||||
"""
|
||||
# 查询用户的有效订阅
|
||||
sql = """
|
||||
SELECT
|
||||
t.validity_type,
|
||||
t.valid_time_range,
|
||||
t.valid_week_days,
|
||||
us.start_date,
|
||||
us.end_date
|
||||
FROM user_subscriptions us
|
||||
JOIN museum_subscriptions ms ON us.museum_subscription_id = ms.sub_id
|
||||
JOIN subscription_templates t ON ms.template_id = t.id
|
||||
WHERE us.user_id = %s
|
||||
AND ms.museum_id = %s
|
||||
AND us.is_active = 1
|
||||
AND ms.is_active = 1
|
||||
AND t.is_active = 1
|
||||
AND us.start_date <= NOW()
|
||||
AND us.end_date >= NOW()
|
||||
"""
|
||||
subscriptions = execute_query(sql, (user_id, museum_id))
|
||||
|
||||
# 检查每个订阅是否在当前时间有效
|
||||
for sub in subscriptions:
|
||||
if is_subscription_valid(sub):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def calculate_subscription_expiry(start_date: datetime, validity_type: str) -> datetime:
|
||||
"""
|
||||
@@ -1203,3 +1297,64 @@ def calculate_subscription_expiry(start_date: datetime, validity_type: str) -> d
|
||||
# 未知类型默认30天
|
||||
logger.warning(f"未知有效期类型: {validity_type}, 使用默认30天")
|
||||
return start_date + timedelta(days=30)
|
||||
|
||||
|
||||
def is_subscription_valid(subscription: dict) -> bool:
|
||||
"""
|
||||
检查订阅在当前时间是否有效
|
||||
|
||||
参数:
|
||||
subscription: 包含订阅信息的字典,包含以下字段:
|
||||
- validity_type: 有效期类型
|
||||
- valid_time_range: 有效时间段 (格式: "08:00-20:00")
|
||||
- valid_week_days: 有效星期 (格式: "1,3,5")
|
||||
- start_date: 订阅开始日期 (datetime 对象)
|
||||
- end_date: 订阅结束日期 (datetime 对象)
|
||||
"""
|
||||
# 设置时区(根据服务器实际时区调整)
|
||||
tz = ZoneInfo('Asia/Shanghai')
|
||||
now = datetime.now(tz)
|
||||
|
||||
# 1. 检查永久免费订阅
|
||||
if subscription['validity_type'] == 'free':
|
||||
return True
|
||||
|
||||
# 2. 检查时间间隔类型订阅
|
||||
if subscription['validity_type'] == 'free_interval':
|
||||
# 时间间隔类型不需要检查有效期范围
|
||||
pass
|
||||
else:
|
||||
# 3. 检查有效期是否在范围内
|
||||
if subscription['validity_type'] in ['1month', '1year', 'permanent']:
|
||||
start_date = subscription['start_date'].astimezone(tz)
|
||||
end_date = subscription['end_date'].astimezone(tz)
|
||||
|
||||
if not (start_date <= now <= end_date):
|
||||
return False
|
||||
|
||||
# 4. 检查星期限制
|
||||
if subscription.get('valid_week_days'):
|
||||
week_day = now.isoweekday() # 1=周一, 7=周日
|
||||
valid_days = [int(d) for d in str(subscription['valid_week_days']).split(',')]
|
||||
if week_day not in valid_days:
|
||||
return False
|
||||
|
||||
# 5. 检查时间范围限制
|
||||
if subscription.get('valid_time_range'):
|
||||
try:
|
||||
start_str, end_str = subscription['valid_time_range'].split('-')
|
||||
start_time = datetime.strptime(start_str, '%H:%M').time()
|
||||
end_time = datetime.strptime(end_str, '%H:%M').time()
|
||||
current_time = now.time()
|
||||
# 处理跨夜时段
|
||||
if end_time < start_time:
|
||||
if not (current_time >= start_time or current_time <= end_time):
|
||||
return False
|
||||
else:
|
||||
if not (start_time <= current_time <= end_time):
|
||||
return False
|
||||
except (ValueError, AttributeError):
|
||||
# 时间格式无效,跳过时间检查
|
||||
pass
|
||||
|
||||
return True
|
||||
Reference in New Issue
Block a user