生产管理系统前端-上边栏搭建与侧边栏搭建
This commit is contained in:
471
docs/项目架构设计文档.md
471
docs/项目架构设计文档.md
@@ -218,7 +218,9 @@ interface User {
|
||||
- ✅ React Hook Form + Zod
|
||||
|
||||
#### 新增核心技术
|
||||
- 🆕 **React Router v6**: 专业路由管理
|
||||
- 🆕 **Next.js 14**: 现代化 React 全栈框架,支持动态路由和SSR
|
||||
- 🆕 **Next.js App Router**: 基于文件系统的动态路由
|
||||
- 🆕 **React Server Components**: 服务端组件渲染优化
|
||||
- 🆕 **Zustand**: 轻量级状态管理
|
||||
- 🆕 **TanStack Query**: 服务端状态管理
|
||||
- 🆕 **MSW**: Mock Service Worker
|
||||
@@ -231,8 +233,48 @@ interface User {
|
||||
crop-x/
|
||||
├── public/ # 静态资源
|
||||
│ ├── favicon.ico
|
||||
│ └── index.html
|
||||
│ └── next-env.d.ts # Next.js 类型声明
|
||||
├── src/
|
||||
│ ├── app/ # Next.js App Router 目录
|
||||
│ │ ├── layout.tsx # 根布局
|
||||
│ │ ├── page.tsx # 首页
|
||||
│ │ ├── globals.css # 全局样式
|
||||
│ │ ├── (auth)/ # 认证相关路由组
|
||||
│ │ │ ├── login/
|
||||
│ │ │ │ └── page.tsx
|
||||
│ │ │ └── register/
|
||||
│ │ │ └── page.tsx
|
||||
│ │ ├── machinery/ # 农机管理动态路由
|
||||
│ │ │ ├── layout.tsx # 农机模块布局
|
||||
│ │ │ ├── page.tsx # 农机默认页面
|
||||
│ │ │ ├── archive/
|
||||
│ │ │ │ ├── entry/
|
||||
│ │ │ │ │ └── page.tsx
|
||||
│ │ │ │ └── [id]/
|
||||
│ │ │ │ └── page.tsx # 动态路由详情页
|
||||
│ │ │ ├── driver/
|
||||
│ │ │ │ └── page.tsx
|
||||
│ │ │ └── monitoring/
|
||||
│ │ │ └── realtime/
|
||||
│ │ │ └── page.tsx
|
||||
│ │ ├── field/ # 地块管理动态路由
|
||||
│ │ │ ├── layout.tsx
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── [category]/
|
||||
│ │ │ └── page.tsx
|
||||
│ │ ├── operation/ # 农事操作动态路由
|
||||
│ │ ├── asset/ # 资产管理动态路由
|
||||
│ │ ├── ai-model/ # AI模型动态路由
|
||||
│ │ ├── irrigation/ # 灌溉控制动态路由
|
||||
│ │ ├── config/ # 配置管理动态路由
|
||||
│ │ │ ├── layout.tsx
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── tenant/
|
||||
│ │ │ ├── enterprise-audit/
|
||||
│ │ │ │ └── page.tsx
|
||||
│ │ │ └── [enterpriseId]/
|
||||
│ │ │ └── page.tsx # 企业详情动态路由
|
||||
│ │ └── loading.tsx # 全局加载组件
|
||||
│ ├── components/ # 可复用组件
|
||||
│ │ ├── ui/ # shadcn/ui 基础组件
|
||||
│ │ │ ├── button/
|
||||
@@ -247,178 +289,307 @@ crop-x/
|
||||
│ │ ├── Header/
|
||||
│ │ ├── Sidebar/
|
||||
│ │ └── Layout/
|
||||
│ ├── pages/ # 页面组件(按业务模块)
|
||||
│ │ ├── auth/ # 认证相关页面
|
||||
│ │ │ ├── LoginPage.tsx
|
||||
│ │ │ └── RegisterPage.tsx
|
||||
│ │ ├── machinery/ # 农机管理页面
|
||||
│ │ │ ├── MachineryListPage.tsx
|
||||
│ │ │ ├── MachineryDetailPage.tsx
|
||||
│ │ │ ├── DriverListPage.tsx
|
||||
│ ├── lib/ # Next.js 库目录
|
||||
│ │ ├── stores/ # Zustand 状态管理
|
||||
│ │ │ ├── authStore.ts
|
||||
│ │ │ ├── machineryStore.ts
|
||||
│ │ │ └── ...
|
||||
│ │ ├── field/ # 地块管理页面
|
||||
│ │ ├── operation/ # 农事操作页面
|
||||
│ │ ├── asset/ # 资产管理页面
|
||||
│ │ ├── ai-model/ # AI模型页面
|
||||
│ │ ├── irrigation/ # 灌溉控制页面
|
||||
│ │ └── config/ # 配置管理页面
|
||||
│ ├── stores/ # Zustand 状态管理
|
||||
│ │ ├── authStore.ts # 认证状态
|
||||
│ │ ├── machineryStore.ts # 农机状态
|
||||
│ │ ├── fieldStore.ts # 地块状态
|
||||
│ │ ├── operationStore.ts # 农事状态
|
||||
│ │ ├── assetStore.ts # 资产状态
|
||||
│ │ ├── aiModelStore.ts # AI模型状态
|
||||
│ │ ├── irrigationStore.ts # 灌溉状态
|
||||
│ │ └── configStore.ts # 配置状态
|
||||
│ ├── services/ # API 服务层
|
||||
│ │ ├── api/ # API 配置和请求
|
||||
│ │ │ ├── client.ts # Axios 配置
|
||||
│ │ │ ├── machineryApi.ts
|
||||
│ │ │ ├── fieldApi.ts
|
||||
│ │ │ └── ...
|
||||
│ │ ├── mock/ # Mock 数据管理
|
||||
│ │ │ ├── handlers/ # MSW 处理器
|
||||
│ │ │ ├── data/ # Mock 数据
|
||||
│ │ │ └── browser.ts # MSW 配置
|
||||
│ │ └── types/ # API 类型定义
|
||||
│ │ ├── machinery.ts
|
||||
│ │ ├── field.ts
|
||||
│ │ └── ...
|
||||
│ ├── hooks/ # 自定义 Hooks
|
||||
│ │ ├── useAuth.ts
|
||||
│ │ ├── useMachinery.ts
|
||||
│ │ └── ...
|
||||
│ ├── utils/ # 工具函数
|
||||
│ │ ├── date.ts
|
||||
│ │ ├── format.ts
|
||||
│ │ └── ...
|
||||
│ ├── constants/ # 常量定义
|
||||
│ │ ├── routes.ts
|
||||
│ │ ├── permissions.ts
|
||||
│ │ └── ...
|
||||
│ ├── router/ # 路由配置
|
||||
│ │ ├── index.ts # 路由器配置
|
||||
│ │ ├── authRoutes.ts # 认证路由
|
||||
│ │ ├── machineryRoutes.ts # 农机路由
|
||||
│ │ └── ...
|
||||
│ ├── styles/ # 样式文件
|
||||
│ │ ├── globals.css
|
||||
│ │ └── components.css
|
||||
│ │ ├── services/ # API 服务层
|
||||
│ │ │ ├── api/ # API 配置和请求
|
||||
│ │ │ │ ├── client.ts
|
||||
│ │ │ │ ├── machineryApi.ts
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ ├── mock/ # Mock 数据管理
|
||||
│ │ │ │ ├── handlers/
|
||||
│ │ │ │ ├── data/
|
||||
│ │ │ │ └── browser.ts
|
||||
│ │ │ └── types/
|
||||
│ │ │ ├── machinery.ts
|
||||
│ │ │ └── ...
|
||||
│ │ ├── hooks/ # 自定义 Hooks
|
||||
│ │ │ ├── useAuth.ts
|
||||
│ │ │ └── useMachinery.ts
|
||||
│ │ ├── utils/ # 工具函数
|
||||
│ │ │ ├── date.ts
|
||||
│ │ │ └── format.ts
|
||||
│ │ └── constants/ # 常量定义
|
||||
│ │ ├── routes.ts
|
||||
│ │ └── permissions.ts
|
||||
│ ├── types/ # 全局类型定义
|
||||
│ │ ├── auth.ts
|
||||
│ │ ├── machinery.ts
|
||||
│ │ ├── navigation.ts
|
||||
│ │ └── ...
|
||||
│ ├── App.tsx # 根组件
|
||||
│ └── main.tsx # 应用入口
|
||||
│ │ └── navigation.ts
|
||||
│ └── styles/ # 样式文件
|
||||
│ └── globals.css
|
||||
├── tests/ # 测试文件
|
||||
│ ├── __mocks__/ # 全局 Mock
|
||||
│ ├── fixtures/ # 测试数据
|
||||
│ ├── unit/ # 单元测试
|
||||
│ ├── integration/ # 集成测试
|
||||
│ └── setup.ts # 测试配置
|
||||
│ ├── __mocks__/
|
||||
│ ├── fixtures/
|
||||
│ ├── unit/
|
||||
│ ├── integration/
|
||||
│ └── setup.ts
|
||||
├── docs/ # 项目文档
|
||||
├── .eslintrc.js # ESLint 配置
|
||||
├── .prettierrc # Prettier 配置
|
||||
├── next.config.js # Next.js 配置
|
||||
├── package.json
|
||||
├── vite.config.ts
|
||||
├── tsconfig.json
|
||||
├── tailwind.config.js
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### 路由系统重设计
|
||||
### Next.js 动态路由系统设计
|
||||
|
||||
#### App Router 架构
|
||||
Next.js App Router 提供了基于文件系统的路由,支持动态路由、嵌套路由和路由组。
|
||||
|
||||
#### 路由架构
|
||||
```typescript
|
||||
// router/index.ts
|
||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
|
||||
import { ProtectedRoute } from '../components/ProtectedRoute'
|
||||
import { Layout } from '../components/layout/Layout'
|
||||
import { authRoutes } from './authRoutes'
|
||||
import { machineryRoutes } from './machineryRoutes'
|
||||
// ... 其他路由
|
||||
// src/app/layout.tsx - 根布局
|
||||
import { AuthProvider } from '@/lib/providers/AuthProvider'
|
||||
import { ThemeProvider } from '@/lib/providers/ThemeProvider'
|
||||
import './globals.css'
|
||||
|
||||
export const router = createBrowserRouter([
|
||||
// 公开路由
|
||||
...authRoutes,
|
||||
|
||||
// 受保护的主路由
|
||||
{
|
||||
path: '/',
|
||||
element: (
|
||||
<ProtectedRoute>
|
||||
<Layout />
|
||||
</ProtectedRoute>
|
||||
),
|
||||
children: [
|
||||
// 7大业务系统路由
|
||||
...machineryRoutes,
|
||||
...fieldRoutes,
|
||||
...operationRoutes,
|
||||
...assetRoutes,
|
||||
...aiModelRoutes,
|
||||
...irrigationRoutes,
|
||||
...configRoutes,
|
||||
|
||||
// 默认路由
|
||||
{
|
||||
index: true,
|
||||
element: <Navigate to="/machinery/archive/entry" replace />
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// 404页面
|
||||
{ path: '*', element: <NotFoundPage /> }
|
||||
])
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<html lang="zh-CN">
|
||||
<body>
|
||||
<ThemeProvider>
|
||||
<AuthProvider>
|
||||
{children}
|
||||
</AuthProvider>
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务路由示例
|
||||
#### 动态路由示例
|
||||
|
||||
##### 1. 农机管理模块路由结构
|
||||
```
|
||||
src/app/machinery/
|
||||
├── layout.tsx # 农机模块专属布局
|
||||
├── page.tsx # /machinery - 农机管理首页
|
||||
├── archive/
|
||||
│ ├── page.tsx # /machinery/archive - 档案管理
|
||||
│ ├── entry/
|
||||
│ │ └── page.tsx # /machinery/archive/entry - 档案录入
|
||||
│ └── [id]/
|
||||
│ └── page.tsx # /machinery/archive/[id] - 动态详情页
|
||||
├── driver/
|
||||
│ ├── page.tsx # /machinery/driver - 驾驶员管理
|
||||
│ └── [driverId]/
|
||||
│ └── page.tsx # /machinery/driver/[driverId] - 驾驶员详情
|
||||
└── monitoring/
|
||||
└── realtime/
|
||||
└── page.tsx # /machinery/monitoring/realtime - 实时监控
|
||||
```
|
||||
|
||||
##### 2. 动态路由组件实现
|
||||
```typescript
|
||||
// router/machineryRoutes.ts
|
||||
import { lazy } from 'react'
|
||||
// src/app/machinery/archive/[id]/page.tsx
|
||||
import { notFound } from 'next/navigation'
|
||||
import { MachineryDetailPage } from '@/components/pages/machinery/MachineryDetailPage'
|
||||
import { getMachineryById } from '@/lib/services/api/machineryApi'
|
||||
|
||||
// 懒加载页面组件
|
||||
const MachineryListPage = lazy(() => import('../pages/machinery/MachineryListPage'))
|
||||
const MachineryDetailPage = lazy(() => import('../pages/machinery/MachineryDetailPage'))
|
||||
const DriverListPage = lazy(() => import('../pages/machinery/DriverListPage'))
|
||||
interface Props {
|
||||
params: { id: string }
|
||||
}
|
||||
|
||||
export const machineryRoutes = [
|
||||
{
|
||||
path: 'machinery/*',
|
||||
children: [
|
||||
// 农机档案管理
|
||||
{
|
||||
path: 'archive/entry',
|
||||
element: <MachineryListPage />
|
||||
},
|
||||
{
|
||||
path: 'archive/detail/:id',
|
||||
element: <MachineryDetailPage />
|
||||
},
|
||||
export default async function MachineryDetail({ params }: Props) {
|
||||
const machinery = await getMachineryById(params.id)
|
||||
|
||||
// 驾驶员管理
|
||||
{
|
||||
path: 'driver/list',
|
||||
element: <DriverListPage />
|
||||
},
|
||||
|
||||
// 实时监控
|
||||
{
|
||||
path: 'monitoring/realtime',
|
||||
element: lazy(() => import('../pages/machinery/MonitoringPage'))
|
||||
},
|
||||
|
||||
// 任务调度
|
||||
{
|
||||
path: 'scheduling/task',
|
||||
element: lazy(() => import('../pages/machinery/SchedulingPage'))
|
||||
}
|
||||
]
|
||||
if (!machinery) {
|
||||
notFound()
|
||||
}
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="container mx-auto p-6">
|
||||
<MachineryDetailPage machinery={machinery} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// 生成静态路径(可选,用于SSG)
|
||||
export async function generateStaticParams() {
|
||||
// 预生成一些常见的农机详情页
|
||||
return [
|
||||
{ id: 'machinery-001' },
|
||||
{ id: 'machinery-002' },
|
||||
{ id: 'machinery-003' },
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
##### 3. 路由组的使用
|
||||
```
|
||||
src/app/
|
||||
├── (auth)/ # 路由组:不影响URL路径
|
||||
│ ├── layout.tsx # 认证页面专属布局
|
||||
│ ├── login/
|
||||
│ │ └── page.tsx # /login
|
||||
│ └── register/
|
||||
│ └── page.tsx # /register
|
||||
├── (dashboard)/ # 路由组:受保护的管理区域
|
||||
│ ├── layout.tsx # 仪表板布局
|
||||
│ ├── machinery/
|
||||
│ ├── field/
|
||||
│ └── config/
|
||||
```
|
||||
|
||||
##### 4. 路由布局系统
|
||||
```typescript
|
||||
// src/app/(dashboard)/layout.tsx
|
||||
import { SidebarProvider } from '@/lib/providers/SidebarProvider'
|
||||
import { MainLayout } from '@/components/layout/MainLayout'
|
||||
import { auth } from '@/lib/auth'
|
||||
|
||||
export default async function DashboardLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
// 服务端认证检查
|
||||
const session = await auth()
|
||||
|
||||
if (!session) {
|
||||
redirect('/login')
|
||||
}
|
||||
|
||||
return (
|
||||
<SidebarProvider>
|
||||
<MainLayout>
|
||||
{children}
|
||||
</MainLayout>
|
||||
</SidebarProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
#### 动态路由特性
|
||||
|
||||
##### 1. 路由参数处理
|
||||
```typescript
|
||||
// src/app/config/tenant/[enterpriseId]/page.tsx
|
||||
interface PageProps {
|
||||
params: { enterpriseId: string }
|
||||
searchParams: { [key: string]: string | string[] | undefined }
|
||||
}
|
||||
|
||||
export default async function EnterpriseDetail({
|
||||
params,
|
||||
searchParams,
|
||||
}: PageProps) {
|
||||
const enterpriseId = params.enterpriseId
|
||||
const tab = searchParams.tab as string || 'basic'
|
||||
|
||||
// 根据查询参数显示不同tab
|
||||
return (
|
||||
<div>
|
||||
<h1>企业详情:{enterpriseId}</h1>
|
||||
<EnterpriseDetailTab activeTab={tab} enterpriseId={enterpriseId} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
##### 2. 平行路由和插槽
|
||||
```typescript
|
||||
// src/app/machinery/layout.tsx
|
||||
export default function MachineryLayout({
|
||||
children,
|
||||
analytics,
|
||||
monitoring, // 插槽
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
analytics?: React.ReactNode
|
||||
monitoring?: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<div className="flex h-full">
|
||||
<div className="flex-1">{children}</div>
|
||||
{analytics && (
|
||||
<div className="w-80 border-l">{analytics}</div>
|
||||
)}
|
||||
{monitoring && (
|
||||
<div className="w-80 border-l">{monitoring}</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
##### 3. 路由中间件
|
||||
```typescript
|
||||
// middleware.ts
|
||||
import { NextResponse } from 'next/server'
|
||||
import type { NextRequest } from 'next/server'
|
||||
import { auth } from './lib/auth'
|
||||
|
||||
export async function middleware(request: NextRequest) {
|
||||
const session = await auth()
|
||||
const { pathname } = request.nextUrl
|
||||
|
||||
// 未登录用户重定向到登录页
|
||||
if (!session && pathname.startsWith('/dashboard')) {
|
||||
return NextResponse.redirect(new URL('/login', request.url))
|
||||
}
|
||||
|
||||
// 已登录用户访问登录页重定向到仪表板
|
||||
if (session && pathname === '/login') {
|
||||
return NextResponse.redirect(new URL('/dashboard', request.url))
|
||||
}
|
||||
|
||||
return NextResponse.next()
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ['/dashboard/:path*', '/login', '/register']
|
||||
}
|
||||
```
|
||||
|
||||
#### 服务端组件优势
|
||||
|
||||
##### 1. 数据获取
|
||||
```typescript
|
||||
// src/app/machinery/page.tsx - 服务端组件
|
||||
import { getMachineryList } from '@/lib/services/api/machineryApi'
|
||||
import { MachineryGrid } from '@/components/business/machinery/MachineryGrid'
|
||||
|
||||
export default async function MachineryPage() {
|
||||
// 服务端直接获取数据
|
||||
const machineryData = await getMachineryList()
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>农机管理系统</h1>
|
||||
<MachineryGrid initialData={machineryData} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
##### 2. 缓存和重新验证
|
||||
```typescript
|
||||
// src/lib/services/api/machineryApi.ts
|
||||
export async function getMachineryList() {
|
||||
const res = await fetch('/api/machinery', {
|
||||
next: {
|
||||
tags: ['machinery'], // 缓存标签
|
||||
revalidate: 60, // 60秒重新验证
|
||||
}
|
||||
})
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error('Failed to fetch machinery data')
|
||||
}
|
||||
|
||||
return res.json()
|
||||
}
|
||||
```
|
||||
|
||||
### 状态管理架构
|
||||
|
||||
Reference in New Issue
Block a user