fix:问答时间和样式修正
This commit is contained in:
parent
f6aa6d9a97
commit
8fb76a9cb6
|
|
@ -0,0 +1,22 @@
|
|||
from datetime import datetime, timezone
|
||||
from typing import Annotated
|
||||
|
||||
from pydantic import PlainSerializer
|
||||
|
||||
|
||||
def _to_utc_iso(v: datetime | None) -> str | None:
|
||||
if v is None:
|
||||
return None
|
||||
if v.tzinfo is None:
|
||||
v = v.replace(tzinfo=timezone.utc)
|
||||
else:
|
||||
v = v.astimezone(timezone.utc)
|
||||
return v.isoformat().replace("+00:00", "Z")
|
||||
|
||||
|
||||
# 数据库里存的是 datetime.utcnow() 产出的 naive UTC。裸 ISO 字符串
|
||||
# 会被 JS new Date(...) 当本地时间解析, 少 8 小时。统一序列化为带 Z 的
|
||||
# UTC ISO, 前端/小程序拿到后 new Date(...) 会正确转成本地时区。
|
||||
UtcDatetime = Annotated[
|
||||
datetime, PlainSerializer(_to_utc_iso, return_type=str, when_used="json")
|
||||
]
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from ._types import UtcDatetime
|
||||
|
||||
|
||||
class AuditLogResponse(BaseModel):
|
||||
id: int
|
||||
|
|
@ -10,7 +10,7 @@ class AuditLogResponse(BaseModel):
|
|||
target_type: str | None
|
||||
target_id: str | None
|
||||
detail_json: dict | None
|
||||
created_at: datetime
|
||||
created_at: UtcDatetime
|
||||
|
||||
|
||||
class StatsOverviewResponse(BaseModel):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from ._types import UtcDatetime
|
||||
|
||||
|
||||
class ConversationCreate(BaseModel):
|
||||
title: str = "新会话"
|
||||
|
|
@ -10,8 +10,8 @@ class ConversationCreate(BaseModel):
|
|||
class ConversationResponse(BaseModel):
|
||||
id: int
|
||||
title: str
|
||||
created_at: datetime
|
||||
last_message_at: datetime | None
|
||||
created_at: UtcDatetime
|
||||
last_message_at: UtcDatetime | None
|
||||
|
||||
|
||||
class ChatStreamRequest(BaseModel):
|
||||
|
|
@ -42,7 +42,7 @@ class MessageResponse(BaseModel):
|
|||
status: str
|
||||
token_usage: int
|
||||
pu_usage: int
|
||||
created_at: datetime
|
||||
created_at: UtcDatetime
|
||||
references: list[ReferenceResponse]
|
||||
attachments: list[AttachmentResponse] = Field(default_factory=list)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from ._types import UtcDatetime
|
||||
|
||||
|
||||
class DocumentCreate(BaseModel):
|
||||
title: str = Field(min_length=1, max_length=255)
|
||||
|
|
@ -31,4 +31,4 @@ class DocumentResponse(BaseModel):
|
|||
status: str
|
||||
owner_dept: str | None
|
||||
tags: list[str]
|
||||
created_at: datetime
|
||||
created_at: UtcDatetime
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from ._types import UtcDatetime
|
||||
|
||||
|
||||
class UserCreate(BaseModel):
|
||||
phone: str = Field(min_length=6, max_length=32)
|
||||
|
|
@ -34,7 +34,7 @@ class UserResponse(BaseModel):
|
|||
status: str
|
||||
role_codes: list[str]
|
||||
is_superuser: bool
|
||||
created_at: datetime | None = None
|
||||
created_at: UtcDatetime | None = None
|
||||
|
||||
|
||||
class BulkImportResult(BaseModel):
|
||||
|
|
|
|||
|
|
@ -835,16 +835,6 @@ button {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 共享文档 (ref.source_url 存在) 时, 标题变成蓝色外链, 悬停加下划线 */
|
||||
.bubble-reference-item summary .ref-title-link {
|
||||
color: #1a73e8;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.bubble-reference-item summary .ref-title-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 展开区域内的链接地址行, 显示完整 URL, 蓝色字, 可换行 */
|
||||
.bubble-reference-item .ref-url-line {
|
||||
display: block;
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ watch(messages, scrollToEnd, { deep: true })
|
|||
@click="onBubbleClick"
|
||||
/>
|
||||
<div v-if="msg.references && msg.references.length" class="bubble-references">
|
||||
<div class="bubble-references-title">参考知识片段</div>
|
||||
<div class="bubble-references-title">参考来源</div>
|
||||
<div class="bubble-references-body">
|
||||
<details
|
||||
v-for="(ref, rIdx) in msg.references"
|
||||
|
|
@ -311,15 +311,7 @@ watch(messages, scrollToEnd, { deep: true })
|
|||
>
|
||||
<summary>
|
||||
<span class="ref-icon">📄</span>
|
||||
<a
|
||||
v-if="ref.source_url"
|
||||
:href="ref.source_url"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="ref-title ref-title-link"
|
||||
@click.stop
|
||||
>{{ rIdx + 1 }}.{{ ref.source_title || '未知来源' }}</a>
|
||||
<span v-else class="ref-title">{{ rIdx + 1 }}.{{ ref.source_title || '未知来源' }}</span>
|
||||
<span class="ref-title">{{ rIdx + 1 }}.{{ ref.source_title || '未知来源' }}</span>
|
||||
<small v-if="ref.page_no" class="ref-page">第 {{ ref.page_no }} 页</small>
|
||||
<span class="ref-arrow">›</span>
|
||||
</summary>
|
||||
|
|
|
|||
Loading…
Reference in New Issue