diff --git a/src/chat/message_receive/storage.py b/src/chat/message_receive/storage.py index e81913549..d0041cd51 100644 --- a/src/chat/message_receive/storage.py +++ b/src/chat/message_receive/storage.py @@ -33,14 +33,13 @@ class MessageStorage: chat_info_dict = chat_stream.to_dict() user_info_dict = message.message_info.user_info.to_dict() - # Ensure message_id is an int if the model field is IntegerField - try: - msg_id = int(message.message_info.message_id) - except ValueError: - logger.error( - f"Message ID {message.message_info.message_id} is not a valid integer. Storing as 0 or consider changing model field type." - ) - msg_id = 0 # Or handle as appropriate, e.g. skip storing, or change model field to TextField + # message_id 现在是 TextField,直接使用字符串值 + msg_id = message.message_info.message_id + + # 安全地获取 group_info, 如果为 None 则视为空字典 + group_info_from_chat = chat_info_dict.get("group_info") or {} + # 安全地获取 user_info, 如果为 None 则视为空字典 (以防万一) + user_info_from_chat = chat_info_dict.get("user_info") or {} Messages.create( message_id=msg_id, @@ -49,13 +48,13 @@ class MessageStorage: # Flattened chat_info chat_info_stream_id=chat_info_dict.get("stream_id"), chat_info_platform=chat_info_dict.get("platform"), - chat_info_user_platform=chat_info_dict.get("user_info", {}).get("platform"), - chat_info_user_id=chat_info_dict.get("user_info", {}).get("user_id"), - chat_info_user_nickname=chat_info_dict.get("user_info", {}).get("user_nickname"), - chat_info_user_cardname=chat_info_dict.get("user_info", {}).get("user_cardname"), - chat_info_group_platform=chat_info_dict.get("group_info", {}).get("platform"), - chat_info_group_id=chat_info_dict.get("group_info", {}).get("group_id"), - chat_info_group_name=chat_info_dict.get("group_info", {}).get("group_name"), + chat_info_user_platform=user_info_from_chat.get("platform"), + chat_info_user_id=user_info_from_chat.get("user_id"), + chat_info_user_nickname=user_info_from_chat.get("user_nickname"), + chat_info_user_cardname=user_info_from_chat.get("user_cardname"), + chat_info_group_platform=group_info_from_chat.get("platform"), + chat_info_group_id=group_info_from_chat.get("group_id"), + chat_info_group_name=group_info_from_chat.get("group_name"), chat_info_create_time=float(chat_info_dict.get("create_time", 0.0)), chat_info_last_active_time=float(chat_info_dict.get("last_active_time", 0.0)), # Flattened user_info (message sender) diff --git a/src/chat/person_info/person_info.py b/src/chat/person_info/person_info.py index 1ad2f358f..9d0841c0e 100644 --- a/src/chat/person_info/person_info.py +++ b/src/chat/person_info/person_info.py @@ -39,13 +39,13 @@ logger = get_logger("person_info") person_info_default = { "person_id": None, - "person_name": None, + "person_name": None, # 模型中已设为 null=True,此默认值OK "name_reason": None, - "platform": None, - "user_id": None, - "nickname": None, + "platform": "unknown", # 提供非None的默认值 + "user_id": "unknown", # 提供非None的默认值 + "nickname": "Unknown", # 提供非None的默认值 "relationship_value": 0, - "konw_time": 0, + "know_time": 0, # 修正拼写:konw_time -> know_time "msg_interval": 2000, "msg_interval_list": [], # 将作为 JSON 字符串存储在 Peewee 的 TextField "user_cardname": None, # 注意:此字段不在 PersonInfo Peewee 模型中 @@ -561,7 +561,7 @@ class PersonInfoManager: "platform": platform, "user_id": str(user_id), "nickname": nickname, - "konw_time": int(datetime.datetime.now().timestamp()), + "know_time": int(datetime.datetime.now().timestamp()), # 修正拼写:konw_time -> know_time } model_fields = PersonInfo._meta.fields.keys() filtered_initial_data = {k: v for k, v in initial_data.items() if v is not None and k in model_fields} diff --git a/src/common/database/database_model.py b/src/common/database/database_model.py index d77184b74..35f464b5f 100644 --- a/src/common/database/database_model.py +++ b/src/common/database/database_model.py @@ -122,7 +122,7 @@ class Messages(BaseModel): 用于存储消息数据的模型。 """ - message_id = IntegerField(index=True) # 消息 ID + message_id = TextField(index=True) # 消息 ID (更改自 IntegerField) time = DoubleField() # 消息时间戳 chat_id = TextField(index=True) # 对应的 ChatStreams stream_id @@ -208,7 +208,7 @@ class PersonInfo(BaseModel): """ person_id = TextField(unique=True, index=True) # 个人唯一ID - person_name = TextField() # 个人名称 + person_name = TextField(null=True) # 个人名称 (允许为空) name_reason = TextField(null=True) # 名称设定的原因 platform = TextField() # 平台 user_id = TextField(index=True) # 用户ID diff --git a/src/common/message_repository.py b/src/common/message_repository.py index 5bf77c1a9..b1fb5dc46 100644 --- a/src/common/message_repository.py +++ b/src/common/message_repository.py @@ -24,7 +24,7 @@ def find_messages( 根据提供的过滤器、排序和限制条件查找消息。 Args: - message_filter: 查询过滤器字典,键为模型字段名,值为期望值。 + message_filter: 查询过滤器字典,键为模型字段名,值为期望值或包含操作符的字典 (例如 {'$gt': value}). sort: 排序条件列表,例如 [('time', 1)] (1 for asc, -1 for desc)。仅在 limit 为 0 时生效。 limit: 返回的最大文档数,0表示不限制。 limit_mode: 当 limit > 0 时生效。 'earliest' 表示获取最早的记录, 'latest' 表示获取最新的记录(结果仍按时间正序排列)。默认为 'latest'。 @@ -40,11 +40,34 @@ def find_messages( conditions = [] for key, value in message_filter.items(): if hasattr(Messages, key): - conditions.append(getattr(Messages, key) == value) + field = getattr(Messages, key) + if isinstance(value, dict): + # 处理 MongoDB 风格的操作符 + for op, op_value in value.items(): + if op == "$gt": + conditions.append(field > op_value) + elif op == "$lt": + conditions.append(field < op_value) + elif op == "$gte": + conditions.append(field >= op_value) + elif op == "$lte": + conditions.append(field <= op_value) + elif op == "$ne": + conditions.append(field != op_value) + elif op == "$in": + conditions.append(field.in_(op_value)) + elif op == "$nin": + conditions.append(field.not_in(op_value)) + else: + logger.warning( + f"过滤器中遇到未知操作符 '{op}' (字段: '{key}')。将跳过此操作符。" + ) + else: + # 直接相等比较 + conditions.append(field == value) else: logger.warning(f"过滤器键 '{key}' 在 Messages 模型中未找到。将跳过此条件。") if conditions: - # 使用 *conditions 将所有条件以 AND 连接 query = query.where(*conditions) if limit > 0: @@ -92,7 +115,7 @@ def count_messages(message_filter: dict[str, Any]) -> int: 根据提供的过滤器计算消息数量。 Args: - message_filter: 查询过滤器字典,键为模型字段名,值为期望值。 + message_filter: 查询过滤器字典,键为模型字段名,值为期望值或包含操作符的字典 (例如 {'$gt': value}). Returns: 符合条件的消息数量,如果出错则返回 0。 @@ -105,7 +128,31 @@ def count_messages(message_filter: dict[str, Any]) -> int: conditions = [] for key, value in message_filter.items(): if hasattr(Messages, key): - conditions.append(getattr(Messages, key) == value) + field = getattr(Messages, key) + if isinstance(value, dict): + # 处理 MongoDB 风格的操作符 + for op, op_value in value.items(): + if op == "$gt": + conditions.append(field > op_value) + elif op == "$lt": + conditions.append(field < op_value) + elif op == "$gte": + conditions.append(field >= op_value) + elif op == "$lte": + conditions.append(field <= op_value) + elif op == "$ne": + conditions.append(field != op_value) + elif op == "$in": + conditions.append(field.in_(op_value)) + elif op == "$nin": + conditions.append(field.not_in(op_value)) + else: + logger.warning( + f"计数时,过滤器中遇到未知操作符 '{op}' (字段: '{key}')。将跳过此操作符。" + ) + else: + # 直接相等比较 + conditions.append(field == value) else: logger.warning(f"计数时,过滤器键 '{key}' 在 Messages 模型中未找到。将跳过此条件。") if conditions: