feat: 优化日期时间处理,确保 ISO 字符串正确解析并转换为上海时区
This commit is contained in:
parent
5871defc4e
commit
8b98b5afb2
@ -34,6 +34,13 @@ class Conversation(Base):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
def format_utc_datetime(dt_value):
|
||||||
|
if dt_value is None:
|
||||||
|
return None
|
||||||
|
if dt_value.tzinfo is None:
|
||||||
|
dt_value = dt_value.replace(tzinfo=dt.UTC)
|
||||||
|
return utc_isoformat(dt_value)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"thread_id": self.thread_id,
|
"thread_id": self.thread_id,
|
||||||
@ -41,8 +48,8 @@ class Conversation(Base):
|
|||||||
"agent_id": self.agent_id,
|
"agent_id": self.agent_id,
|
||||||
"title": self.title,
|
"title": self.title,
|
||||||
"status": self.status,
|
"status": self.status,
|
||||||
"created_at": utc_isoformat(self.created_at) if self.created_at else None,
|
"created_at": format_utc_datetime(self.created_at),
|
||||||
"updated_at": utc_isoformat(self.updated_at) if self.updated_at else None,
|
"updated_at": format_utc_datetime(self.updated_at),
|
||||||
"metadata": self.extra_metadata or {},
|
"metadata": self.extra_metadata or {},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,13 +75,20 @@ class Message(Base):
|
|||||||
tool_calls = relationship("ToolCall", back_populates="message", cascade="all, delete-orphan")
|
tool_calls = relationship("ToolCall", back_populates="message", cascade="all, delete-orphan")
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
def format_utc_datetime(dt_value):
|
||||||
|
if dt_value is None:
|
||||||
|
return None
|
||||||
|
if dt_value.tzinfo is None:
|
||||||
|
dt_value = dt_value.replace(tzinfo=dt.UTC)
|
||||||
|
return utc_isoformat(dt_value)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"conversation_id": self.conversation_id,
|
"conversation_id": self.conversation_id,
|
||||||
"role": self.role,
|
"role": self.role,
|
||||||
"content": self.content,
|
"content": self.content,
|
||||||
"message_type": self.message_type,
|
"message_type": self.message_type,
|
||||||
"created_at": utc_isoformat(self.created_at) if self.created_at else None,
|
"created_at": format_utc_datetime(self.created_at),
|
||||||
"token_count": self.token_count,
|
"token_count": self.token_count,
|
||||||
"metadata": self.extra_metadata or {},
|
"metadata": self.extra_metadata or {},
|
||||||
"tool_calls": [tc.to_dict() for tc in self.tool_calls] if self.tool_calls else [],
|
"tool_calls": [tc.to_dict() for tc in self.tool_calls] if self.tool_calls else [],
|
||||||
@ -108,6 +122,13 @@ class ToolCall(Base):
|
|||||||
message = relationship("Message", back_populates="tool_calls")
|
message = relationship("Message", back_populates="tool_calls")
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
def format_utc_datetime(dt_value):
|
||||||
|
if dt_value is None:
|
||||||
|
return None
|
||||||
|
if dt_value.tzinfo is None:
|
||||||
|
dt_value = dt_value.replace(tzinfo=dt.UTC)
|
||||||
|
return utc_isoformat(dt_value)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"message_id": self.message_id,
|
"message_id": self.message_id,
|
||||||
@ -117,7 +138,7 @@ class ToolCall(Base):
|
|||||||
"tool_output": self.tool_output,
|
"tool_output": self.tool_output,
|
||||||
"status": self.status,
|
"status": self.status,
|
||||||
"error_message": self.error_message,
|
"error_message": self.error_message,
|
||||||
"created_at": utc_isoformat(self.created_at) if self.created_at else None,
|
"created_at": format_utc_datetime(self.created_at),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -141,6 +162,13 @@ class ConversationStats(Base):
|
|||||||
conversation = relationship("Conversation", back_populates="stats")
|
conversation = relationship("Conversation", back_populates="stats")
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
def format_utc_datetime(dt_value):
|
||||||
|
if dt_value is None:
|
||||||
|
return None
|
||||||
|
if dt_value.tzinfo is None:
|
||||||
|
dt_value = dt_value.replace(tzinfo=dt.UTC)
|
||||||
|
return utc_isoformat(dt_value)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"conversation_id": self.conversation_id,
|
"conversation_id": self.conversation_id,
|
||||||
@ -148,8 +176,8 @@ class ConversationStats(Base):
|
|||||||
"total_tokens": self.total_tokens,
|
"total_tokens": self.total_tokens,
|
||||||
"model_used": self.model_used,
|
"model_used": self.model_used,
|
||||||
"user_feedback": self.user_feedback or {},
|
"user_feedback": self.user_feedback or {},
|
||||||
"created_at": utc_isoformat(self.created_at) if self.created_at else None,
|
"created_at": format_utc_datetime(self.created_at),
|
||||||
"updated_at": utc_isoformat(self.updated_at) if self.updated_at else None,
|
"updated_at": format_utc_datetime(self.updated_at),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -181,6 +209,15 @@ class User(Base):
|
|||||||
operation_logs = relationship("OperationLog", back_populates="user", cascade="all, delete-orphan")
|
operation_logs = relationship("OperationLog", back_populates="user", cascade="all, delete-orphan")
|
||||||
|
|
||||||
def to_dict(self, include_password=False):
|
def to_dict(self, include_password=False):
|
||||||
|
# SQLite 存储 naive datetime,需要标记为 UTC 后再转换
|
||||||
|
def format_utc_datetime(dt_value):
|
||||||
|
if dt_value is None:
|
||||||
|
return None
|
||||||
|
# 如果是 naive datetime,假设它是 UTC(因为代码中使用 utc_now() 存储)
|
||||||
|
if dt_value.tzinfo is None:
|
||||||
|
dt_value = dt_value.replace(tzinfo=dt.UTC)
|
||||||
|
return utc_isoformat(dt_value)
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"username": self.username,
|
"username": self.username,
|
||||||
@ -188,13 +225,13 @@ class User(Base):
|
|||||||
"phone_number": self.phone_number,
|
"phone_number": self.phone_number,
|
||||||
"avatar": self.avatar,
|
"avatar": self.avatar,
|
||||||
"role": self.role,
|
"role": self.role,
|
||||||
"created_at": utc_isoformat(self.created_at) if self.created_at else None,
|
"created_at": format_utc_datetime(self.created_at),
|
||||||
"last_login": utc_isoformat(self.last_login) if self.last_login else None,
|
"last_login": format_utc_datetime(self.last_login),
|
||||||
"login_failed_count": self.login_failed_count,
|
"login_failed_count": self.login_failed_count,
|
||||||
"last_failed_login": utc_isoformat(self.last_failed_login) if self.last_failed_login else None,
|
"last_failed_login": format_utc_datetime(self.last_failed_login),
|
||||||
"login_locked_until": utc_isoformat(self.login_locked_until) if self.login_locked_until else None,
|
"login_locked_until": format_utc_datetime(self.login_locked_until),
|
||||||
"is_deleted": self.is_deleted,
|
"is_deleted": self.is_deleted,
|
||||||
"deleted_at": utc_isoformat(self.deleted_at) if self.deleted_at else None,
|
"deleted_at": format_utc_datetime(self.deleted_at),
|
||||||
}
|
}
|
||||||
if include_password:
|
if include_password:
|
||||||
result["password_hash"] = self.password_hash
|
result["password_hash"] = self.password_hash
|
||||||
@ -259,13 +296,20 @@ class OperationLog(Base):
|
|||||||
user = relationship("User", back_populates="operation_logs")
|
user = relationship("User", back_populates="operation_logs")
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
def format_utc_datetime(dt_value):
|
||||||
|
if dt_value is None:
|
||||||
|
return None
|
||||||
|
if dt_value.tzinfo is None:
|
||||||
|
dt_value = dt_value.replace(tzinfo=dt.UTC)
|
||||||
|
return utc_isoformat(dt_value)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"user_id": self.user_id,
|
"user_id": self.user_id,
|
||||||
"operation": self.operation,
|
"operation": self.operation,
|
||||||
"details": self.details,
|
"details": self.details,
|
||||||
"ip_address": self.ip_address,
|
"ip_address": self.ip_address,
|
||||||
"timestamp": utc_isoformat(self.timestamp) if self.timestamp else None,
|
"timestamp": format_utc_datetime(self.timestamp),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -287,11 +331,18 @@ class MessageFeedback(Base):
|
|||||||
message = relationship("Message", backref="feedbacks")
|
message = relationship("Message", backref="feedbacks")
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
def format_utc_datetime(dt_value):
|
||||||
|
if dt_value is None:
|
||||||
|
return None
|
||||||
|
if dt_value.tzinfo is None:
|
||||||
|
dt_value = dt_value.replace(tzinfo=dt.UTC)
|
||||||
|
return utc_isoformat(dt_value)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"message_id": self.message_id,
|
"message_id": self.message_id,
|
||||||
"user_id": self.user_id,
|
"user_id": self.user_id,
|
||||||
"rating": self.rating,
|
"rating": self.rating,
|
||||||
"reason": self.reason,
|
"reason": self.reason,
|
||||||
"created_at": utc_isoformat(self.created_at) if self.created_at else None,
|
"created_at": format_utc_datetime(self.created_at),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,10 +41,12 @@ const coerceDayjs = (value) => {
|
|||||||
return dayjs(numeric).tz(DEFAULT_TZ)
|
return dayjs(numeric).tz(DEFAULT_TZ)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解析 ISO 字符串(dayjs 会自动识别时区信息,如 Z 后缀表示 UTC)
|
||||||
const parsed = dayjs(stringValue)
|
const parsed = dayjs(stringValue)
|
||||||
if (!parsed.isValid()) {
|
if (!parsed.isValid()) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
// 转换为上海时区
|
||||||
return parsed.tz(DEFAULT_TZ)
|
return parsed.tz(DEFAULT_TZ)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user