# 海洋项目管理系统 - 前端技术架构文档 ## 1. 前端技术栈 ### 1.1 核心框架 - **React 18**: 用于构建用户界面的JavaScript库 - **React Router 6**: 客户端路由管理 - **Vite**: 现代化的前端构建工具(替代Create React App) ### 1.2 UI组件库 - **Ant Design 5**: 企业级UI组件库 - **@ant-design/icons**: Ant Design图标库 ### 1.3 HTTP客户端 - **Axios**: HTTP请求库 ### 1.4 状态管理 - **React Context API**: 轻量级状态管理 - **useReducer Hook**: 复杂状态逻辑 ### 1.5 表单处理 - **Ant Design Form**: 表单组件和验证 - **react-hook-form**: 表单状态管理(可选) ### 1.6 工具库 - **dayjs**: 日期处理(轻量级替代moment.js) - **lodash**: 工具函数库 - **classnames**: 条件类名处理 ### 1.7 开发工具 - **ESLint**: 代码质量检查 - **Prettier**: 代码格式化 - **Vitest**: 单元测试框架 - **React Testing Library**: 组件测试 - **TypeScript**: 类型检查(可选,当前使用JavaScript) ### 1.8 构建和部署 - **Vite**: 开发服务器和构建工具 - **Docker**: 容器化部署(生产环境) ## 2. 前端目录结构 ``` frontend/ ├── src/ # 源代码目录 │ ├── assets/ # 静态资源 │ │ ├── images/ # 图片 │ │ ├── fonts/ # 字体文件 │ │ └── styles/ # 全局样式 │ │ ├── global.css # 全局CSS │ │ ├── variables.css # CSS变量 │ │ └── mixins.css # CSS mixins │ ├── components/ # 可复用组件 │ │ ├── Layout/ # 布局组件 │ │ │ ├── Layout.jsx # 主布局 │ │ │ ├── Header.jsx # 顶部导航 │ │ │ └── Sidebar.jsx # 侧边栏 │ │ ├── Common/ # 通用组件 │ │ │ ├── Button.jsx # 按钮组件 │ │ │ ├── Input.jsx # 输入框组件 │ │ │ ├── Select.jsx # 选择框组件 │ │ │ ├── Table.jsx # 表格组件 │ │ │ ├── Modal.jsx # 弹窗组件 │ │ │ ├── Form.jsx # 表单组件 │ │ │ ├── Card.jsx # 卡片组件 │ │ │ └── Tag.jsx # 标签组件 │ │ ├── Business/ # 业务组件 │ │ │ ├── ProjectCard.jsx # 项目卡片 │ │ │ ├── StatCard.jsx # 统计卡片 │ │ │ └── UserAvatar.jsx # 用户头像 │ │ └── index.js # 组件导出 │ ├── pages/ # 页面组件 │ │ ├── Login/ # 登录页 │ │ │ └── Login.jsx │ │ ├── Dashboard/ # 仪表盘 │ │ │ └── Dashboard.jsx │ │ ├── Projects/ # 项目管理 │ │ │ ├── ProjectList.jsx # 项目列表 │ │ │ ├── ProjectForm.jsx # 项目表单 │ │ │ ├── ProjectDetail.jsx # 项目详情 │ │ │ └── ProjectStatistics.jsx # 项目统计 │ │ ├── Users/ # 用户管理(仅管理员) │ │ │ ├── UserList.jsx # 用户列表 │ │ │ ├── UserForm.jsx # 用户表单 │ │ │ └── UserResetPassword.jsx # 重置密码 │ │ └── Statistics/ # 统计分析 │ │ └── Statistics.jsx │ ├── contexts/ # Context上下文 │ │ ├── AuthContext.jsx # 认证上下文 │ │ └── ThemeContext.jsx # 主题上下文(可选) │ ├── hooks/ # 自定义Hooks │ │ ├── useAuth.js # 认证Hook │ │ ├── useApi.js # API调用Hook │ │ ├── usePermission.js # 权限检查Hook │ │ ├── useTable.js # 表格Hook │ │ ├── useForm.js # 表单Hook │ │ └── useDebounce.js # 防抖Hook │ ├── services/ # API服务 │ │ ├── api.js # Axios配置 │ │ ├── auth.js # 认证API │ │ ├── user.js # 用户API │ │ ├── project.js # 项目API │ │ └── statistics.js # 统计API │ ├── utils/ # 工具函数 │ │ ├── request.js # 请求封装 │ │ ├── storage.js # 本地存储 │ │ ├── auth.js # 认证工具 │ │ ├── format.js # 格式化函数 │ │ ├── validation.js # 验证函数 │ │ └── constants.js # 常量定义 │ ├── config/ # 配置文件 │ │ ├── routes.js # 路由配置 │ │ ├── menu.js # 菜单配置 │ │ ├── colors.js # 颜色配置 │ │ └── app.config.js # 应用配置 │ ├── router/ # 路由相关 │ │ ├── index.jsx # 路由配置 │ │ ├── PrivateRoute.jsx # 路由守卫 │ │ └── routes.js # 路由定义 │ ├── styles/ # 样式文件 │ │ └── index.css # 主样式文件 │ ├── App.jsx # 根组件 │ └── main.jsx # 应用入口 ├── tests/ # 测试目录 │ ├── components/ # 组件测试 │ ├── pages/ # 页面测试 │ ├── hooks/ # Hooks测试 │ └── utils/ # 工具测试 ├── public/ # 公共资源 │ ├── favicon.ico # 网站图标 │ ├── logo.png # Logo │ └── robots.txt # 爬虫配置 ├── docs/ # 前端文档 │ ├── frontend-architecture.md # 前端技术架构(本文档) │ ├── component-design.md # 组件设计文档 │ ├── api-service.md # API服务封装 │ ├── state-management.md # 状态管理设计 │ ├── routing-design.md # 路由设计文档 │ └── development-guide.md # 开发指南 ├── .env # 环境变量 ├── .env.development # 开发环境变量 ├── .env.production # 生产环境变量 ├── .eslintrc.js # ESLint配置 ├── .prettierrc # Prettier配置 ├── package.json # 项目依赖 ├── vite.config.js # Vite配置 ├── index.html # HTML模板 ├── WORKSTANDARDS.md # 前端工作规范 └── README.md # 前端说明文档 ``` ## 3. 组件架构 ### 3.1 组件层级 ``` App ├── AuthProvider (认证上下文) ├── Router (路由) │ ├── PrivateRoute (路由守卫) │ ├── Login (登录页) │ └── Layout (主布局) │ ├── Header (顶部导航) │ ├── Sidebar (侧边栏) │ └── Content (内容区) │ ├── Dashboard (仪表盘) │ ├── ProjectList (项目列表) │ ├── ProjectForm (项目表单) │ ├── ProjectDetail (项目详情) │ ├── UserList (用户列表) │ ├── UserForm (用户表单) │ └── Statistics (统计页) ``` ### 3.2 组件设计原则 #### 3.2.1 单一职责原则 - 每个组件只负责一个功能 - 避免组件过大,合理拆分 #### 3.2.2 组件复用性 - 提取可复用的通用组件到 `components/Common/` - 提取业务相关组件到 `components/Business/` #### 3.2.3 组件分类 - **布局组件**: Layout, Header, Sidebar - **通用组件**: Button, Input, Form, Modal, Table - **业务组件**: ProjectCard, StatCard, UserAvatar - **页面组件**: Login, Dashboard, ProjectList等 #### 3.2.4 组件Props规范 ```jsx // 推荐的Props定义方式 const MyComponent = ({ title, // 必填props value, // 可选props onChange, // 事件回调 className, // 样式类名 style, // 内联样式 children, // 子元素 }) => { return
{title}
; }; MyComponent.propTypes = { title: PropTypes.string.isRequired, value: PropTypes.string, onChange: PropTypes.func, className: PropTypes.string, style: PropTypes.object, children: PropTypes.node, }; MyComponent.defaultProps = { value: '', onChange: () => {}, className: '', style: {}, }; ``` ## 4. 状态管理 ### 4.1 Context API方案 #### 4.1.1 AuthContext(认证上下文) ```javascript // contexts/AuthContext.jsx const AuthContext = createContext(); export const AuthProvider = ({ children }) => { const [user, setUser] = useState(null); const [token, setToken] = useState(null); const [loading, setLoading] = useState(true); // 登录 const login = async (username, password) => { // 登录逻辑 }; // 登出 const logout = () => { // 登出逻辑 }; // 检查登录状态 const checkAuth = async () => { // 检查逻辑 }; return ( {children} ); }; ``` #### 4.1.2 ThemeContext(主题上下文,可选) ```javascript // contexts/ThemeContext.jsx const ThemeContext = createContext(); export const ThemeProvider = ({ children }) => { const [theme, setTheme] = useState('light'); const toggleTheme = () => { setTheme(prev => prev === 'light' ? 'dark' : 'light'); }; return ( {children} ); }; ``` ### 4.2 本地状态管理 - 使用 `useState` 管理组件内部状态 - 使用 `useReducer` 管理复杂的状态逻辑 ### 4.3 表单状态管理 - 使用 Ant Design Form 组件 - 使用 `react-hook-form`(可选) ## 5. 路由设计 ### 5.1 路由配置 ```javascript // router/routes.js const routes = [ { path: '/login', element: , meta: { title: '登录', requiresAuth: false }, }, { path: '/', element: , meta: { title: '主页', requiresAuth: true }, children: [ { path: '/dashboard', element: , meta: { title: '仪表盘', icon: 'DashboardOutlined' }, }, { path: '/projects', element: , meta: { title: '项目管理', icon: 'FileTextOutlined' }, }, { path: '/projects/create', element: , meta: { title: '创建项目' }, }, { path: '/projects/:id', element: , meta: { title: '项目详情' }, }, { path: '/projects/:id/edit', element: , meta: { title: '编辑项目' }, }, { path: '/users', element: , meta: { title: '用户管理', icon: 'UserOutlined', requiresRole: ['admin'] }, }, { path: '/users/create', element: , meta: { title: '创建用户', requiresRole: ['admin'] }, }, { path: '/statistics', element: , meta: { title: '统计分析', icon: 'BarChartOutlined' }, }, ], }, ]; ``` ### 5.2 路由守卫 ```javascript // router/PrivateRoute.jsx const PrivateRoute = ({ children, requiresAuth, requiresRole }) => { const { isAuthenticated, user } = useAuth(); const navigate = useNavigate(); if (requiresAuth && !isAuthenticated) { return ; } if (requiresRole && !requiresRole.includes(user?.role)) { return ; } return children; }; ``` ## 6. API服务封装 ### 6.1 Axios配置 ```javascript // services/api.js import axios from 'axios'; import { message } from 'antd'; const api = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:5000/api/v1', timeout: 10000, headers: { 'Content-Type': 'application/json', }, }); // 请求拦截器 api.interceptors.request.use( (config) => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, (error) => { return Promise.reject(error); } ); // 响应拦截器 api.interceptors.response.use( (response) => { return response.data; }, (error) => { if (error.response) { const { status, data } = error.response; switch (status) { case 401: message.error('登录已过期,请重新登录'); localStorage.removeItem('token'); window.location.href = '/login'; break; case 403: message.error('权限不足'); break; case 404: message.error('请求的资源不存在'); break; case 500: message.error('服务器错误'); break; default: message.error(data.message || '请求失败'); } } else { message.error('网络错误,请检查网络连接'); } return Promise.reject(error); } ); export default api; ``` ### 6.2 API模块化 ```javascript // services/project.js import api from './api'; export const projectAPI = { // 获取项目列表 getList: (params) => api.get('/projects', { params }), // 获取项目详情 getDetail: (id) => api.get(`/projects/${id}`), // 创建项目 create: (data) => api.post('/projects', data), // 更新项目 update: (id, data) => api.put(`/projects/${id}`, data), // 删除项目 delete: (id) => api.delete(`/projects/${id}`), // 获取统计信息 getStatistics: (params) => api.get('/projects/statistics', { params }), // 获取分组统计 getGroupStatistics: (params) => api.get('/projects/statistics/group', { params }), // 获取时间维度统计 getTimelineStatistics: (params) => api.get('/projects/statistics/timeline', { params }), }; ``` ## 7. 权限控制 ### 7.1 路由级权限 - 使用 `PrivateRoute` 组件检查认证状态 - 使用 `requiresRole` 属性检查角色权限 ### 7.2 组件级权限 ```javascript // hooks/usePermission.js export const usePermission = () => { const { user } = useAuth(); const hasRole = (roles) => { if (!user) return false; return roles.includes(user.role); }; const canEdit = (resource, createdBy) => { if (!user) return false; if (user.role === 'admin') return true; if (user.role === 'market' && createdBy === user.id) return true; return false; }; return { hasRole, canEdit }; }; ``` ### 7.3 按钮级权限 ```javascript // 组件中使用 const { hasRole } = usePermission(); {hasRole(['admin', 'market']) && ( )} ``` ## 8. 性能优化 ### 8.1 代码分割 ```javascript import { lazy, Suspense } from 'react'; const ProjectList = lazy(() => import('./pages/Projects/ProjectList')); const ProjectDetail = lazy(() => import('./pages/Projects/ProjectDetail')); }> ``` ### 8.2 图片优化 - 使用懒加载 - 压缩图片文件 - 使用WebP格式 ### 8.3 请求优化 - 防抖处理搜索请求 - 取消重复请求 - 使用缓存策略 ### 8.4 渲染优化 - 使用 `React.memo` 避免不必要的重渲染 - 使用 `useMemo` 缓存计算结果 - 使用 `useCallback` 缓存函数引用 ## 9. 前端安全 ### 9.1 XSS防护 - React自动转义HTML - 避免使用 `dangerouslySetInnerHTML` - 输入验证和过滤 ### 9.2 CSRF防护 - 使用Cookie SameSite属性 - 添加CSRF Token(可选) ### 9.3 敏感信息保护 - Token存储在LocalStorage(可改为HttpOnly Cookie) - 不在URL中传递敏感信息 - 使用HTTPS(生产环境) ### 9.4 内容安全策略(CSP) - 设置CSP头部 - 限制外部资源加载 ## 10. 开发规范 ### 10.1 代码风格 - 使用ESLint进行代码检查 - 使用Prettier进行代码格式化 - 遵循Airbnb JavaScript风格指南 ### 10.2 命名规范 - 组件名使用PascalCase(如 `ProjectList`) - 函数和变量使用camelCase(如 `getUserById`) - 常量使用UPPER_SNAKE_CASE(如 `API_BASE_URL`) - CSS类名使用kebab-case(如 `project-card`) ### 10.3 注释规范 ```javascript /** * 获取项目列表 * @param {Object} params - 查询参数 * @param {number} params.page - 页码 * @param {number} params.pageSize - 每页数量 * @returns {Promise} 项目列表数据 */ const getProjectList = async (params) => { // 实现代码 }; ``` ### 10.4 Git提交规范 ``` [frontend] feat: 添加项目列表页面 [frontend] fix: 修复登录bug [frontend] style: 优化代码格式 [frontend] refactor: 重构API服务 [frontend] test: 添加组件测试 [frontend] docs: 更新文档 [frontend] chore: 更新依赖 ``` ## 11. 测试策略 ### 11.1 单元测试 - 测试工具函数和自定义Hooks - 使用Vitest测试框架 ### 11.2 组件测试 - 测试组件渲染和交互 - 使用React Testing Library ### 11.3 集成测试 - 测试页面和路由 - 测试API调用 ### 11.4 E2E测试(可选) - 测试完整用户流程 - 使用Playwright ## 12. 部署方案 ### 12.1 开发环境 ```bash npm run dev # 访问 http://localhost:3000 ``` ### 12.2 生产构建 ```bash npm run build # 生成 dist 目录 ``` ### 12.3 Docker部署 ```dockerfile # Dockerfile FROM node:18-alpine as builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ``` ### 12.4 Nginx配置 ```nginx server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://backend:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` ## 13. 相关文档 - [组件设计文档](component-design.md) - 详细的组件设计规范 - [API服务封装](api-service.md) - API服务封装详解 - [状态管理设计](state-management.md) - 状态管理方案详解 - [路由设计文档](routing-design.md) - 路由设计详解 - [开发指南](development-guide.md) - 前端开发指南 --- **文档维护**: 前端程序员 **文档类型**: 前端技术架构文档 **最后更新**: 2026-01-25