删除废弃的API和架构文档
This commit is contained in:
1779
docs/development/API接口文档.md
Normal file
1779
docs/development/API接口文档.md
Normal file
File diff suppressed because it is too large
Load Diff
594
docs/development/CONTRIBUTING.md
Normal file
594
docs/development/CONTRIBUTING.md
Normal file
@@ -0,0 +1,594 @@
|
||||
# 贡献指南
|
||||
|
||||
## 欢迎贡献
|
||||
|
||||
我们热烈欢迎社区开发者为宁夏智慧养殖监管平台做出贡献!无论您是想修复bug、添加新功能、改进文档,还是提供反馈建议,我们都非常感谢您的参与。
|
||||
|
||||
## 目录
|
||||
|
||||
- [开始之前](#开始之前)
|
||||
- [如何贡献](#如何贡献)
|
||||
- [开发环境搭建](#开发环境搭建)
|
||||
- [代码贡献流程](#代码贡献流程)
|
||||
- [代码规范](#代码规范)
|
||||
- [提交规范](#提交规范)
|
||||
- [Pull Request 指南](#pull-request-指南)
|
||||
- [问题报告](#问题报告)
|
||||
- [文档贡献](#文档贡献)
|
||||
- [社区行为准则](#社区行为准则)
|
||||
|
||||
## 开始之前
|
||||
|
||||
### 阅读项目文档
|
||||
在开始贡献之前,请确保您已经阅读并理解了以下文档:
|
||||
- [README.md](README.md) - 项目概述
|
||||
- [DEVELOPMENT.md](DEVELOPMENT.md) - 开发指南
|
||||
- [API.md](API.md) - API 文档
|
||||
- [架构文档](arch.md) - 系统架构
|
||||
|
||||
### 了解项目状态
|
||||
- 查看 [Issues](https://github.com/your-org/nxxmdata/issues) 了解当前需要解决的问题
|
||||
- 查看 [Projects](https://github.com/your-org/nxxmdata/projects) 了解项目路线图
|
||||
- 查看 [CHANGELOG.md](CHANGELOG.md) 了解最新变更
|
||||
|
||||
## 如何贡献
|
||||
|
||||
您可以通过以下方式为项目做出贡献:
|
||||
|
||||
### 🐛 报告 Bug
|
||||
- 发现了系统错误或异常行为
|
||||
- 遇到了文档中的错误或不清楚的地方
|
||||
- 发现了安全漏洞(请通过私密渠道报告)
|
||||
|
||||
### 💡 提出功能建议
|
||||
- 提出新的功能想法
|
||||
- 建议改进现有功能
|
||||
- 提出用户体验优化建议
|
||||
|
||||
### 📝 改进文档
|
||||
- 修复文档中的错误
|
||||
- 添加缺失的文档
|
||||
- 改进文档的清晰度和准确性
|
||||
- 翻译文档到其他语言
|
||||
|
||||
### 💻 贡献代码
|
||||
- 修复已知的 bug
|
||||
- 实现新功能
|
||||
- 优化性能
|
||||
- 重构代码
|
||||
- 添加测试用例
|
||||
|
||||
### 🎨 设计贡献
|
||||
- 改进用户界面设计
|
||||
- 提供图标和图片资源
|
||||
- 优化用户体验
|
||||
|
||||
## 开发环境搭建
|
||||
|
||||
### 前置要求
|
||||
- Node.js 18.0+
|
||||
- npm 8.0+ 或 yarn 1.22+
|
||||
- MySQL 8.0+
|
||||
- Git 2.25+
|
||||
|
||||
### 克隆项目
|
||||
```bash
|
||||
# 1. Fork 项目到您的 GitHub 账户
|
||||
# 2. 克隆您的 fork
|
||||
git clone https://github.com/YOUR_USERNAME/nxxmdata.git
|
||||
cd nxxmdata
|
||||
|
||||
# 3. 添加上游仓库
|
||||
git remote add upstream https://github.com/original-org/nxxmdata.git
|
||||
```
|
||||
|
||||
### 安装依赖
|
||||
```bash
|
||||
# 后端依赖
|
||||
cd backend
|
||||
npm install
|
||||
|
||||
# 前端依赖
|
||||
cd ../admin-system/frontend
|
||||
npm install
|
||||
|
||||
cd ../../website/data-screen
|
||||
npm install
|
||||
|
||||
# 微信小程序依赖(可选)
|
||||
cd ../../mini_program/farm-monitor-dashboard
|
||||
npm install
|
||||
```
|
||||
|
||||
### 配置环境
|
||||
```bash
|
||||
# 复制环境配置文件
|
||||
cd backend
|
||||
cp .env.example .env
|
||||
|
||||
cd ../admin-system/frontend
|
||||
cp .env.example .env
|
||||
|
||||
# 编辑配置文件,设置数据库连接等信息
|
||||
```
|
||||
|
||||
### 初始化数据库
|
||||
```bash
|
||||
cd backend
|
||||
# 创建数据库
|
||||
mysql -u root -p -e "CREATE DATABASE nxxmdata CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||
|
||||
# 运行迁移
|
||||
npm run db:migrate
|
||||
|
||||
# 填充种子数据
|
||||
npm run db:seed
|
||||
```
|
||||
|
||||
### 启动开发服务器
|
||||
```bash
|
||||
# 启动后端服务
|
||||
cd backend
|
||||
npm run dev
|
||||
|
||||
# 启动前端服务(新终端)
|
||||
cd admin-system/frontend
|
||||
npm run dev
|
||||
|
||||
# 启动官网大屏(新终端)
|
||||
cd website/data-screen
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## 代码贡献流程
|
||||
|
||||
### 1. 选择或创建 Issue
|
||||
- 查看现有的 [Issues](https://github.com/your-org/nxxmdata/issues)
|
||||
- 选择标记为 `good first issue` 的问题(适合新手)
|
||||
- 如果是新功能,请先创建 Issue 讨论
|
||||
|
||||
### 2. 创建分支
|
||||
```bash
|
||||
# 更新主分支
|
||||
git checkout main
|
||||
git pull upstream main
|
||||
|
||||
# 创建功能分支
|
||||
git checkout -b feature/your-feature-name
|
||||
# 或者修复分支
|
||||
git checkout -b fix/bug-description
|
||||
```
|
||||
|
||||
### 3. 开发代码
|
||||
- 编写代码
|
||||
- 添加或更新测试
|
||||
- 更新相关文档
|
||||
- 确保代码符合项目规范
|
||||
|
||||
### 4. 测试代码
|
||||
```bash
|
||||
# 运行单元测试
|
||||
npm test
|
||||
|
||||
# 运行集成测试
|
||||
npm run test:integration
|
||||
|
||||
# 运行端到端测试
|
||||
npm run test:e2e
|
||||
|
||||
# 检查代码风格
|
||||
npm run lint
|
||||
|
||||
# 修复代码风格问题
|
||||
npm run lint:fix
|
||||
```
|
||||
|
||||
### 5. 提交代码
|
||||
```bash
|
||||
# 添加变更文件
|
||||
git add .
|
||||
|
||||
# 提交代码(遵循提交信息规范)
|
||||
git commit -m "feat: add user profile management feature"
|
||||
|
||||
# 推送到您的 fork
|
||||
git push origin feature/your-feature-name
|
||||
```
|
||||
|
||||
### 6. 创建 Pull Request
|
||||
- 在 GitHub 上创建 Pull Request
|
||||
- 填写 PR 模板中的所有必要信息
|
||||
- 等待代码审查
|
||||
|
||||
## 代码规范
|
||||
|
||||
### JavaScript/TypeScript 规范
|
||||
|
||||
#### 命名约定
|
||||
```javascript
|
||||
// 变量和函数使用 camelCase
|
||||
const userName = 'john_doe';
|
||||
function getUserInfo() {}
|
||||
|
||||
// 常量使用 UPPER_SNAKE_CASE
|
||||
const API_BASE_URL = 'http://localhost:5350';
|
||||
|
||||
// 类名使用 PascalCase
|
||||
class UserService {}
|
||||
|
||||
// 文件名使用 kebab-case
|
||||
// user-service.js, farm-detail.vue
|
||||
```
|
||||
|
||||
#### 代码风格
|
||||
```javascript
|
||||
// 使用 const/let,避免 var
|
||||
const config = {...};
|
||||
let mutableData = [];
|
||||
|
||||
// 使用箭头函数
|
||||
const processData = (data) => {
|
||||
return data.map(item => item.value);
|
||||
};
|
||||
|
||||
// 使用模板字符串
|
||||
const message = `Hello, ${userName}!`;
|
||||
|
||||
// 使用对象解构
|
||||
const { name, email } = user;
|
||||
|
||||
// 使用扩展运算符
|
||||
const newArray = [...oldArray, newItem];
|
||||
```
|
||||
|
||||
#### 错误处理
|
||||
```javascript
|
||||
// 使用 try-catch 处理异步错误
|
||||
try {
|
||||
const result = await api.fetchData();
|
||||
return result;
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch data:', error);
|
||||
throw new Error('Data fetch failed');
|
||||
}
|
||||
|
||||
// 返回 Promise 的函数应该处理所有可能的错误
|
||||
async function createUser(userData) {
|
||||
try {
|
||||
const user = await User.create(userData);
|
||||
return { success: true, data: user };
|
||||
} catch (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Vue.js 组件规范
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="component-name">
|
||||
<!-- 使用语义化的 HTML 标签 -->
|
||||
<header class="component-header">
|
||||
<h1>{{ title }}</h1>
|
||||
</header>
|
||||
|
||||
<!-- 事件处理使用 handle 前缀 -->
|
||||
<button @click="handleSubmit">提交</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'ComponentName', // 组件名使用 PascalCase
|
||||
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['submit'],
|
||||
|
||||
setup(props, { emit }) {
|
||||
// 响应式数据
|
||||
const isLoading = ref(false)
|
||||
|
||||
// 计算属性
|
||||
const displayTitle = computed(() => {
|
||||
return props.title.toUpperCase()
|
||||
})
|
||||
|
||||
// 方法
|
||||
const handleSubmit = () => {
|
||||
emit('submit')
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
// 初始化逻辑
|
||||
})
|
||||
|
||||
return {
|
||||
isLoading,
|
||||
displayTitle,
|
||||
handleSubmit
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.component-name {
|
||||
/* 使用 BEM 命名法 */
|
||||
}
|
||||
|
||||
.component-header {
|
||||
/* 样式规则 */
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### CSS/SCSS 规范
|
||||
|
||||
```css
|
||||
/* 使用 BEM 命名法 */
|
||||
.block {}
|
||||
.block__element {}
|
||||
.block--modifier {}
|
||||
|
||||
/* 使用语义化的类名 */
|
||||
.button--primary {}
|
||||
.form__input--error {}
|
||||
|
||||
/* 避免深层嵌套 */
|
||||
.component {
|
||||
.header {} /* 最多 3 层嵌套 */
|
||||
}
|
||||
```
|
||||
|
||||
## 提交规范
|
||||
|
||||
我们使用 [Conventional Commits](https://www.conventionalcommits.org/) 规范:
|
||||
|
||||
### 提交消息格式
|
||||
```
|
||||
<type>(<scope>): <description>
|
||||
|
||||
[optional body]
|
||||
|
||||
[optional footer(s)]
|
||||
```
|
||||
|
||||
### 类型 (type)
|
||||
- `feat`: 新增功能
|
||||
- `fix`: 修复 bug
|
||||
- `docs`: 文档更新
|
||||
- `style`: 代码格式调整(不影响代码逻辑)
|
||||
- `refactor`: 重构(既不是新增功能也不是修复 bug)
|
||||
- `perf`: 性能优化
|
||||
- `test`: 添加或修改测试
|
||||
- `chore`: 构建过程或辅助工具的变动
|
||||
- `ci`: CI/CD 相关变更
|
||||
|
||||
### 范围 (scope)
|
||||
- `api`: API 相关
|
||||
- `ui`: 用户界面
|
||||
- `auth`: 认证相关
|
||||
- `db`: 数据库相关
|
||||
- `config`: 配置相关
|
||||
|
||||
### 示例
|
||||
```bash
|
||||
feat(api): add user profile update endpoint
|
||||
fix(ui): resolve map display issue on mobile devices
|
||||
docs(readme): update installation instructions
|
||||
style(frontend): format code with prettier
|
||||
refactor(auth): simplify token validation logic
|
||||
perf(db): optimize farm data query performance
|
||||
test(api): add unit tests for user controller
|
||||
chore(deps): update vue to version 3.4.0
|
||||
```
|
||||
|
||||
### 破坏性变更
|
||||
```bash
|
||||
feat(api)!: change user authentication method
|
||||
|
||||
BREAKING CHANGE: JWT token format has changed
|
||||
```
|
||||
|
||||
## Pull Request 指南
|
||||
|
||||
### PR 标题
|
||||
PR 标题应该简洁明了地描述变更内容,遵循提交信息规范:
|
||||
```
|
||||
feat(user): add profile management feature
|
||||
fix(map): resolve coordinate display issue
|
||||
docs: update API documentation
|
||||
```
|
||||
|
||||
### PR 描述模板
|
||||
```markdown
|
||||
## 变更类型
|
||||
- [ ] Bug 修复
|
||||
- [ ] 新功能
|
||||
- [ ] 文档更新
|
||||
- [ ] 代码重构
|
||||
- [ ] 性能优化
|
||||
- [ ] 其他: ____________
|
||||
|
||||
## 变更描述
|
||||
<!-- 简要描述这个 PR 的变更内容 -->
|
||||
|
||||
## 相关 Issue
|
||||
<!-- 如果有相关的 Issue,请在此链接 -->
|
||||
Closes #123
|
||||
|
||||
## 测试
|
||||
- [ ] 我已经测试了我的代码
|
||||
- [ ] 我已经添加了测试用例
|
||||
- [ ] 所有测试都通过了
|
||||
|
||||
## 检查清单
|
||||
- [ ] 我的代码遵循项目的代码规范
|
||||
- [ ] 我已经进行了自我代码审查
|
||||
- [ ] 我已经添加了必要的注释
|
||||
- [ ] 我已经更新了相关文档
|
||||
- [ ] 我的变更不会产生新的警告
|
||||
- [ ] 我已经添加了适当的测试
|
||||
- [ ] 新功能和修复都有对应的测试
|
||||
|
||||
## 截图(如果适用)
|
||||
<!-- 如果是 UI 相关的变更,请添加截图 -->
|
||||
|
||||
## 额外说明
|
||||
<!-- 任何其他需要说明的内容 -->
|
||||
```
|
||||
|
||||
### 代码审查
|
||||
- 所有 PR 都需要至少一个审查者的批准
|
||||
- 解决所有审查意见后才能合并
|
||||
- 保持代码变更的原子性和逻辑性
|
||||
- 确保 CI/CD 检查通过
|
||||
|
||||
## 问题报告
|
||||
|
||||
### Bug 报告
|
||||
使用 Bug 报告模板创建 Issue:
|
||||
|
||||
```markdown
|
||||
**问题描述**
|
||||
简要描述遇到的问题。
|
||||
|
||||
**复现步骤**
|
||||
1. 进入 '...'
|
||||
2. 点击 '....'
|
||||
3. 滚动到 '....'
|
||||
4. 看到错误
|
||||
|
||||
**预期行为**
|
||||
描述您期望发生的行为。
|
||||
|
||||
**实际行为**
|
||||
描述实际发生的行为。
|
||||
|
||||
**截图**
|
||||
如果适用,添加截图来帮助解释您的问题。
|
||||
|
||||
**环境信息:**
|
||||
- 操作系统: [例如 macOS 12.0]
|
||||
- 浏览器: [例如 Chrome 95.0]
|
||||
- Node.js 版本: [例如 18.12.0]
|
||||
- 项目版本: [例如 1.2.0]
|
||||
|
||||
**附加信息**
|
||||
添加任何其他有关问题的信息。
|
||||
```
|
||||
|
||||
### 功能请求
|
||||
```markdown
|
||||
**功能描述**
|
||||
简要描述您想要的功能。
|
||||
|
||||
**问题解决**
|
||||
这个功能解决了什么问题?
|
||||
|
||||
**解决方案**
|
||||
描述您想要的解决方案。
|
||||
|
||||
**备选方案**
|
||||
描述您考虑过的任何备选解决方案或功能。
|
||||
|
||||
**附加信息**
|
||||
添加任何其他关于功能请求的信息或截图。
|
||||
```
|
||||
|
||||
## 文档贡献
|
||||
|
||||
### 文档类型
|
||||
- **用户文档**: README, 安装指南, 使用教程
|
||||
- **开发者文档**: API 文档, 开发指南, 架构文档
|
||||
- **运维文档**: 部署指南, 故障排除, 监控指南
|
||||
|
||||
### 文档写作规范
|
||||
- 使用清晰、简洁的语言
|
||||
- 提供具体的示例和代码片段
|
||||
- 包含必要的截图和图表
|
||||
- 保持文档的时效性
|
||||
- 使用统一的格式和风格
|
||||
|
||||
### 文档更新流程
|
||||
1. 识别需要更新的文档
|
||||
2. 创建文档分支 `docs/update-api-guide`
|
||||
3. 更新文档内容
|
||||
4. 提交并创建 PR
|
||||
5. 经过审查后合并
|
||||
|
||||
## 社区行为准则
|
||||
|
||||
### 我们的承诺
|
||||
为了营造一个开放和受欢迎的环境,我们作为贡献者和维护者承诺:无论年龄、体型、身体健全或残疾、民族、性别特征、性别认同和表达、经验水平、教育程度、社会经济地位、国籍、外貌、种族、宗教或性取向如何,参与我们项目和社区的每个人都享有无骚扰的体验。
|
||||
|
||||
### 我们的标准
|
||||
有助于创造积极环境的行为包括:
|
||||
- 使用受欢迎和包容性的语言
|
||||
- 尊重不同的观点和经验
|
||||
- 优雅地接受建设性批评
|
||||
- 关注对社区最有利的事情
|
||||
- 对其他社区成员表示同情
|
||||
|
||||
不可接受的行为包括:
|
||||
- 使用性化的语言或图像以及不受欢迎的性关注或求爱
|
||||
- 捣乱、侮辱/贬损评论以及个人或政治攻击
|
||||
- 公开或私下骚扰
|
||||
- 未经明确许可发布他人的私人信息
|
||||
- 在专业环境中可能被合理认为不适当的其他行为
|
||||
|
||||
### 报告
|
||||
如果您遇到不当行为,请联系项目团队:
|
||||
- 邮箱: conduct@nxxmdata.com
|
||||
- 我们将认真对待所有报告并进行调查
|
||||
|
||||
## 获得帮助
|
||||
|
||||
### 联系方式
|
||||
- **技术问题**: 在 GitHub Issues 中提问
|
||||
- **功能讨论**: 在 GitHub Discussions 中讨论
|
||||
- **安全问题**: 发送邮件到 security@nxxmdata.com
|
||||
- **其他问题**: 发送邮件到 hello@nxxmdata.com
|
||||
|
||||
### 社区资源
|
||||
- [GitHub 仓库](https://github.com/your-org/nxxmdata)
|
||||
- [项目文档](https://docs.nxxmdata.com)
|
||||
- [API 文档](https://api.nxxmdata.com/docs)
|
||||
|
||||
## 认可贡献者
|
||||
|
||||
我们感谢所有为项目做出贡献的人!贡献者将被列在:
|
||||
- [CONTRIBUTORS.md](CONTRIBUTORS.md) 文件中
|
||||
- 项目的 README 中
|
||||
- 每次发布的致谢中
|
||||
|
||||
### 贡献类型
|
||||
我们认可以下类型的贡献:
|
||||
- 💻 代码贡献
|
||||
- 📖 文档贡献
|
||||
- 🎨 设计贡献
|
||||
- 🐛 Bug 报告
|
||||
- 💡 想法和建议
|
||||
- 🤔 答疑解惑
|
||||
- 📢 推广项目
|
||||
|
||||
## 许可证
|
||||
|
||||
通过向此项目贡献代码,您同意您的贡献将在与项目相同的许可证下被许可。
|
||||
|
||||
---
|
||||
|
||||
再次感谢您对宁夏智慧养殖监管平台的关注和贡献!我们期待与您一起构建更好的系统。
|
||||
|
||||
*最后更新: 2025年1月*
|
||||
108
docs/development/examples/performance-monitor-integration.js
Normal file
108
docs/development/examples/performance-monitor-integration.js
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* 性能监控系统集成示例
|
||||
* @file performance-monitor-integration.js
|
||||
* @description 演示如何在Express应用中集成性能监控系统
|
||||
*/
|
||||
const express = require('express');
|
||||
const { initPerformanceMonitoring, getPerformanceRoutes } = require('../backend/config/performance-config');
|
||||
const logger = require('../backend/utils/logger');
|
||||
|
||||
// 创建Express应用
|
||||
const app = express();
|
||||
|
||||
// 配置中间件
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
|
||||
// 初始化性能监控系统
|
||||
const performanceMonitor = initPerformanceMonitoring(app, {
|
||||
autoStart: true,
|
||||
interval: 30000, // 30秒监控间隔
|
||||
logToConsole: true,
|
||||
thresholds: {
|
||||
system: {
|
||||
cpuUsage: 75, // CPU使用率阈值(百分比)
|
||||
memoryUsage: 80, // 内存使用率阈值(百分比)
|
||||
diskUsage: 85 // 磁盘使用率阈值(百分比)
|
||||
},
|
||||
database: {
|
||||
connectionPoolUtilization: 70, // 连接池利用率阈值(百分比)
|
||||
slowQueryCount: 3, // 慢查询数量阈值
|
||||
errorRate: 2 // 错误率阈值(百分比)
|
||||
},
|
||||
api: {
|
||||
responseTime: 300, // API响应时间阈值(毫秒)
|
||||
errorRate: 1, // API错误率阈值(百分比)
|
||||
requestRate: 500 // 每分钟请求数阈值
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 注册性能监控路由
|
||||
app.use('/api/performance', getPerformanceRoutes());
|
||||
|
||||
// 示例API路由
|
||||
app.get('/api/users', (req, res) => {
|
||||
// 模拟数据库操作延迟
|
||||
setTimeout(() => {
|
||||
res.json({ users: [{ id: 1, name: '张三' }, { id: 2, name: '李四' }] });
|
||||
}, 50);
|
||||
});
|
||||
|
||||
app.get('/api/products', (req, res) => {
|
||||
// 模拟数据库操作延迟
|
||||
setTimeout(() => {
|
||||
res.json({ products: [{ id: 1, name: '产品A' }, { id: 2, name: '产品B' }] });
|
||||
}, 30);
|
||||
});
|
||||
|
||||
// 模拟慢响应API
|
||||
app.get('/api/reports', (req, res) => {
|
||||
// 模拟耗时操作
|
||||
setTimeout(() => {
|
||||
res.json({ report: { id: 1, data: '报表数据...' } });
|
||||
}, 600); // 超过阈值的响应时间
|
||||
});
|
||||
|
||||
// 模拟错误API
|
||||
app.get('/api/error', (req, res) => {
|
||||
res.status(500).json({ error: '服务器内部错误' });
|
||||
});
|
||||
|
||||
// 错误处理中间件
|
||||
app.use((err, req, res, next) => {
|
||||
logger.error('应用错误:', err);
|
||||
res.status(500).json({ error: '服务器内部错误', message: err.message });
|
||||
});
|
||||
|
||||
// 启动服务器
|
||||
const PORT = process.env.PORT || 3000;
|
||||
app.listen(PORT, () => {
|
||||
logger.info(`服务器已启动,监听端口 ${PORT}`);
|
||||
logger.info('性能监控系统已集成');
|
||||
|
||||
// 输出性能监控访问信息
|
||||
logger.info('性能监控API:');
|
||||
logger.info('- 获取所有指标: GET /api/performance/metrics');
|
||||
logger.info('- 获取系统指标: GET /api/performance/system');
|
||||
logger.info('- 获取数据库指标: GET /api/performance/database');
|
||||
logger.info('- 获取API指标: GET /api/performance/api');
|
||||
logger.info('- 获取监控状态: GET /api/performance/status');
|
||||
});
|
||||
|
||||
// 优雅关闭
|
||||
process.on('SIGTERM', shutdown);
|
||||
process.on('SIGINT', shutdown);
|
||||
|
||||
function shutdown() {
|
||||
logger.info('正在关闭应用...');
|
||||
|
||||
// 停止性能监控
|
||||
performanceMonitor.stopMonitoring();
|
||||
|
||||
// 关闭服务器
|
||||
server.close(() => {
|
||||
logger.info('HTTP服务器已关闭');
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
599
docs/development/代码规范.md
Normal file
599
docs/development/代码规范.md
Normal file
@@ -0,0 +1,599 @@
|
||||
# 宁夏智慧养殖监管平台代码规范
|
||||
|
||||
## 版本历史
|
||||
|
||||
| 版本 | 日期 | 修改内容 | 修改人 |
|
||||
|------|------|----------|--------|
|
||||
| v1.0 | 2024-01-20 | 初始版本,制定基础代码规范 | 开发团队 |
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档规定了宁夏智慧养殖监管平台项目的代码编写规范,旨在提高代码质量、可读性和可维护性。
|
||||
|
||||
## 2. 通用规范
|
||||
|
||||
### 2.1 文件命名
|
||||
- **文件名**: 使用小写字母和连字符,如 `user-service.js`
|
||||
- **目录名**: 使用小写字母和连字符,如 `user-management`
|
||||
- **组件文件**: 使用 PascalCase,如 `UserProfile.vue`
|
||||
|
||||
### 2.2 编码格式
|
||||
- **字符编码**: UTF-8
|
||||
- **换行符**: LF (Unix)
|
||||
- **缩进**: 2个空格
|
||||
- **行尾**: 不允许有多余空格
|
||||
|
||||
### 2.3 注释规范
|
||||
```javascript
|
||||
/**
|
||||
* 函数功能描述
|
||||
* @param {string} param1 - 参数1描述
|
||||
* @param {number} param2 - 参数2描述
|
||||
* @returns {boolean} 返回值描述
|
||||
* @author 作者名
|
||||
* @since 版本号
|
||||
*/
|
||||
function exampleFunction(param1, param2) {
|
||||
// 单行注释说明
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
## 3. JavaScript/Node.js 规范
|
||||
|
||||
### 3.1 变量命名
|
||||
```javascript
|
||||
// 使用 camelCase
|
||||
const userName = 'admin';
|
||||
const userAge = 25;
|
||||
|
||||
// 常量使用 UPPER_SNAKE_CASE
|
||||
const MAX_RETRY_COUNT = 3;
|
||||
const API_BASE_URL = 'https://api.example.com';
|
||||
|
||||
// 私有变量使用下划线前缀
|
||||
const _privateVariable = 'private';
|
||||
```
|
||||
|
||||
### 3.2 函数定义
|
||||
```javascript
|
||||
// 优先使用箭头函数
|
||||
const getUserInfo = (userId) => {
|
||||
return userService.findById(userId);
|
||||
};
|
||||
|
||||
// 异步函数
|
||||
const fetchUserData = async (userId) => {
|
||||
try {
|
||||
const user = await userService.findById(userId);
|
||||
return user;
|
||||
} catch (error) {
|
||||
logger.error('获取用户数据失败', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 3.3 对象和数组
|
||||
```javascript
|
||||
// 对象属性换行
|
||||
const userConfig = {
|
||||
name: 'admin',
|
||||
role: 'administrator',
|
||||
permissions: ['read', 'write', 'delete'],
|
||||
settings: {
|
||||
theme: 'dark',
|
||||
language: 'zh-CN'
|
||||
}
|
||||
};
|
||||
|
||||
// 数组解构
|
||||
const [first, second, ...rest] = items;
|
||||
|
||||
// 对象解构
|
||||
const { name, age, ...otherProps } = user;
|
||||
```
|
||||
|
||||
### 3.4 错误处理
|
||||
```javascript
|
||||
// 统一错误处理
|
||||
const handleApiError = (error) => {
|
||||
if (error.response) {
|
||||
// 服务器响应错误
|
||||
logger.error('API响应错误', {
|
||||
status: error.response.status,
|
||||
data: error.response.data
|
||||
});
|
||||
} else if (error.request) {
|
||||
// 请求发送失败
|
||||
logger.error('请求发送失败', error.request);
|
||||
} else {
|
||||
// 其他错误
|
||||
logger.error('未知错误', error.message);
|
||||
}
|
||||
throw error;
|
||||
};
|
||||
```
|
||||
|
||||
## 4. Vue.js 规范
|
||||
|
||||
### 4.1 组件命名
|
||||
```javascript
|
||||
// 组件名使用 PascalCase
|
||||
export default {
|
||||
name: 'UserProfile',
|
||||
// ...
|
||||
}
|
||||
|
||||
// 文件名: UserProfile.vue
|
||||
```
|
||||
|
||||
### 4.2 组件结构
|
||||
```vue
|
||||
<template>
|
||||
<div class="user-profile">
|
||||
<!-- 模板内容 -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'UserProfile',
|
||||
props: {
|
||||
userId: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
emits: ['update', 'delete'],
|
||||
setup(props, { emit }) {
|
||||
// 响应式数据
|
||||
const user = ref(null)
|
||||
|
||||
// 计算属性
|
||||
const displayName = computed(() => {
|
||||
return user.value ? user.value.name : '未知用户'
|
||||
})
|
||||
|
||||
// 方法
|
||||
const loadUser = async () => {
|
||||
try {
|
||||
user.value = await userApi.getById(props.userId)
|
||||
} catch (error) {
|
||||
console.error('加载用户失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
loadUser()
|
||||
})
|
||||
|
||||
return {
|
||||
user,
|
||||
displayName,
|
||||
loadUser
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.user-profile {
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 4.3 Props 定义
|
||||
```javascript
|
||||
props: {
|
||||
// 基础类型检查
|
||||
title: String,
|
||||
count: Number,
|
||||
isActive: Boolean,
|
||||
|
||||
// 复杂类型检查
|
||||
user: {
|
||||
type: Object,
|
||||
required: true,
|
||||
validator: (value) => {
|
||||
return value && typeof value.id === 'string'
|
||||
}
|
||||
},
|
||||
|
||||
// 带默认值
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium',
|
||||
validator: (value) => {
|
||||
return ['small', 'medium', 'large'].includes(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.4 事件命名
|
||||
```javascript
|
||||
// 使用 kebab-case
|
||||
this.$emit('user-updated', userData)
|
||||
this.$emit('form-submitted', formData)
|
||||
|
||||
// 在模板中
|
||||
<UserForm @user-updated="handleUserUpdate" />
|
||||
```
|
||||
|
||||
## 5. CSS/SCSS 规范
|
||||
|
||||
### 5.1 类名命名
|
||||
```css
|
||||
/* 使用 BEM 命名法 */
|
||||
.user-profile {
|
||||
/* 块 */
|
||||
}
|
||||
|
||||
.user-profile__header {
|
||||
/* 元素 */
|
||||
}
|
||||
|
||||
.user-profile__header--large {
|
||||
/* 修饰符 */
|
||||
}
|
||||
|
||||
.user-profile__avatar {
|
||||
/* 元素 */
|
||||
}
|
||||
|
||||
.user-profile__avatar--round {
|
||||
/* 修饰符 */
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 样式组织
|
||||
```scss
|
||||
// 变量定义
|
||||
$primary-color: #1890ff;
|
||||
$success-color: #52c41a;
|
||||
$warning-color: #faad14;
|
||||
$error-color: #f5222d;
|
||||
|
||||
// 混入定义
|
||||
@mixin flex-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 组件样式
|
||||
.user-profile {
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
|
||||
&__header {
|
||||
@include flex-center;
|
||||
margin-bottom: 16px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&__content {
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 6. API 接口规范
|
||||
|
||||
### 6.1 接口命名
|
||||
```javascript
|
||||
// RESTful API 命名
|
||||
GET /api/users // 获取用户列表
|
||||
GET /api/users/:id // 获取单个用户
|
||||
POST /api/users // 创建用户
|
||||
PUT /api/users/:id // 更新用户
|
||||
DELETE /api/users/:id // 删除用户
|
||||
|
||||
// 复杂操作使用动词
|
||||
POST /api/users/:id/reset-password // 重置密码
|
||||
POST /api/users/:id/change-status // 更改状态
|
||||
```
|
||||
|
||||
### 6.2 请求响应格式
|
||||
```javascript
|
||||
// 统一响应格式
|
||||
{
|
||||
"code": 200,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
// 具体数据
|
||||
},
|
||||
"timestamp": "2024-01-20T10:30:00Z"
|
||||
}
|
||||
|
||||
// 分页响应格式
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取成功",
|
||||
"data": {
|
||||
"list": [...],
|
||||
"pagination": {
|
||||
"current": 1,
|
||||
"pageSize": 10,
|
||||
"total": 100,
|
||||
"totalPages": 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 错误响应格式
|
||||
{
|
||||
"code": 400,
|
||||
"message": "参数错误",
|
||||
"error": {
|
||||
"field": "email",
|
||||
"reason": "邮箱格式不正确"
|
||||
},
|
||||
"timestamp": "2024-01-20T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 数据库规范
|
||||
|
||||
### 7.1 表命名
|
||||
```sql
|
||||
-- 表名使用复数形式,下划线分隔
|
||||
users
|
||||
farm_devices
|
||||
alert_records
|
||||
user_roles
|
||||
|
||||
-- 关联表使用两个表名组合
|
||||
user_farm_bindings
|
||||
device_alert_configs
|
||||
```
|
||||
|
||||
### 7.2 字段命名
|
||||
```sql
|
||||
-- 字段名使用下划线分隔
|
||||
CREATE TABLE users (
|
||||
id VARCHAR(36) PRIMARY KEY,
|
||||
user_name VARCHAR(50) NOT NULL,
|
||||
email VARCHAR(100) UNIQUE,
|
||||
phone_number VARCHAR(20),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT TRUE
|
||||
);
|
||||
```
|
||||
|
||||
## 8. Git 提交规范
|
||||
|
||||
### 8.1 提交信息格式
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
<body>
|
||||
|
||||
<footer>
|
||||
```
|
||||
|
||||
### 8.2 类型说明
|
||||
- **feat**: 新功能
|
||||
- **fix**: 修复bug
|
||||
- **docs**: 文档更新
|
||||
- **style**: 代码格式调整
|
||||
- **refactor**: 代码重构
|
||||
- **test**: 测试相关
|
||||
- **chore**: 构建过程或辅助工具的变动
|
||||
|
||||
### 8.3 提交示例
|
||||
```
|
||||
feat(user): 添加用户头像上传功能
|
||||
|
||||
- 支持jpg、png格式图片上传
|
||||
- 添加图片压缩和裁剪功能
|
||||
- 更新用户资料页面UI
|
||||
|
||||
Closes #123
|
||||
```
|
||||
|
||||
## 9. 测试规范
|
||||
|
||||
### 9.1 单元测试
|
||||
```javascript
|
||||
// 测试文件命名: *.test.js 或 *.spec.js
|
||||
describe('UserService', () => {
|
||||
describe('getUserById', () => {
|
||||
it('应该返回正确的用户信息', async () => {
|
||||
// Arrange
|
||||
const userId = '123';
|
||||
const expectedUser = { id: '123', name: 'Test User' };
|
||||
|
||||
// Act
|
||||
const result = await userService.getUserById(userId);
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(expectedUser);
|
||||
});
|
||||
|
||||
it('用户不存在时应该抛出错误', async () => {
|
||||
// Arrange
|
||||
const userId = 'nonexistent';
|
||||
|
||||
// Act & Assert
|
||||
await expect(userService.getUserById(userId))
|
||||
.rejects.toThrow('用户不存在');
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 9.2 集成测试
|
||||
```javascript
|
||||
describe('User API', () => {
|
||||
beforeEach(async () => {
|
||||
await setupTestDatabase();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await cleanupTestDatabase();
|
||||
});
|
||||
|
||||
it('POST /api/users 应该创建新用户', async () => {
|
||||
const userData = {
|
||||
name: 'Test User',
|
||||
email: 'test@example.com'
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/users')
|
||||
.send(userData)
|
||||
.expect(201);
|
||||
|
||||
expect(response.body.data).toMatchObject(userData);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 10. 性能优化规范
|
||||
|
||||
### 10.1 前端优化
|
||||
```javascript
|
||||
// 懒加载组件
|
||||
const UserProfile = () => import('./components/UserProfile.vue');
|
||||
|
||||
// 防抖处理
|
||||
import { debounce } from 'lodash-es';
|
||||
|
||||
const handleSearch = debounce((keyword) => {
|
||||
// 搜索逻辑
|
||||
}, 300);
|
||||
|
||||
// 虚拟滚动
|
||||
<VirtualList
|
||||
:items="largeDataSet"
|
||||
:item-height="50"
|
||||
:visible-count="10"
|
||||
/>
|
||||
```
|
||||
|
||||
### 10.2 后端优化
|
||||
```javascript
|
||||
// 数据库查询优化
|
||||
const users = await User.findAll({
|
||||
attributes: ['id', 'name', 'email'], // 只查询需要的字段
|
||||
include: [{
|
||||
model: Role,
|
||||
attributes: ['name']
|
||||
}],
|
||||
limit: 10,
|
||||
offset: (page - 1) * 10
|
||||
});
|
||||
|
||||
// 缓存使用
|
||||
const cacheKey = `user:${userId}`;
|
||||
let user = await redis.get(cacheKey);
|
||||
|
||||
if (!user) {
|
||||
user = await User.findById(userId);
|
||||
await redis.setex(cacheKey, 3600, JSON.stringify(user));
|
||||
} else {
|
||||
user = JSON.parse(user);
|
||||
}
|
||||
```
|
||||
|
||||
## 11. 安全规范
|
||||
|
||||
### 11.1 输入验证
|
||||
```javascript
|
||||
// 使用验证库
|
||||
const Joi = require('joi');
|
||||
|
||||
const userSchema = Joi.object({
|
||||
name: Joi.string().min(2).max(50).required(),
|
||||
email: Joi.string().email().required(),
|
||||
password: Joi.string().min(8).pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/)
|
||||
});
|
||||
|
||||
const { error, value } = userSchema.validate(req.body);
|
||||
if (error) {
|
||||
return res.status(400).json({ message: error.details[0].message });
|
||||
}
|
||||
```
|
||||
|
||||
### 11.2 SQL 注入防护
|
||||
```javascript
|
||||
// 使用参数化查询
|
||||
const user = await User.findOne({
|
||||
where: {
|
||||
email: req.body.email // Sequelize 自动转义
|
||||
}
|
||||
});
|
||||
|
||||
// 原生查询使用占位符
|
||||
const result = await sequelize.query(
|
||||
'SELECT * FROM users WHERE email = ?',
|
||||
{
|
||||
replacements: [email],
|
||||
type: QueryTypes.SELECT
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
## 12. 代码审查清单
|
||||
|
||||
### 12.1 功能性检查
|
||||
- [ ] 功能是否按需求实现
|
||||
- [ ] 边界条件是否处理
|
||||
- [ ] 错误处理是否完善
|
||||
- [ ] 性能是否满足要求
|
||||
|
||||
### 12.2 代码质量检查
|
||||
- [ ] 命名是否清晰明确
|
||||
- [ ] 代码结构是否合理
|
||||
- [ ] 是否有重复代码
|
||||
- [ ] 注释是否充分
|
||||
|
||||
### 12.3 安全性检查
|
||||
- [ ] 输入验证是否完整
|
||||
- [ ] 权限控制是否正确
|
||||
- [ ] 敏感信息是否泄露
|
||||
- [ ] SQL注入防护是否到位
|
||||
|
||||
## 13. 工具配置
|
||||
|
||||
### 13.1 ESLint 配置
|
||||
```javascript
|
||||
// .eslintrc.js
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'@vue/eslint-config-prettier'
|
||||
],
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'vue/multi-word-component-names': 'off'
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 13.2 Prettier 配置
|
||||
```javascript
|
||||
// .prettierrc.js
|
||||
module.exports = {
|
||||
semi: true,
|
||||
singleQuote: true,
|
||||
tabWidth: 2,
|
||||
trailingComma: 'es5',
|
||||
printWidth: 80,
|
||||
endOfLine: 'lf'
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**注意**: 本规范会根据项目发展持续更新,请团队成员定期查看最新版本。
|
||||
1322
docs/development/开发指南.md
Normal file
1322
docs/development/开发指南.md
Normal file
File diff suppressed because it is too large
Load Diff
570
docs/development/测试文档.md
Normal file
570
docs/development/测试文档.md
Normal file
@@ -0,0 +1,570 @@
|
||||
# 宁夏智慧养殖监管平台 测试文档
|
||||
|
||||
## 版本历史
|
||||
|
||||
| 版本 | 日期 | 作者 | 描述 |
|
||||
|------|------|------|------|
|
||||
| v1.0 | 2025-01-20 | 测试团队 | 初始版本 |
|
||||
|
||||
## 1. 测试概述
|
||||
|
||||
### 1.1 测试目标
|
||||
|
||||
本文档旨在为宁夏智慧养殖监管平台提供全面的测试指导,确保系统的功能性、性能、安全性和可靠性满足产品需求。
|
||||
|
||||
### 1.2 测试范围
|
||||
|
||||
**包含的测试内容:**
|
||||
- 前端应用测试(Vue 3 + Vite)
|
||||
- 后端API测试(Node.js + Express)
|
||||
- 数据库测试(MySQL)
|
||||
- 小程序测试(uni-app)
|
||||
- 集成测试
|
||||
- 性能测试
|
||||
- 安全测试
|
||||
|
||||
**不包含的测试内容:**
|
||||
- 第三方服务测试(百度地图API等)
|
||||
- 硬件设备测试
|
||||
- 网络基础设施测试
|
||||
|
||||
## 2. 测试策略
|
||||
|
||||
### 2.1 测试类型
|
||||
|
||||
#### 2.1.1 单元测试
|
||||
- **目标覆盖率**: ≥80%
|
||||
- **测试框架**: Jest (后端), Vitest (前端)
|
||||
- **测试内容**: 函数、组件、工具类
|
||||
- **执行频率**: 每次代码提交
|
||||
|
||||
#### 2.1.2 集成测试
|
||||
- **测试框架**: Supertest (API), Vue Test Utils (组件)
|
||||
- **测试内容**: API接口、组件交互、数据流
|
||||
- **执行频率**: 每日构建
|
||||
|
||||
#### 2.1.3 端到端测试
|
||||
- **测试框架**: Cypress
|
||||
- **测试内容**: 完整业务流程、用户交互
|
||||
- **执行频率**: 版本发布前
|
||||
|
||||
#### 2.1.4 性能测试
|
||||
- **测试工具**: Jest (单元性能), 自定义脚本
|
||||
- **测试内容**: 响应时间、并发处理、资源使用
|
||||
- **执行频率**: 版本发布前
|
||||
|
||||
### 2.2 测试环境
|
||||
|
||||
#### 2.2.1 开发环境
|
||||
- **用途**: 开发人员自测
|
||||
- **数据**: 模拟数据
|
||||
- **配置**: 本地开发配置
|
||||
|
||||
#### 2.2.2 测试环境
|
||||
- **用途**: QA团队测试
|
||||
- **数据**: 测试数据集
|
||||
- **配置**: 接近生产环境
|
||||
|
||||
#### 2.2.3 预生产环境
|
||||
- **用途**: 用户验收测试
|
||||
- **数据**: 生产数据副本
|
||||
- **配置**: 生产环境配置
|
||||
|
||||
## 3. 测试工具和框架
|
||||
|
||||
### 3.1 后端测试工具
|
||||
|
||||
#### 3.1.1 Jest 配置
|
||||
```json
|
||||
{
|
||||
"testEnvironment": "node",
|
||||
"collectCoverageFrom": [
|
||||
"controllers/**/*.js",
|
||||
"models/**/*.js",
|
||||
"routes/**/*.js",
|
||||
"utils/**/*.js",
|
||||
"!**/node_modules/**",
|
||||
"!**/migrations/**",
|
||||
"!**/seeds/**"
|
||||
],
|
||||
"coverageDirectory": "coverage",
|
||||
"coverageReporters": ["text", "lcov", "html"]
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.1.2 Supertest API测试
|
||||
```javascript
|
||||
const request = require('supertest');
|
||||
const app = require('../app');
|
||||
|
||||
describe('API Tests', () => {
|
||||
test('GET /api/farms', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/farms')
|
||||
.expect(200);
|
||||
|
||||
expect(response.body).toHaveProperty('data');
|
||||
expect(Array.isArray(response.body.data)).toBe(true);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 3.2 前端测试工具
|
||||
|
||||
#### 3.2.1 Vitest 配置
|
||||
```typescript
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
coverage: {
|
||||
reporter: ['text', 'json', 'html']
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### 3.2.2 Vue Test Utils 组件测试
|
||||
```typescript
|
||||
import { mount } from '@vue/test-utils'
|
||||
import StatusTag from '@/components/StatusTag.vue'
|
||||
|
||||
describe('StatusTag.vue', () => {
|
||||
it('renders correctly', () => {
|
||||
const wrapper = mount(StatusTag, {
|
||||
props: {
|
||||
status: 'success',
|
||||
text: '正常'
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.text()).toContain('正常')
|
||||
expect(wrapper.classes()).toContain('status-success')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### 3.3 小程序测试工具
|
||||
|
||||
#### 3.3.1 uni-app 测试配置
|
||||
```typescript
|
||||
// jest.config.ts
|
||||
export default {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'jsdom',
|
||||
moduleNameMapping: {
|
||||
'^@/(.*)$': '<rootDir>/src/$1'
|
||||
},
|
||||
transform: {
|
||||
'^.+\\.vue$': '@vue/vue3-jest'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 测试用例设计
|
||||
|
||||
### 4.1 功能测试用例
|
||||
|
||||
#### 4.1.1 用户认证测试
|
||||
```javascript
|
||||
describe('用户认证', () => {
|
||||
test('正确的用户名密码应该登录成功', async () => {
|
||||
const loginData = {
|
||||
username: 'testuser',
|
||||
password: 'testpass123'
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send(loginData)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body).toHaveProperty('token');
|
||||
expect(response.body.user.username).toBe('testuser');
|
||||
});
|
||||
|
||||
test('错误的密码应该返回401', async () => {
|
||||
const loginData = {
|
||||
username: 'testuser',
|
||||
password: 'wrongpass'
|
||||
};
|
||||
|
||||
await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send(loginData)
|
||||
.expect(401);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
#### 4.1.2 数据CRUD测试
|
||||
```javascript
|
||||
describe('养殖场管理', () => {
|
||||
let farmId;
|
||||
|
||||
test('创建养殖场', async () => {
|
||||
const farmData = {
|
||||
name: '测试养殖场',
|
||||
location: '宁夏银川',
|
||||
type: 'cattle'
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/farms')
|
||||
.send(farmData)
|
||||
.expect(201);
|
||||
|
||||
farmId = response.body.data.id;
|
||||
expect(response.body.data.name).toBe('测试养殖场');
|
||||
});
|
||||
|
||||
test('获取养殖场列表', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/farms')
|
||||
.expect(200);
|
||||
|
||||
expect(Array.isArray(response.body.data)).toBe(true);
|
||||
expect(response.body.data.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('更新养殖场信息', async () => {
|
||||
const updateData = {
|
||||
name: '更新后的养殖场'
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.put(`/api/farms/${farmId}`)
|
||||
.send(updateData)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.data.name).toBe('更新后的养殖场');
|
||||
});
|
||||
|
||||
test('删除养殖场', async () => {
|
||||
await request(app)
|
||||
.delete(`/api/farms/${farmId}`)
|
||||
.expect(204);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 4.2 性能测试用例
|
||||
|
||||
#### 4.2.1 响应时间测试
|
||||
```javascript
|
||||
describe('性能测试', () => {
|
||||
test('API响应时间应小于500ms', async () => {
|
||||
const startTime = Date.now();
|
||||
|
||||
await request(app)
|
||||
.get('/api/farms')
|
||||
.expect(200);
|
||||
|
||||
const responseTime = Date.now() - startTime;
|
||||
expect(responseTime).toBeLessThan(500);
|
||||
});
|
||||
|
||||
test('并发请求处理', async () => {
|
||||
const promises = [];
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
promises.push(
|
||||
request(app)
|
||||
.get('/api/farms')
|
||||
.expect(200)
|
||||
);
|
||||
}
|
||||
|
||||
const results = await Promise.all(promises);
|
||||
expect(results.length).toBe(10);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 4.3 安全测试用例
|
||||
|
||||
#### 4.3.1 输入验证测试
|
||||
```javascript
|
||||
describe('安全测试', () => {
|
||||
test('SQL注入防护', async () => {
|
||||
const maliciousInput = {
|
||||
name: "'; DROP TABLE farms; --"
|
||||
};
|
||||
|
||||
await request(app)
|
||||
.post('/api/farms')
|
||||
.send(maliciousInput)
|
||||
.expect(400);
|
||||
});
|
||||
|
||||
test('XSS防护', async () => {
|
||||
const xssInput = {
|
||||
name: '<script>alert("xss")</script>'
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/farms')
|
||||
.send(xssInput)
|
||||
.expect(201);
|
||||
|
||||
expect(response.body.data.name).not.toContain('<script>');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 5. 测试执行
|
||||
|
||||
### 5.1 测试命令
|
||||
|
||||
#### 5.1.1 后端测试
|
||||
```bash
|
||||
# 运行所有测试
|
||||
npm test
|
||||
|
||||
# 运行单元测试
|
||||
npm run test:unit
|
||||
|
||||
# 运行集成测试
|
||||
npm run test:integration
|
||||
|
||||
# 生成覆盖率报告
|
||||
npm run test:coverage
|
||||
|
||||
# 监听模式
|
||||
npm run test:watch
|
||||
```
|
||||
|
||||
#### 5.1.2 前端测试
|
||||
```bash
|
||||
# 运行所有测试
|
||||
npm run test
|
||||
|
||||
# 运行单元测试
|
||||
npm run test:unit
|
||||
|
||||
# 运行端到端测试
|
||||
npm run test:e2e
|
||||
|
||||
# 生成覆盖率报告
|
||||
npm run test:coverage
|
||||
```
|
||||
|
||||
#### 5.1.3 小程序测试
|
||||
```bash
|
||||
# 运行测试
|
||||
npm run test
|
||||
|
||||
# 监听模式
|
||||
npm run test:watch
|
||||
|
||||
# 覆盖率报告
|
||||
npm run test:coverage
|
||||
```
|
||||
|
||||
### 5.2 持续集成
|
||||
|
||||
#### 5.2.1 GitHub Actions 配置
|
||||
```yaml
|
||||
name: Test Suite
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: testpass
|
||||
MYSQL_DATABASE: test_db
|
||||
ports:
|
||||
- 3306:3306
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v2
|
||||
```
|
||||
|
||||
## 6. 测试数据管理
|
||||
|
||||
### 6.1 测试数据准备
|
||||
|
||||
#### 6.1.1 种子数据
|
||||
```javascript
|
||||
// seeds/test-data.js
|
||||
module.exports = {
|
||||
farms: [
|
||||
{
|
||||
id: 1,
|
||||
name: '测试养殖场1',
|
||||
location: '宁夏银川',
|
||||
type: 'cattle',
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '测试养殖场2',
|
||||
location: '宁夏石嘴山',
|
||||
type: 'sheep',
|
||||
status: 'active'
|
||||
}
|
||||
],
|
||||
users: [
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
role: 'admin'
|
||||
}
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
#### 6.1.2 数据清理
|
||||
```javascript
|
||||
// 测试前清理数据
|
||||
beforeEach(async () => {
|
||||
await Farm.destroy({ where: {} });
|
||||
await User.destroy({ where: {} });
|
||||
});
|
||||
|
||||
// 测试后清理数据
|
||||
afterEach(async () => {
|
||||
await Farm.destroy({ where: {} });
|
||||
await User.destroy({ where: {} });
|
||||
});
|
||||
```
|
||||
|
||||
### 6.2 Mock数据
|
||||
|
||||
#### 6.2.1 API Mock
|
||||
```javascript
|
||||
// __mocks__/api.js
|
||||
export const mockFarmData = {
|
||||
id: 1,
|
||||
name: '模拟养殖场',
|
||||
location: '宁夏银川',
|
||||
animals: 100
|
||||
};
|
||||
|
||||
export const getFarms = jest.fn(() =>
|
||||
Promise.resolve({ data: [mockFarmData] })
|
||||
);
|
||||
```
|
||||
|
||||
## 7. 测试报告
|
||||
|
||||
### 7.1 覆盖率报告
|
||||
|
||||
测试覆盖率目标:
|
||||
- **整体覆盖率**: ≥80%
|
||||
- **函数覆盖率**: ≥85%
|
||||
- **分支覆盖率**: ≥75%
|
||||
- **行覆盖率**: ≥80%
|
||||
|
||||
### 7.2 测试结果分析
|
||||
|
||||
#### 7.2.1 成功标准
|
||||
- 所有测试用例通过
|
||||
- 覆盖率达到目标要求
|
||||
- 性能测试满足要求
|
||||
- 安全测试无漏洞
|
||||
|
||||
#### 7.2.2 失败处理
|
||||
- 记录失败原因
|
||||
- 分析根本原因
|
||||
- 修复问题
|
||||
- 重新执行测试
|
||||
|
||||
## 8. 最佳实践
|
||||
|
||||
### 8.1 测试编写原则
|
||||
|
||||
1. **独立性**: 测试用例之间相互独立
|
||||
2. **可重复性**: 测试结果可重复
|
||||
3. **快速执行**: 单元测试执行时间短
|
||||
4. **清晰命名**: 测试名称描述清楚
|
||||
5. **边界测试**: 包含边界值测试
|
||||
|
||||
### 8.2 测试维护
|
||||
|
||||
1. **定期更新**: 随代码变更更新测试
|
||||
2. **重构测试**: 消除重复代码
|
||||
3. **性能优化**: 提高测试执行效率
|
||||
4. **文档更新**: 保持测试文档最新
|
||||
|
||||
## 9. 故障排除
|
||||
|
||||
### 9.1 常见问题
|
||||
|
||||
#### 9.1.1 测试环境问题
|
||||
- 数据库连接失败
|
||||
- 依赖服务不可用
|
||||
- 环境变量配置错误
|
||||
|
||||
#### 9.1.2 测试用例问题
|
||||
- 异步测试超时
|
||||
- Mock数据不正确
|
||||
- 测试数据污染
|
||||
|
||||
### 9.2 解决方案
|
||||
|
||||
#### 9.2.1 环境检查
|
||||
```bash
|
||||
# 检查数据库连接
|
||||
npm run test:db-connection
|
||||
|
||||
# 检查服务状态
|
||||
npm run test:services
|
||||
|
||||
# 验证环境配置
|
||||
npm run test:config
|
||||
```
|
||||
|
||||
#### 9.2.2 调试技巧
|
||||
```javascript
|
||||
// 使用调试模式
|
||||
describe.only('特定测试', () => {
|
||||
// 只运行这个测试套件
|
||||
});
|
||||
|
||||
// 跳过测试
|
||||
test.skip('暂时跳过的测试', () => {
|
||||
// 这个测试不会执行
|
||||
});
|
||||
```
|
||||
|
||||
## 10. 联系信息
|
||||
|
||||
### 10.1 测试团队
|
||||
- **测试负责人**: 张三 (zhang.san@nxxmdata.com)
|
||||
- **自动化测试**: 李四 (li.si@nxxmdata.com)
|
||||
- **性能测试**: 王五 (wang.wu@nxxmdata.com)
|
||||
|
||||
### 10.2 支持渠道
|
||||
- **邮箱**: test-support@nxxmdata.com
|
||||
- **Slack**: #testing-support
|
||||
- **工作时间**: 周一至周五 9:00-18:00
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2025年1月20日
|
||||
**文档版本**: v1.0
|
||||
**维护团队**: 宁夏智慧养殖平台测试团队
|
||||
680
docs/development/环境配置文档.md
Normal file
680
docs/development/环境配置文档.md
Normal file
@@ -0,0 +1,680 @@
|
||||
# 宁夏智慧养殖监管平台 环境配置文档
|
||||
|
||||
## 版本历史
|
||||
|
||||
| 版本 | 日期 | 作者 | 描述 |
|
||||
|------|------|------|------|
|
||||
| v1.0 | 2025-01-20 | 开发团队 | 初始版本 |
|
||||
|
||||
## 1. 环境概述
|
||||
|
||||
### 1.1 环境分类
|
||||
|
||||
本项目包含以下几种环境:
|
||||
|
||||
- **开发环境 (Development)**: 本地开发使用
|
||||
- **测试环境 (Testing)**: QA测试使用
|
||||
- **预生产环境 (Staging)**: 用户验收测试使用
|
||||
- **生产环境 (Production)**: 正式运行环境
|
||||
|
||||
### 1.2 技术栈要求
|
||||
|
||||
**基础环境:**
|
||||
- Node.js: 18.0+ (推荐 LTS 版本)
|
||||
- npm: 8.0+ 或 yarn: 1.22+ 或 pnpm: 7.0+
|
||||
- MySQL: 8.0+
|
||||
- Redis: 6.0+
|
||||
- Git: 2.25+
|
||||
|
||||
**开发工具:**
|
||||
- Visual Studio Code (推荐)
|
||||
- Postman (API测试)
|
||||
- MySQL Workbench (数据库管理)
|
||||
|
||||
## 2. 开发环境配置
|
||||
|
||||
### 2.1 Node.js 安装
|
||||
|
||||
#### 2.1.1 使用 nvm 管理 Node.js 版本
|
||||
|
||||
**macOS/Linux:**
|
||||
```bash
|
||||
# 安装 nvm
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
|
||||
|
||||
# 重启终端或执行
|
||||
source ~/.bashrc
|
||||
|
||||
# 安装并使用 Node.js 18
|
||||
nvm install 18
|
||||
nvm use 18
|
||||
nvm alias default 18
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
```bash
|
||||
# 下载并安装 nvm-windows
|
||||
# https://github.com/coreybutler/nvm-windows/releases
|
||||
|
||||
# 安装 Node.js
|
||||
nvm install 18.19.0
|
||||
nvm use 18.19.0
|
||||
```
|
||||
|
||||
#### 2.1.2 验证安装
|
||||
```bash
|
||||
node --version # 应显示 v18.x.x
|
||||
npm --version # 应显示 8.x.x 或更高
|
||||
```
|
||||
|
||||
### 2.2 数据库配置
|
||||
|
||||
#### 2.2.1 MySQL 安装
|
||||
|
||||
**macOS (使用 Homebrew):**
|
||||
```bash
|
||||
brew install mysql
|
||||
brew services start mysql
|
||||
```
|
||||
|
||||
**Ubuntu/Debian:**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install mysql-server
|
||||
sudo systemctl start mysql
|
||||
sudo systemctl enable mysql
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
下载并安装 MySQL Community Server:
|
||||
https://dev.mysql.com/downloads/mysql/
|
||||
|
||||
#### 2.2.2 数据库初始化
|
||||
```bash
|
||||
# 登录 MySQL
|
||||
mysql -u root -p
|
||||
|
||||
# 创建数据库
|
||||
CREATE DATABASE nxxm_farming_dev CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
# 创建用户
|
||||
CREATE USER 'nxxm_dev'@'localhost' IDENTIFIED BY 'dev_password_123';
|
||||
GRANT ALL PRIVILEGES ON nxxm_farming_dev.* TO 'nxxm_dev'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
### 2.3 Redis 配置
|
||||
|
||||
#### 2.3.1 Redis 安装
|
||||
|
||||
**macOS:**
|
||||
```bash
|
||||
brew install redis
|
||||
brew services start redis
|
||||
```
|
||||
|
||||
**Ubuntu/Debian:**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install redis-server
|
||||
sudo systemctl start redis-server
|
||||
sudo systemctl enable redis-server
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
下载并安装 Redis for Windows:
|
||||
https://github.com/microsoftarchive/redis/releases
|
||||
|
||||
#### 2.3.2 验证 Redis
|
||||
```bash
|
||||
redis-cli ping
|
||||
# 应返回 PONG
|
||||
```
|
||||
|
||||
### 2.4 项目配置
|
||||
|
||||
#### 2.4.1 克隆项目
|
||||
```bash
|
||||
git clone https://github.com/nxxmdata/smart-farming-platform.git
|
||||
cd smart-farming-platform
|
||||
```
|
||||
|
||||
#### 2.4.2 安装依赖
|
||||
|
||||
**后端依赖:**
|
||||
```bash
|
||||
cd backend
|
||||
npm install
|
||||
```
|
||||
|
||||
**前端依赖:**
|
||||
```bash
|
||||
cd admin-system
|
||||
npm install
|
||||
```
|
||||
|
||||
**小程序依赖:**
|
||||
```bash
|
||||
cd bank_mini_program
|
||||
npm install
|
||||
```
|
||||
|
||||
#### 2.4.3 环境变量配置
|
||||
|
||||
**后端环境变量 (.env):**
|
||||
```bash
|
||||
# 复制环境变量模板
|
||||
cp backend/.env.example backend/.env
|
||||
|
||||
# 编辑环境变量
|
||||
vim backend/.env
|
||||
```
|
||||
|
||||
```env
|
||||
# 服务器配置
|
||||
NODE_ENV=development
|
||||
PORT=5350
|
||||
|
||||
# 数据库配置
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_NAME=nxxm_farming_dev
|
||||
DB_USER=nxxm_dev
|
||||
DB_PASSWORD=dev_password_123
|
||||
DB_DIALECT=mysql
|
||||
|
||||
# Redis 配置
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
|
||||
# JWT 配置
|
||||
JWT_SECRET=your_jwt_secret_key_here
|
||||
JWT_EXPIRES_IN=24h
|
||||
|
||||
# 文件上传配置
|
||||
UPLOAD_PATH=./uploads
|
||||
UPLOAD_MAX_SIZE=10485760
|
||||
|
||||
# 日志配置
|
||||
LOG_LEVEL=debug
|
||||
LOG_FILE=logs/app.log
|
||||
```
|
||||
|
||||
**前端环境变量 (.env.development):**
|
||||
```env
|
||||
# API 配置
|
||||
VITE_API_BASE_URL=http://localhost:5350/api
|
||||
VITE_API_TIMEOUT=10000
|
||||
|
||||
# 百度地图配置
|
||||
VITE_BAIDU_MAP_AK=your_baidu_map_ak
|
||||
|
||||
# 上传配置
|
||||
VITE_UPLOAD_URL=http://localhost:5350/api/upload
|
||||
```
|
||||
|
||||
## 3. 数据库迁移
|
||||
|
||||
### 3.1 运行迁移
|
||||
```bash
|
||||
cd backend
|
||||
npm run migrate
|
||||
```
|
||||
|
||||
### 3.2 填充种子数据
|
||||
```bash
|
||||
npm run seed
|
||||
```
|
||||
|
||||
### 3.3 重置数据库
|
||||
```bash
|
||||
npm run db:reset
|
||||
```
|
||||
|
||||
## 4. 启动项目
|
||||
|
||||
### 4.1 启动后端服务
|
||||
```bash
|
||||
cd backend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### 4.2 启动前端服务
|
||||
```bash
|
||||
cd admin-system
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### 4.3 启动小程序开发
|
||||
```bash
|
||||
cd bank_mini_program
|
||||
npm run dev:mp-weixin
|
||||
```
|
||||
|
||||
### 4.4 验证服务
|
||||
```bash
|
||||
# 检查后端服务
|
||||
curl http://localhost:5350/api/health
|
||||
|
||||
# 检查前端服务
|
||||
# 浏览器访问 http://localhost:3000
|
||||
```
|
||||
|
||||
## 5. 测试环境配置
|
||||
|
||||
### 5.1 环境变量
|
||||
|
||||
**后端测试环境 (.env.test):**
|
||||
```env
|
||||
NODE_ENV=test
|
||||
PORT=5351
|
||||
|
||||
# 测试数据库
|
||||
DB_NAME=nxxm_farming_test
|
||||
DB_USER=nxxm_test
|
||||
DB_PASSWORD=test_password_123
|
||||
|
||||
# 其他配置保持与开发环境一致
|
||||
```
|
||||
|
||||
### 5.2 测试数据库初始化
|
||||
```bash
|
||||
# 创建测试数据库
|
||||
mysql -u root -p -e "CREATE DATABASE nxxm_farming_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||
|
||||
# 运行测试迁移
|
||||
NODE_ENV=test npm run migrate
|
||||
```
|
||||
|
||||
### 5.3 运行测试
|
||||
```bash
|
||||
# 后端测试
|
||||
cd backend
|
||||
npm test
|
||||
|
||||
# 前端测试
|
||||
cd admin-system
|
||||
npm run test
|
||||
|
||||
# 小程序测试
|
||||
cd bank_mini_program
|
||||
npm test
|
||||
```
|
||||
|
||||
## 6. 生产环境配置
|
||||
|
||||
### 6.1 服务器要求
|
||||
|
||||
**最低配置:**
|
||||
- CPU: 2核
|
||||
- 内存: 4GB
|
||||
- 存储: 50GB SSD
|
||||
- 网络: 10Mbps
|
||||
|
||||
**推荐配置:**
|
||||
- CPU: 4核
|
||||
- 内存: 8GB
|
||||
- 存储: 100GB SSD
|
||||
- 网络: 100Mbps
|
||||
|
||||
### 6.2 环境变量
|
||||
|
||||
**生产环境 (.env.production):**
|
||||
```env
|
||||
NODE_ENV=production
|
||||
PORT=5350
|
||||
|
||||
# 数据库配置
|
||||
DB_HOST=your_production_db_host
|
||||
DB_PORT=3306
|
||||
DB_NAME=nxxm_farming_prod
|
||||
DB_USER=nxxm_prod
|
||||
DB_PASSWORD=your_secure_password
|
||||
|
||||
# Redis 配置
|
||||
REDIS_HOST=your_redis_host
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=your_redis_password
|
||||
|
||||
# JWT 配置
|
||||
JWT_SECRET=your_very_secure_jwt_secret
|
||||
JWT_EXPIRES_IN=24h
|
||||
|
||||
# HTTPS 配置
|
||||
HTTPS_ENABLED=true
|
||||
SSL_CERT_PATH=/path/to/cert.pem
|
||||
SSL_KEY_PATH=/path/to/key.pem
|
||||
|
||||
# 日志配置
|
||||
LOG_LEVEL=info
|
||||
LOG_FILE=/var/log/nxxm-farming/app.log
|
||||
```
|
||||
|
||||
### 6.3 部署脚本
|
||||
|
||||
**部署脚本 (deploy.sh):**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# 拉取最新代码
|
||||
git pull origin main
|
||||
|
||||
# 安装依赖
|
||||
npm ci --production
|
||||
|
||||
# 运行数据库迁移
|
||||
npm run migrate
|
||||
|
||||
# 构建前端
|
||||
cd admin-system
|
||||
npm run build
|
||||
cd ..
|
||||
|
||||
# 重启服务
|
||||
pm2 restart nxxm-farming-backend
|
||||
pm2 restart nxxm-farming-frontend
|
||||
|
||||
echo "部署完成"
|
||||
```
|
||||
|
||||
## 7. Docker 配置
|
||||
|
||||
### 7.1 Dockerfile
|
||||
|
||||
**后端 Dockerfile:**
|
||||
```dockerfile
|
||||
FROM node:18-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 5350
|
||||
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
**前端 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/nginx.conf
|
||||
|
||||
EXPOSE 80
|
||||
```
|
||||
|
||||
### 7.2 Docker Compose
|
||||
|
||||
**docker-compose.yml:**
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
backend:
|
||||
build: ./backend
|
||||
ports:
|
||||
- "5350:5350"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- DB_HOST=mysql
|
||||
- REDIS_HOST=redis
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
|
||||
frontend:
|
||||
build: ./admin-system
|
||||
ports:
|
||||
- "80:80"
|
||||
depends_on:
|
||||
- backend
|
||||
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: rootpassword
|
||||
MYSQL_DATABASE: nxxm_farming_prod
|
||||
MYSQL_USER: nxxm_prod
|
||||
MYSQL_PASSWORD: prodpassword
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
|
||||
redis:
|
||||
image: redis:6-alpine
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
redis_data:
|
||||
```
|
||||
|
||||
## 8. 监控和日志
|
||||
|
||||
### 8.1 日志配置
|
||||
|
||||
**Winston 日志配置:**
|
||||
```javascript
|
||||
const winston = require('winston');
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: process.env.LOG_LEVEL || 'info',
|
||||
format: winston.format.combine(
|
||||
winston.format.timestamp(),
|
||||
winston.format.errors({ stack: true }),
|
||||
winston.format.json()
|
||||
),
|
||||
transports: [
|
||||
new winston.transports.File({
|
||||
filename: 'logs/error.log',
|
||||
level: 'error'
|
||||
}),
|
||||
new winston.transports.File({
|
||||
filename: 'logs/combined.log'
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
logger.add(new winston.transports.Console({
|
||||
format: winston.format.simple()
|
||||
}));
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 健康检查
|
||||
|
||||
**健康检查端点:**
|
||||
```javascript
|
||||
app.get('/api/health', async (req, res) => {
|
||||
try {
|
||||
// 检查数据库连接
|
||||
await sequelize.authenticate();
|
||||
|
||||
// 检查 Redis 连接
|
||||
await redis.ping();
|
||||
|
||||
res.json({
|
||||
status: 'healthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
services: {
|
||||
database: 'connected',
|
||||
redis: 'connected'
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(503).json({
|
||||
status: 'unhealthy',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 9. 故障排除
|
||||
|
||||
### 9.1 常见问题
|
||||
|
||||
#### 9.1.1 端口占用
|
||||
```bash
|
||||
# 查看端口占用
|
||||
lsof -i :5350
|
||||
|
||||
# 杀死进程
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
#### 9.1.2 数据库连接失败
|
||||
```bash
|
||||
# 检查 MySQL 服务状态
|
||||
sudo systemctl status mysql
|
||||
|
||||
# 重启 MySQL 服务
|
||||
sudo systemctl restart mysql
|
||||
|
||||
# 检查数据库连接
|
||||
mysql -u nxxm_dev -p -h localhost
|
||||
```
|
||||
|
||||
#### 9.1.3 Redis 连接失败
|
||||
```bash
|
||||
# 检查 Redis 服务状态
|
||||
sudo systemctl status redis
|
||||
|
||||
# 重启 Redis 服务
|
||||
sudo systemctl restart redis
|
||||
|
||||
# 测试 Redis 连接
|
||||
redis-cli ping
|
||||
```
|
||||
|
||||
### 9.2 性能优化
|
||||
|
||||
#### 9.2.1 数据库优化
|
||||
```sql
|
||||
-- 添加索引
|
||||
CREATE INDEX idx_farm_status ON farms(status);
|
||||
CREATE INDEX idx_animal_farm_id ON animals(farm_id);
|
||||
|
||||
-- 查看慢查询
|
||||
SHOW VARIABLES LIKE 'slow_query_log';
|
||||
SET GLOBAL slow_query_log = 'ON';
|
||||
```
|
||||
|
||||
#### 9.2.2 Redis 缓存优化
|
||||
```javascript
|
||||
// 缓存配置
|
||||
const redis = new Redis({
|
||||
host: process.env.REDIS_HOST,
|
||||
port: process.env.REDIS_PORT,
|
||||
maxRetriesPerRequest: 3,
|
||||
retryDelayOnFailover: 100,
|
||||
lazyConnect: true
|
||||
});
|
||||
```
|
||||
|
||||
## 10. 安全配置
|
||||
|
||||
### 10.1 HTTPS 配置
|
||||
|
||||
**Nginx HTTPS 配置:**
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name api.nxxmdata.com;
|
||||
|
||||
ssl_certificate /path/to/cert.pem;
|
||||
ssl_certificate_key /path/to/key.pem;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:5350;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 10.2 防火墙配置
|
||||
|
||||
**UFW 防火墙配置:**
|
||||
```bash
|
||||
# 启用防火墙
|
||||
sudo ufw enable
|
||||
|
||||
# 允许 SSH
|
||||
sudo ufw allow ssh
|
||||
|
||||
# 允许 HTTP/HTTPS
|
||||
sudo ufw allow 80
|
||||
sudo ufw allow 443
|
||||
|
||||
# 允许应用端口(仅内网)
|
||||
sudo ufw allow from 10.0.0.0/8 to any port 5350
|
||||
```
|
||||
|
||||
## 11. 备份和恢复
|
||||
|
||||
### 11.1 数据库备份
|
||||
|
||||
**自动备份脚本:**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_DIR="/backup/mysql"
|
||||
DB_NAME="nxxm_farming_prod"
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# 备份数据库
|
||||
mysqldump -u root -p$MYSQL_ROOT_PASSWORD $DB_NAME > $BACKUP_DIR/backup_$DATE.sql
|
||||
|
||||
# 压缩备份文件
|
||||
gzip $BACKUP_DIR/backup_$DATE.sql
|
||||
|
||||
# 删除7天前的备份
|
||||
find $BACKUP_DIR -name "backup_*.sql.gz" -mtime +7 -delete
|
||||
```
|
||||
|
||||
### 11.2 文件备份
|
||||
|
||||
**文件备份脚本:**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_DIR="/backup/files"
|
||||
SOURCE_DIR="/app/uploads"
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# 备份文件
|
||||
tar -czf $BACKUP_DIR/files_$DATE.tar.gz -C $SOURCE_DIR .
|
||||
|
||||
# 删除30天前的备份
|
||||
find $BACKUP_DIR -name "files_*.tar.gz" -mtime +30 -delete
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2025年1月20日
|
||||
**文档版本**: v1.0
|
||||
**维护团队**: 宁夏智慧养殖平台开发团队
|
||||
Reference in New Issue
Block a user