Merge branch 'dhk-2' into 'master'
页面结构调整 See merge request knowledge-base-bj/deerflow-server!5
This commit is contained in:
commit
4567db8836
3 files changed
+149
-14
No files matched your search
@@ -5,25 +5,35 @@ import { PageSidebar } from "@/components/page-sidebar";
|
|||||||
|
|
||||||
import WorkspaceRoutes from "./WorkspaceRoutes";
|
import WorkspaceRoutes from "./WorkspaceRoutes";
|
||||||
|
|
||||||
|
// 设为 true 时隐藏侧边栏(开发中,暂未完成)
|
||||||
|
const SIDEBAR_ENABLED = false;
|
||||||
|
|
||||||
function PageLayout() {
|
function PageLayout() {
|
||||||
const [collapsed, setCollapsed] = useState(false);
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-muted/20">
|
<div className="min-h-screen bg-muted/20">
|
||||||
<PageSidebar
|
{SIDEBAR_ENABLED && (
|
||||||
collapsed={collapsed}
|
<PageSidebar
|
||||||
onToggleCollapsed={() => setCollapsed((prev) => !prev)}
|
collapsed={collapsed}
|
||||||
/>
|
onToggleCollapsed={() => setCollapsed((prev) => !prev)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<main
|
<main
|
||||||
className={`min-h-screen transition-[padding] duration-300 ${
|
className={`min-h-screen transition-[padding] duration-300 ${
|
||||||
collapsed ? "pl-16" : "pl-16 md:pl-64"
|
!SIDEBAR_ENABLED ? "" : collapsed ? "pl-16" : "pl-16 md:pl-64"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route index element={<Navigate to="workspace" replace />} />
|
<Route index element={<Navigate to="workspace" replace />} />
|
||||||
<Route
|
<Route
|
||||||
path="workspace/*"
|
path="workspace/*"
|
||||||
element={<WorkspaceRoutes pageSidebarCollapsed={collapsed} />}
|
element={
|
||||||
|
<WorkspaceRoutes
|
||||||
|
pageSidebarCollapsed={collapsed}
|
||||||
|
pageSidebarHidden={!SIDEBAR_ENABLED}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -20,16 +20,24 @@ import ScheduledTasksPage from "./ScheduledTasksPage";
|
|||||||
function WorkspaceLayout({
|
function WorkspaceLayout({
|
||||||
children,
|
children,
|
||||||
pageSidebarCollapsed,
|
pageSidebarCollapsed,
|
||||||
|
pageSidebarHidden = false,
|
||||||
}: {
|
}: {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
pageSidebarCollapsed: boolean;
|
pageSidebarCollapsed: boolean;
|
||||||
|
pageSidebarHidden?: boolean;
|
||||||
}) {
|
}) {
|
||||||
|
const pageSidebarWidth = pageSidebarHidden
|
||||||
|
? "0rem"
|
||||||
|
: pageSidebarCollapsed
|
||||||
|
? "4rem"
|
||||||
|
: "16rem";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarProvider
|
<SidebarProvider
|
||||||
className="h-screen w-full overflow-x-hidden [&_[data-slot=sidebar-container]]:left-[var(--page-sidebar-width)]"
|
className="h-screen w-full overflow-x-hidden [&_[data-slot=sidebar-container]]:left-[var(--page-sidebar-width)]"
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
"--page-sidebar-width": pageSidebarCollapsed ? "4rem" : "16rem",
|
"--page-sidebar-width": pageSidebarWidth,
|
||||||
} as CSSProperties
|
} as CSSProperties
|
||||||
}
|
}
|
||||||
// Keep the fixed workspace sidebar aligned to the outer page sidebar width.
|
// Keep the fixed workspace sidebar aligned to the outer page sidebar width.
|
||||||
@@ -57,16 +65,20 @@ function ChatRuntime({ children }: { children: ReactNode }) {
|
|||||||
|
|
||||||
export default function WorkspaceRoutes({
|
export default function WorkspaceRoutes({
|
||||||
pageSidebarCollapsed = false,
|
pageSidebarCollapsed = false,
|
||||||
|
pageSidebarHidden = false,
|
||||||
}: {
|
}: {
|
||||||
pageSidebarCollapsed?: boolean;
|
pageSidebarCollapsed?: boolean;
|
||||||
|
pageSidebarHidden?: boolean;
|
||||||
}) {
|
}) {
|
||||||
|
const layoutProps = { pageSidebarCollapsed, pageSidebarHidden };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route index element={<Navigate to="chats/new" replace />} />
|
<Route index element={<Navigate to="chats/new" replace />} />
|
||||||
<Route
|
<Route
|
||||||
path="chats"
|
path="chats"
|
||||||
element={
|
element={
|
||||||
<WorkspaceLayout pageSidebarCollapsed={pageSidebarCollapsed}>
|
<WorkspaceLayout {...layoutProps}>
|
||||||
<ChatsPage />
|
<ChatsPage />
|
||||||
</WorkspaceLayout>
|
</WorkspaceLayout>
|
||||||
}
|
}
|
||||||
@@ -74,7 +86,7 @@ export default function WorkspaceRoutes({
|
|||||||
<Route
|
<Route
|
||||||
path="chats/:thread_id"
|
path="chats/:thread_id"
|
||||||
element={
|
element={
|
||||||
<WorkspaceLayout pageSidebarCollapsed={pageSidebarCollapsed}>
|
<WorkspaceLayout {...layoutProps}>
|
||||||
<ChatRuntime>
|
<ChatRuntime>
|
||||||
<ChatPage />
|
<ChatPage />
|
||||||
</ChatRuntime>
|
</ChatRuntime>
|
||||||
@@ -84,7 +96,7 @@ export default function WorkspaceRoutes({
|
|||||||
<Route
|
<Route
|
||||||
path="agents"
|
path="agents"
|
||||||
element={
|
element={
|
||||||
<WorkspaceLayout pageSidebarCollapsed={pageSidebarCollapsed}>
|
<WorkspaceLayout {...layoutProps}>
|
||||||
<AgentsPage />
|
<AgentsPage />
|
||||||
</WorkspaceLayout>
|
</WorkspaceLayout>
|
||||||
}
|
}
|
||||||
@@ -92,7 +104,7 @@ export default function WorkspaceRoutes({
|
|||||||
<Route
|
<Route
|
||||||
path="agents/new"
|
path="agents/new"
|
||||||
element={
|
element={
|
||||||
<WorkspaceLayout pageSidebarCollapsed={pageSidebarCollapsed}>
|
<WorkspaceLayout {...layoutProps}>
|
||||||
<NewAgentPage />
|
<NewAgentPage />
|
||||||
</WorkspaceLayout>
|
</WorkspaceLayout>
|
||||||
}
|
}
|
||||||
@@ -104,7 +116,7 @@ export default function WorkspaceRoutes({
|
|||||||
<Route
|
<Route
|
||||||
path="agents/:agent_id/chats/:thread_id"
|
path="agents/:agent_id/chats/:thread_id"
|
||||||
element={
|
element={
|
||||||
<WorkspaceLayout pageSidebarCollapsed={pageSidebarCollapsed}>
|
<WorkspaceLayout {...layoutProps}>
|
||||||
<ChatRuntime>
|
<ChatRuntime>
|
||||||
<AgentChatPage />
|
<AgentChatPage />
|
||||||
</ChatRuntime>
|
</ChatRuntime>
|
||||||
@@ -118,7 +130,7 @@ export default function WorkspaceRoutes({
|
|||||||
<Route
|
<Route
|
||||||
path="scheduled/tasks"
|
path="scheduled/tasks"
|
||||||
element={
|
element={
|
||||||
<WorkspaceLayout pageSidebarCollapsed={pageSidebarCollapsed}>
|
<WorkspaceLayout {...layoutProps}>
|
||||||
<ScheduledTasksPage />
|
<ScheduledTasksPage />
|
||||||
</WorkspaceLayout>
|
</WorkspaceLayout>
|
||||||
}
|
}
|
||||||
@@ -126,7 +138,7 @@ export default function WorkspaceRoutes({
|
|||||||
<Route
|
<Route
|
||||||
path="scheduled/runs/:run_id"
|
path="scheduled/runs/:run_id"
|
||||||
element={
|
element={
|
||||||
<WorkspaceLayout pageSidebarCollapsed={pageSidebarCollapsed}>
|
<WorkspaceLayout {...layoutProps}>
|
||||||
<ScheduledTaskRunDetailPage />
|
<ScheduledTaskRunDetailPage />
|
||||||
</WorkspaceLayout>
|
</WorkspaceLayout>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
# 后端服务启停说明(Windows)
|
||||||
|
|
||||||
|
你当前是 **Windows + PowerShell** 环境,下面这份是可直接用的后端启停命令。
|
||||||
|
|
||||||
|
> 说明:仓库里的 `scripts/*.sh` 是 Bash 脚本,Windows 原生 PowerShell 不能直接执行,所以会出现“启动不了”。
|
||||||
|
|
||||||
|
## 一、后端目录
|
||||||
|
|
||||||
|
后端目录:
|
||||||
|
|
||||||
|
```text
|
||||||
|
offline-backend-20260512/backend/
|
||||||
|
```
|
||||||
|
|
||||||
|
下面命令默认都在这个目录执行。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、Windows 下推荐启动方式
|
||||||
|
|
||||||
|
### 1) 开发模式启动(热重载)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
uv run uvicorn app.gateway.app:app --host 0.0.0.0 --port 8001 --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2) 普通模式启动(无热重载)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
uv run uvicorn app.gateway.app:app --host 0.0.0.0 --port 8001
|
||||||
|
```
|
||||||
|
|
||||||
|
> 如果你习惯 `make dev / make gateway`,Windows 上通常还需要额外安装 make,建议直接用上面两条 `uv run uvicorn` 更稳。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、停止后端
|
||||||
|
|
||||||
|
如果后端在当前窗口前台运行:
|
||||||
|
|
||||||
|
- 直接按 `Ctrl + C`
|
||||||
|
|
||||||
|
如果窗口已经关了,或你想强制结束 8001 端口进程:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
netstat -ano | findstr :8001
|
||||||
|
```
|
||||||
|
|
||||||
|
记下最后一列 PID 后执行:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
taskkill /PID <PID> /F
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、首次安装依赖(只需一次)
|
||||||
|
|
||||||
|
在 `offline-backend-20260512/backend` 目录执行:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
uv sync
|
||||||
|
```
|
||||||
|
|
||||||
|
如果 `uv` 命令不存在,先安装(任选其一):
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
pip install uv
|
||||||
|
```
|
||||||
|
|
||||||
|
或(已安装 winget 时):
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
winget install --id Astral-sh.uv -e
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、快速自检
|
||||||
|
|
||||||
|
启动后浏览器访问:
|
||||||
|
|
||||||
|
- [http://localhost:8001/health](http://localhost:8001/health)
|
||||||
|
|
||||||
|
返回健康状态即表示后端正常。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、常见问题
|
||||||
|
|
||||||
|
### 1) 报错:端口 8001 被占用
|
||||||
|
|
||||||
|
先执行:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
netstat -ano | findstr :8001
|
||||||
|
```
|
||||||
|
|
||||||
|
然后 `taskkill` 对应 PID,再重启后端。
|
||||||
|
|
||||||
|
### 2) 报错:`uv` 不是内部或外部命令
|
||||||
|
|
||||||
|
先安装 `uv`(见上面的“首次安装依赖”),安装后重开一个 PowerShell 窗口再试。
|
||||||
|
|
||||||
|
### 3) 报错:模块/依赖缺失
|
||||||
|
|
||||||
|
重新执行:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
uv sync
|
||||||
|
```
|
||||||
|
|
||||||
|
再启动。
|
||||||
Reference in new issue
Block a user