提交1 bmad搭建与项目启动 - ok

This commit is contained in:
2025-10-17 17:24:56 +08:00
commit ec58562661
686 changed files with 149750 additions and 0 deletions

644
crop-x/DEVELOPMENT.md Normal file
View File

@@ -0,0 +1,644 @@
# 开发指南
本文档为智慧农业生产管理系统的开发指南,帮助开发者快速了解项目结构、开发规范和最佳实践。
## 📋 目录
- [环境准备](#环境准备)
- [项目结构](#项目结构)
- [开发规范](#开发规范)
- [组件开发](#组件开发)
- [状态管理](#状态管理)
- [样式指南](#样式指南)
- [API集成](#api集成)
- [测试指南](#测试指南)
- [调试技巧](#调试技巧)
- [常见问题](#常见问题)
## 🛠️ 环境准备
### 必需软件
- **Node.js**: >= 18.0.0
- **npm**: >= 8.0.0 或 **yarn**: >= 1.22.0
- **Git**: 最新版本
### 推荐工具
- **IDE**: Visual Studio Code
- **浏览器**: Chrome/Firefox (最新版本)
- **Node管理**: nvm (可选)
### VSCode扩展推荐
项目已配置 `.vscode/extensions.json`,安装以下扩展获得最佳开发体验:
```json
{
"recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"bradlc.vscode-tailwindcss",
"ms-vscode.vscode-typescript-next",
"formulahendry.auto-rename-tag",
"christian-kohler.path-intellisense"
]
}
```
## 📁 项目结构详解
### 核心目录
```
src/
├── components/ # 组件库
│ ├── ui/ # shadcn/ui基础组件
│ ├── common/ # 通用业务组件
│ └── layouts/ # 布局组件
├── pages/ # 页面组件
├── hooks/ # 自定义Hooks
├── lib/ # 工具库
├── config/ # 配置文件
├── types/ # TypeScript类型
├── utils/ # 工具函数
├── styles/ # 样式文件
└── assets/ # 静态资源
```
### 组件组织原则
1. **UI组件** (`components/ui/`): 纯UI组件无业务逻辑
2. **业务组件** (`components/common/`): 包含业务逻辑的复用组件
3. **页面组件** (`pages/`): 具体页面实现,组合业务组件
4. **布局组件** (`components/layouts/`): 页面布局结构
## 📏 开发规范
### 代码规范
#### TypeScript规范
```typescript
// ✅ 使用类型注解
interface UserData {
id: string
name: string
email: string
}
const getUser = async (id: string): Promise<UserData> => {
// 实现
}
// ✅ 使用泛型
interface ApiResponse<T> {
data: T
success: boolean
}
// ✅ 枚举使用
enum UserRole {
ADMIN = 'admin',
USER = 'user'
}
```
#### React组件规范
```typescript
// ✅ 函数式组件 + Hooks
interface UserCardProps {
user: UserData
onEdit?: (user: UserData) => void
className?: string
}
export const UserCard: React.FC<UserCardProps> = ({
user,
onEdit,
className
}) => {
const [isEditing, setIsEditing] = useState(false)
const handleEdit = useCallback(() => {
onEdit?.(user)
setIsEditing(true)
}, [user, onEdit])
return (
<div className={cn('user-card', className)}>
{/* 组件内容 */}
</div>
)
}
```
#### 命名规范
- **文件名**: kebab-case (`user-card.tsx`)
- **组件名**: PascalCase (`UserCard`)
- **变量名**: camelCase (`userName`)
- **常量名**: UPPER_SNAKE_CASE (`API_BASE_URL`)
- **类型名**: PascalCase (`UserData`)
### Git提交规范
使用 [Conventional Commits](https://conventionalcommits.org/) 规范:
```
<type>(<scope>): <subject>
<body>
<footer>
```
#### 提交类型
- `feat`: 新功能
- `fix`: 修复bug
- `docs`: 文档更新
- `style`: 代码格式化
- `refactor`: 重构代码
- `test`: 测试相关
- `chore`: 构建工具、依赖更新
#### 示例
```bash
feat(machinery): add machinery status monitoring
fix(auth): resolve login validation issue
docs(readme): update installation guide
```
## 🧩 组件开发
### 组件结构模板
```typescript
// src/components/example/ExampleComponent.tsx
import React, { useState, useCallback } from 'react'
import { cn } from '@/lib/utils'
interface ExampleComponentProps {
title: string
onAction?: () => void
className?: string
}
export const ExampleComponent: React.FC<ExampleComponentProps> = ({
title,
onAction,
className
}) => {
const [state, setState] = useState(false)
const handleClick = useCallback(() => {
setState(prev => !prev)
onAction?.()
}, [onAction])
return (
<div className={cn('example-component', className)}>
<h3 className="example-title">{title}</h3>
<button onClick={handleClick}>
Click me
</button>
</div>
)
}
```
### 组件样式规范
```css
/* 优先使用Tailwind CSS类名 */
.example-component {
@apply rounded-lg border border-gray-200 p-4 bg-white shadow-sm;
}
.example-title {
@apply text-lg font-semibold text-gray-900 mb-2;
}
/* 必要时使用传统CSS */
.example-component:hover {
transform: translateY(-1px);
transition: transform 0.2s ease;
}
```
### shadcn/ui组件使用
```typescript
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
export const MachineryCard = ({ machinery }) => {
return (
<Card className="machinery-card">
<CardHeader>
<CardTitle>{machinery.name}</CardTitle>
<Badge variant={machinery.status === 'running' ? 'default' : 'secondary'}>
{machinery.status}
</Badge>
</CardHeader>
<CardContent>
{/* 内容 */}
</CardContent>
</Card>
)
}
```
## 🔄 状态管理
### useState使用
```typescript
const [formData, setFormData] = useState({
name: '',
email: '',
phone: ''
})
// 更新对象状态
const handleChange = (field: string, value: string) => {
setFormData(prev => ({
...prev,
[field]: value
}))
}
```
### useReducer使用
```typescript
type State = {
count: number
loading: boolean
}
type Action =
| { type: 'increment' }
| { type: 'decrement' }
| { type: 'setLoading'; payload: boolean }
const reducer = (state: State, action: Action): State => {
switch (action.type) {
case 'increment':
return { ...state, count: state.count + 1 }
case 'decrement':
return { ...state, count: state.count - 1 }
case 'setLoading':
return { ...state, loading: action.payload }
default:
return state
}
}
const [state, dispatch] = useReducer(reducer, {
count: 0,
loading: false
})
```
### 自定义Hooks
```typescript
// src/hooks/useApi.ts
import { useState, useEffect } from 'react'
export function useApi<T>(url: string) {
const [data, setData] = useState<T | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true)
const response = await fetch(url)
const result = await response.json()
setData(result)
} catch (err) {
setError(err.message)
} finally {
setLoading(false)
}
}
fetchData()
}, [url])
return { data, loading, error }
}
```
## 🎨 样式指南
### Tailwind CSS最佳实践
```typescript
// ✅ 使用cn工具函数合并类名
import { cn } from '@/lib/utils'
const Button = ({ variant = 'primary', className, ...props }) => {
return (
<button
className={cn(
'px-4 py-2 rounded-md font-medium transition-colors',
{
'bg-blue-600 text-white hover:bg-blue-700': variant === 'primary',
'bg-gray-200 text-gray-900 hover:bg-gray-300': variant === 'secondary'
},
className
)}
{...props}
/>
)
}
```
### 响应式设计
```typescript
// 移动优先的响应式设计
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{/* 内容 */}
</div>
// 响应式间距
<div className="px-4 sm:px-6 lg:px-8">
{/* 内容 */}
</div>
```
### 深色模式支持
```typescript
import { useTheme } from '@/hooks/useTheme'
export const ThemedComponent = () => {
const { theme, setTheme } = useTheme()
return (
<div className="bg-background text-foreground">
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
切换主题
</button>
</div>
)
}
```
## 🌐 API集成
### API配置
```typescript
// src/config/api.ts
export const API_CONFIG = {
baseUrl: import.meta.env.VITE_API_BASE_URL,
timeout: 10000
}
export const apiClient = {
get: <T>(url: string): Promise<T> => {
return fetch(`${API_CONFIG.baseUrl}${url}`).then(res => res.json())
},
post: <T>(url: string, data: any): Promise<T> => {
return fetch(`${API_CONFIG.baseUrl}${url}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
}).then(res => res.json())
}
}
```
### 数据获取Hook
```typescript
// src/hooks/useMachinery.ts
import { useState, useEffect } from 'react'
import { apiClient } from '@/config/api'
export function useMachinery() {
const [machinery, setMachinery] = useState([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
apiClient.get('/machinery')
.then(setMachinery)
.catch(setError)
.finally(() => setLoading(false))
}, [])
return { machinery, loading, error }
}
```
## 🧪 测试指南
### 单元测试示例
```typescript
// src/components/__tests__/Button.test.tsx
import { render, screen, fireEvent } from '@testing-library/react'
import { Button } from '../Button'
describe('Button', () => {
it('renders correctly', () => {
render(<Button>Click me</Button>)
expect(screen.getByRole('button')).toBeInTheDocument()
})
it('calls onClick when clicked', () => {
const handleClick = jest.fn()
render(<Button onClick={handleClick}>Click me</Button>)
fireEvent.click(screen.getByRole('button'))
expect(handleClick).toHaveBeenCalledTimes(1)
})
})
```
### Hook测试
```typescript
// src/hooks/__tests__/useCounter.test.ts
import { renderHook, act } from '@testing-library/react'
import { useCounter } from '../useCounter'
describe('useCounter', () => {
it('initializes with default value', () => {
const { result } = renderHook(() => useCounter())
expect(result.current.count).toBe(0)
})
it('increments count', () => {
const { result } = renderHook(() => useCounter())
act(() => {
result.current.increment()
})
expect(result.current.count).toBe(1)
})
})
```
## 🐛 调试技巧
### React DevTools
安装 React Developer Tools 浏览器扩展:
```bash
# 检查组件状态
# 查看组件层次结构
# 性能分析
```
### VSCode调试配置
```json
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug React",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/.bin/vite",
"args": ["--mode", "development"],
"env": {
"NODE_ENV": "development"
}
}
]
}
```
### 常用调试代码
```typescript
// 开发环境调试
if (import.meta.env.DEV) {
console.log('Debug info:', data)
}
// 性能监控
console.time('component-render')
// ... 组件渲染逻辑
console.timeEnd('component-render')
// 网络请求调试
const debugFetch = async (url: string) => {
console.log(`Fetching: ${url}`)
const start = performance.now()
try {
const response = await fetch(url)
const data = await response.json()
console.log(`Fetched in ${performance.now() - start}ms`, data)
return data
} catch (error) {
console.error(`Fetch failed after ${performance.now() - start}ms`, error)
throw error
}
}
```
## ❓ 常见问题
### Q: 如何添加新的UI组件
A:
1.`src/components/ui/` 下创建组件文件
2. 使用 shadcn/ui 设计规范
3. 添加 TypeScript 类型定义
4. 编写组件文档
### Q: 如何处理表单验证?
A: 推荐使用 react-hook-form + zod
```typescript
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
const schema = z.object({
name: z.string().min(1, '名称不能为空'),
email: z.string().email('邮箱格式不正确')
})
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema)
})
```
### Q: 如何优化性能?
A:
1. 使用 React.memo 避免不必要的重渲染
2. 使用 useMemo 和 useCallback 缓存计算结果
3. 实现虚拟列表处理大数据
4. 使用代码分割减少初始加载时间
### Q: 如何处理国际化?
A: 项目支持多语言配置:
```typescript
// src/config/i18n.ts
export const locales = {
'zh-CN': '简体中文',
'en-US': 'English'
}
export const translations = {
'zh-CN': {
'machinery.title': '农机管理',
'machinery.status.running': '运行中'
},
'en-US': {
'machinery.title': 'Machinery Management',
'machinery.status.running': 'Running'
}
}
```
### Q: 如何配置开发工具?
A: 使用项目提供的脚本:
```bash
# 查看状态
npm run scripts:setup
# 启用工具
npm run scripts:enable
# 禁用工具
npm run scripts:disable
```
## 📚 更多资源
- [React 官方文档](https://react.dev/)
- [TypeScript 手册](https://www.typescriptlang.org/docs/)
- [Tailwind CSS 文档](https://tailwindcss.com/docs)
- [shadcn/ui 组件库](https://ui.shadcn.com/)
- [Vite 构建工具](https://vitejs.dev/)
---
💡 **提示**: 如果遇到问题,请先查看常见问题部分,或联系项目维护者获取帮助。