Compare commits
No commits in common. "b9fa4109f479ace6437a4a87dd6a49eac9526c1f" and "7f6a992830604a43946173a1d6573aa63f835d55" have entirely different histories.
b9fa4109f4
...
7f6a992830
|
|
@ -1,6 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
数据表模型
|
表模型
|
||||||
"""
|
"""
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from random import choices
|
from random import choices
|
||||||
|
|
@ -9,31 +9,30 @@ from pydantic_ai._uuid import uuid7
|
||||||
from sqlmodel import Field, JSON, SQLModel
|
from sqlmodel import Field, JSON, SQLModel
|
||||||
|
|
||||||
|
|
||||||
class CaptchaTable(SQLModel, table=True):
|
# 验证码表
|
||||||
"""
|
class Captchas(SQLModel, table=True):
|
||||||
验证码表
|
|
||||||
"""
|
|
||||||
|
|
||||||
email: str = Field(..., primary_key=True, description="邮箱")
|
email: str = Field(..., primary_key=True, description="邮箱")
|
||||||
captcha: str = Field(
|
captcha: str = Field(
|
||||||
default_factory=lambda: "".join(choices("0123456789", k=6)),
|
default_factory=lambda: "".join(choices("0123456789", k=6)),
|
||||||
primary_key=True,
|
|
||||||
description="验证码",
|
description="验证码",
|
||||||
)
|
)
|
||||||
is_verified: bool = Field(
|
is_valid: bool = Field(
|
||||||
default=False,
|
default=True, index=True, description="是否有效,True 表示有效,False 表示无效"
|
||||||
|
)
|
||||||
|
is_unused: bool = Field(
|
||||||
|
default=True,
|
||||||
index=True,
|
index=True,
|
||||||
description="已核验:True 表示已核验,False 表示未核验",
|
description="是否未使用,True 表示未使用,False 表示已使用。",
|
||||||
)
|
)
|
||||||
expired_at: datetime = Field(
|
expired_at: datetime = Field(
|
||||||
default_factory=lambda: datetime.now() + timedelta(minutes=30),
|
default_factory=lambda: datetime.now() + timedelta(minutes=30),
|
||||||
primary_key=True,
|
primary_key=True,
|
||||||
description="失效时间",
|
description="过期时间",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# 用户表
|
# 用户表
|
||||||
class UserTable(SQLModel, table=True):
|
class Users(SQLModel, table=True):
|
||||||
id: str = Field(
|
id: str = Field(
|
||||||
default_factory=lambda: str(uuid7()),
|
default_factory=lambda: str(uuid7()),
|
||||||
primary_key=True,
|
primary_key=True,
|
||||||
|
|
@ -43,7 +42,7 @@ class UserTable(SQLModel, table=True):
|
||||||
|
|
||||||
|
|
||||||
# 会话表
|
# 会话表
|
||||||
class ConversationTable(SQLModel, table=True):
|
class Conversations(SQLModel, table=True):
|
||||||
id: str = Field(
|
id: str = Field(
|
||||||
default_factory=lambda: str(uuid7()),
|
default_factory=lambda: str(uuid7()),
|
||||||
primary_key=True,
|
primary_key=True,
|
||||||
|
|
@ -51,8 +50,8 @@ class ConversationTable(SQLModel, table=True):
|
||||||
)
|
)
|
||||||
user_id: str = Field(..., index=True, description="用户唯一标识")
|
user_id: str = Field(..., index=True, description="用户唯一标识")
|
||||||
description: str = Field(..., description="会话描述")
|
description: str = Field(..., description="会话描述")
|
||||||
|
is_deleted: bool = Field(default=False, index=True, description="是否删除")
|
||||||
created_at: datetime = Field(default_factory=datetime.now, description="创建时间")
|
created_at: datetime = Field(default_factory=datetime.now, description="创建时间")
|
||||||
is_deleted: bool = Field(default=False, index=True, description="已删除:True 表示已删除,False 表示未删除")
|
|
||||||
|
|
||||||
|
|
||||||
# 思考节点表(仅定义)
|
# 思考节点表(仅定义)
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,18 @@ import reflex as rx
|
||||||
|
|
||||||
from application.models import Conversation, Dialog, ThoughtNode
|
from application.models import Conversation, Dialog, ThoughtNode
|
||||||
from application.states import ConversationState, AuthState
|
from application.states import ConversationState, AuthState
|
||||||
from reflex_base.vars.object import ObjectVar
|
|
||||||
|
|
||||||
|
|
||||||
def render_conversation_history_item(
|
def render_conversation_history_item(
|
||||||
item: rx.Var[tuple],
|
item: rx.Var[tuple[str, Conversation]],
|
||||||
) -> rx.Component:
|
) -> rx.Component:
|
||||||
"""
|
"""
|
||||||
渲染会话历史条目
|
渲染会话历史条目
|
||||||
:param item: 会话历史条目
|
:param item: 会话历史条目
|
||||||
:return: Component
|
:return: Component
|
||||||
"""
|
"""
|
||||||
conversation_id: rx.Var[str] = item[0]
|
# 解构会话唯一标识和会话实例
|
||||||
conversation: ObjectVar[Conversation] = item[1].to(Conversation)
|
conversation_id, conversation = item[0], item[1] # type: ignore
|
||||||
|
|
||||||
# 会话激活状态
|
# 会话激活状态
|
||||||
is_conversation_actived = conversation_id == ConversationState.conversation_id
|
is_conversation_actived = conversation_id == ConversationState.conversation_id
|
||||||
|
|
@ -45,10 +44,7 @@ def render_conversation_history_item(
|
||||||
rx.popover.trigger(
|
rx.popover.trigger(
|
||||||
rx.box(
|
rx.box(
|
||||||
rx.icon(
|
rx.icon(
|
||||||
"ellipsis",
|
"ellipsis", size=14, color="var(--prismui-color-2)"
|
||||||
width="14px",
|
|
||||||
height="14px",
|
|
||||||
color="var(--prismui-color-2)",
|
|
||||||
),
|
),
|
||||||
cursor="pointer",
|
cursor="pointer",
|
||||||
)
|
)
|
||||||
|
|
@ -119,14 +115,6 @@ def render_conversation_history_item(
|
||||||
margin_bottom="8px",
|
margin_bottom="8px",
|
||||||
cursor="pointer",
|
cursor="pointer",
|
||||||
),
|
),
|
||||||
rx.hstack(
|
|
||||||
rx.spacer(),
|
|
||||||
# 创建时间
|
|
||||||
rx.text(
|
|
||||||
"1",
|
|
||||||
margin_bottom="8px",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
width="100%",
|
width="100%",
|
||||||
padding="16px",
|
padding="16px",
|
||||||
|
|
@ -136,7 +124,7 @@ def render_conversation_history_item(
|
||||||
"linear-gradient(to right, #f3efff, #f3efff33, #e2f1fd33, #e2f1fd)",
|
"linear-gradient(to right, #f3efff, #f3efff33, #e2f1fd33, #e2f1fd)",
|
||||||
"var(--prismui-background-color-1)",
|
"var(--prismui-background-color-1)",
|
||||||
),
|
),
|
||||||
border_radius="var(--prismui-border-radius-3)",
|
border_radius="var(--prismui-border-radius-2)",
|
||||||
box_shadow=rx.cond(is_conversation_actived, "2px 2px 8px #e9e9e9", "none"),
|
box_shadow=rx.cond(is_conversation_actived, "2px 2px 8px #e9e9e9", "none"),
|
||||||
style={
|
style={
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
|
|
@ -154,12 +142,10 @@ def render_conversation_history_item(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def conversation_history_collapse(
|
def render_collapse(is_expanded: bool) -> rx.Component:
|
||||||
is_conversation_history_shown: bool,
|
|
||||||
) -> rx.Component:
|
|
||||||
"""
|
"""
|
||||||
会话历史折叠面板
|
渲染折叠面板
|
||||||
:param is_conversation_history_shown: 会话历史展示状态
|
:param is_expanded: 折叠面板展开状态
|
||||||
:return: Component
|
:return: Component
|
||||||
"""
|
"""
|
||||||
return rx.box(
|
return rx.box(
|
||||||
|
|
@ -175,22 +161,22 @@ def conversation_history_collapse(
|
||||||
align_items="center",
|
align_items="center",
|
||||||
justify_content="space-between",
|
justify_content="space-between",
|
||||||
),
|
),
|
||||||
# 渲染会话历史列表
|
# 渲染列表
|
||||||
rx.auto_scroll(
|
rx.auto_scroll(
|
||||||
rx.foreach(
|
rx.foreach(
|
||||||
ConversationState.conversation_history,
|
ConversationState.conversation_history,
|
||||||
render_conversation_history_item,
|
render_conversation_history_item,
|
||||||
),
|
),
|
||||||
flex="1",
|
flex="1",
|
||||||
align_items="stretch",
|
|
||||||
width="100%",
|
|
||||||
margin_top="8px",
|
margin_top="8px",
|
||||||
|
width="100%",
|
||||||
|
align_items="stretch",
|
||||||
|
overflow="auto",
|
||||||
style={
|
style={
|
||||||
"&::-webkit-scrollbar": {
|
"&::-webkit-scrollbar": {
|
||||||
"display": "none",
|
"display": "none",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
overflow="auto",
|
|
||||||
),
|
),
|
||||||
display="flex",
|
display="flex",
|
||||||
flex_direction="column",
|
flex_direction="column",
|
||||||
|
|
@ -199,13 +185,14 @@ def conversation_history_collapse(
|
||||||
background_color="#f9f9f9cc",
|
background_color="#f9f9f9cc",
|
||||||
backdrop_filter="blur(50px)",
|
backdrop_filter="blur(50px)",
|
||||||
gap="12px",
|
gap="12px",
|
||||||
|
color="var(--prismui-color-text)",
|
||||||
),
|
),
|
||||||
width=rx.cond(is_conversation_history_shown, "25%", "0px"),
|
width=rx.cond(is_expanded, "25%", "0px"),
|
||||||
min_width=rx.cond(is_conversation_history_shown, "240px", "0px"),
|
min_width=rx.cond(is_expanded, "240px", "0px"),
|
||||||
max_width=rx.cond(is_conversation_history_shown, "380px", "0px"),
|
max_width=rx.cond(is_expanded, "380px", "0px"),
|
||||||
height="100%",
|
height="100%",
|
||||||
transition="all 0.3s ease-in-out",
|
|
||||||
overflow="hidden",
|
overflow="hidden",
|
||||||
|
transition="all 0.3s ease-in-out",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -370,7 +357,7 @@ def render_dialog_history_item(dialog_id: str, dialog: Dialog) -> rx.Component:
|
||||||
max_width="600px",
|
max_width="600px",
|
||||||
padding="12px 16px",
|
padding="12px 16px",
|
||||||
background_color="var(--prismui-background-color-3)",
|
background_color="var(--prismui-background-color-3)",
|
||||||
border_radius="var(--prismui-border-radius-3)",
|
border_radius="var(--prismui-border-radius-2)",
|
||||||
word_wrap="break-word",
|
word_wrap="break-word",
|
||||||
word_break="break-all",
|
word_break="break-all",
|
||||||
white_space="pre-line",
|
white_space="pre-line",
|
||||||
|
|
@ -725,9 +712,9 @@ def render_input() -> rx.Component:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def workbench() -> rx.Component:
|
def render_workplace() -> rx.Component:
|
||||||
"""
|
"""
|
||||||
工作台
|
渲染会话工作区
|
||||||
:return: Component
|
:return: Component
|
||||||
"""
|
"""
|
||||||
return rx.box(
|
return rx.box(
|
||||||
|
|
@ -755,16 +742,16 @@ def workbench() -> rx.Component:
|
||||||
|
|
||||||
|
|
||||||
def render_conversation_history_collapse_button(
|
def render_conversation_history_collapse_button(
|
||||||
is_conversation_history_shown: bool,
|
is_expanded: bool,
|
||||||
) -> rx.Component:
|
) -> rx.Component:
|
||||||
"""
|
"""
|
||||||
渲染会话历史折叠面板按钮
|
渲染会话历史折叠面板的按钮
|
||||||
:param is_conversation_history_shown: 会话历史展示状态
|
:param is_expanded: 会话历史折叠面板展开状态
|
||||||
:return: Component
|
:return: Component
|
||||||
"""
|
"""
|
||||||
return rx.button(
|
return rx.button(
|
||||||
rx.icon(
|
rx.icon(
|
||||||
rx.cond(is_conversation_history_shown, "chevron-left", "chevron-right"),
|
rx.cond(is_expanded, "chevron-left", "chevron-right"),
|
||||||
stroke_width=1,
|
stroke_width=1,
|
||||||
width="16px",
|
width="16px",
|
||||||
height="16px",
|
height="16px",
|
||||||
|
|
@ -772,18 +759,12 @@ def render_conversation_history_collapse_button(
|
||||||
),
|
),
|
||||||
position="absolute",
|
position="absolute",
|
||||||
top="calc(50% - 20px)",
|
top="calc(50% - 20px)",
|
||||||
left=rx.cond(
|
left=rx.cond(is_expanded, "calc(clamp(240px, 25%, 380px) - 8px)", "0"),
|
||||||
is_conversation_history_shown, "calc(clamp(240px, 25%, 380px) - 8px)", "0"
|
|
||||||
),
|
|
||||||
z_index=99,
|
z_index=99,
|
||||||
width="16px",
|
width="16px",
|
||||||
height="40px",
|
height="40px",
|
||||||
background_color="var(--prismui-background-color-1)",
|
background_color="var(--prismui-background-color-1)",
|
||||||
border_radius=rx.cond(
|
border_radius=rx.cond(is_expanded, "6px", "0 6px 6px 0"),
|
||||||
is_conversation_history_shown,
|
|
||||||
"var(--prismui-border-radius-2)",
|
|
||||||
"0 var(--prismui-border-radius-2)",
|
|
||||||
),
|
|
||||||
box_shadow="var(--prismui-box-shadow-4)",
|
box_shadow="var(--prismui-box-shadow-4)",
|
||||||
transition="all 0.3s ease-in-out",
|
transition="all 0.3s ease-in-out",
|
||||||
cursor="pointer",
|
cursor="pointer",
|
||||||
|
|
@ -801,17 +782,10 @@ def render_conversation() -> rx.Component:
|
||||||
|
|
||||||
return rx.box(
|
return rx.box(
|
||||||
rx.hstack(
|
rx.hstack(
|
||||||
<<<<<<< HEAD
|
|
||||||
# 会话历史折叠面板
|
|
||||||
conversation_history_collapse(is_conversation_history_shown),
|
|
||||||
# 工作台
|
|
||||||
workbench(),
|
|
||||||
=======
|
|
||||||
# 渲染折叠面板
|
# 渲染折叠面板
|
||||||
render_collapse(is_conversation_history_shown),
|
render_collapse(is_conversation_history_shown),
|
||||||
# 渲染工作区
|
# 渲染工作区
|
||||||
render_workplace(),
|
render_workplace(),
|
||||||
>>>>>>> 7f6a992830604a43946173a1d6573aa63f835d55
|
|
||||||
position="relative",
|
position="relative",
|
||||||
display="flex",
|
display="flex",
|
||||||
flex="1",
|
flex="1",
|
||||||
|
|
@ -820,12 +794,12 @@ def render_conversation() -> rx.Component:
|
||||||
overflow="hidden",
|
overflow="hidden",
|
||||||
transition="all 0.3s ease-in-out",
|
transition="all 0.3s ease-in-out",
|
||||||
),
|
),
|
||||||
# 渲染会话历史折叠面板按钮
|
# 渲染对话历史折叠面板打开/关闭按钮
|
||||||
render_conversation_history_collapse_button(is_conversation_history_shown),
|
render_conversation_history_collapse_button(is_conversation_history_shown),
|
||||||
position="relative",
|
position="relative",
|
||||||
width="100%",
|
width="100%",
|
||||||
height="100%",
|
height="100%",
|
||||||
border_radius="var(--prismui-border-radius-4)",
|
border_radius="var(--prismui-border-radius-3)",
|
||||||
overflow="hidden",
|
overflow="hidden",
|
||||||
# 挂载事件:同步用户唯一标识
|
# 挂载事件:同步用户唯一标识
|
||||||
on_mount=AuthState.sync_user_id,
|
on_mount=AuthState.sync_user_id,
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ def render_nav_button(
|
||||||
"var(--prismui-background-color-1)",
|
"var(--prismui-background-color-1)",
|
||||||
"transparent",
|
"transparent",
|
||||||
),
|
),
|
||||||
border_radius="var(--prismui-border-radius-3)",
|
border_radius="var(--prismui-border-radius-2)",
|
||||||
box_shadow=rx.cond(
|
box_shadow=rx.cond(
|
||||||
is_nav_button_actived, "var(--prismui-box-shadow-2)", "none"
|
is_nav_button_actived, "var(--prismui-box-shadow-2)", "none"
|
||||||
),
|
),
|
||||||
|
|
@ -88,7 +88,7 @@ def render_settings_button():
|
||||||
align_items="center",
|
align_items="center",
|
||||||
width="36px",
|
width="36px",
|
||||||
height="36px",
|
height="36px",
|
||||||
border_radius="var(--prismui-border-radius-3)",
|
border_radius="var(--prismui-border-radius-2)",
|
||||||
style={
|
style={
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
"background": "var(--prismui-background-color-5)",
|
"background": "var(--prismui-background-color-5)",
|
||||||
|
|
@ -120,7 +120,7 @@ def render_settings_button():
|
||||||
border_radius="var(--prismui-border-radius-1)",
|
border_radius="var(--prismui-border-radius-1)",
|
||||||
style={
|
style={
|
||||||
"_hover": {
|
"_hover": {
|
||||||
"background_color": "var(--prismui-background-color-6)",
|
"background_color": "var(--prismui-color-7, #f2f2f3)",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
# 点击事件:退出登录
|
# 点击事件:退出登录
|
||||||
|
|
@ -133,7 +133,6 @@ def render_settings_button():
|
||||||
position="relative",
|
position="relative",
|
||||||
align="center",
|
align="center",
|
||||||
padding="4px 12px",
|
padding="4px 12px",
|
||||||
border_radius="var(--prismui-border-radius-1)",
|
|
||||||
box_shadow="var(--prismui-box-shadow-3)",
|
box_shadow="var(--prismui-box-shadow-3)",
|
||||||
font_family="var(--prismui-font-family)",
|
font_family="var(--prismui-font-family)",
|
||||||
overflow="visible",
|
overflow="visible",
|
||||||
|
|
@ -236,7 +235,7 @@ def render_login_window() -> rx.Component:
|
||||||
height="45px",
|
height="45px",
|
||||||
margin_bottom="24px",
|
margin_bottom="24px",
|
||||||
padding="4px",
|
padding="4px",
|
||||||
border_radius="var(--prismui-border-radius-4)",
|
border_radius="var(--prismui-border-radius-3)",
|
||||||
line_height="16px",
|
line_height="16px",
|
||||||
# 值变化事件:设置邮箱
|
# 值变化事件:设置邮箱
|
||||||
on_change=AuthState.set_email,
|
on_change=AuthState.set_email,
|
||||||
|
|
@ -288,7 +287,7 @@ def render_login_window() -> rx.Component:
|
||||||
height="45px",
|
height="45px",
|
||||||
align_items="center",
|
align_items="center",
|
||||||
border="var(--prismui-border-1)",
|
border="var(--prismui-border-1)",
|
||||||
border_radius="var(--prismui-border-radius-4)",
|
border_radius="var(--prismui-border-radius-3)",
|
||||||
),
|
),
|
||||||
rx.text(
|
rx.text(
|
||||||
AuthState.login_error_message,
|
AuthState.login_error_message,
|
||||||
|
|
@ -364,7 +363,7 @@ def render_login_window() -> rx.Component:
|
||||||
"登录",
|
"登录",
|
||||||
width="100%",
|
width="100%",
|
||||||
height="38px",
|
height="38px",
|
||||||
border_radius="var(--prismui-border-radius-4)",
|
border_radius="var(--prismui-border-radius-3)",
|
||||||
background_color="var(--prismui-color-5)",
|
background_color="var(--prismui-color-5)",
|
||||||
color="var(--prismui-color-9)",
|
color="var(--prismui-color-9)",
|
||||||
cursor="pointer",
|
cursor="pointer",
|
||||||
|
|
@ -392,7 +391,7 @@ def render_login_window() -> rx.Component:
|
||||||
padding="20px",
|
padding="20px",
|
||||||
background_color="var(--prismui-background-color-1)",
|
background_color="var(--prismui-background-color-1)",
|
||||||
border="var(--prismui-border-2)",
|
border="var(--prismui-border-2)",
|
||||||
border_radius="var(--prismui-border-radius-5)",
|
border_radius="var(--prismui-border-radius-4)",
|
||||||
),
|
),
|
||||||
rx.text(
|
rx.text(
|
||||||
"加微信好友",
|
"加微信好友",
|
||||||
|
|
@ -409,7 +408,7 @@ def render_login_window() -> rx.Component:
|
||||||
),
|
),
|
||||||
background="var(--prismui-background-2)",
|
background="var(--prismui-background-2)",
|
||||||
border="1px solid #2222220f",
|
border="1px solid #2222220f",
|
||||||
border_radius="var(--prismui-border-radius-5)",
|
border_radius="var(--prismui-border-radius-4)",
|
||||||
box_shadow="0 4px 64px 0 #0000001a",
|
box_shadow="0 4px 64px 0 #0000001a",
|
||||||
overflow="hidden",
|
overflow="hidden",
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,9 @@
|
||||||
--prismui-color-9: #ffffff;
|
--prismui-color-9: #ffffff;
|
||||||
--prismui-border-1: 1px solid #060a260f;
|
--prismui-border-1: 1px solid #060a260f;
|
||||||
--prismui-border-radius-1: 4px;
|
--prismui-border-radius-1: 4px;
|
||||||
--prismui-border-radius-2: 6px;
|
--prismui-border-radius-2: 8px;
|
||||||
--prismui-border-radius-3: 8px;
|
--prismui-border-radius-3: 12px;
|
||||||
--prismui-border-radius-4: 12px;
|
--prismui-border-radius-4: 20px;
|
||||||
--prismui-border-radius-5: 20px;
|
|
||||||
--prismui-box-shadow-1: 0 4px 64px 0 #0000001a;
|
--prismui-box-shadow-1: 0 4px 64px 0 #0000001a;
|
||||||
--prismui-box-shadow-2: 0 4px 12px #0000001a;
|
--prismui-box-shadow-2: 0 4px 12px #0000001a;
|
||||||
--prismui-box-shadow-3: 0 2px 12px 0 #252b3a3d;
|
--prismui-box-shadow-3: 0 2px 12px 0 #252b3a3d;
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue