重构动物认领页面和导航菜单,统一使用SVG图标并优化交互体验
This commit is contained in:
35
.codebuddy/.rules/my-rule.mdc
Normal file
35
.codebuddy/.rules/my-rule.mdc
Normal file
@@ -0,0 +1,35 @@
|
||||
# my-rule
|
||||
|
||||
这是一个规则文件,用于帮助 AI 理解您的代码库和遵循项目约定。
|
||||
1. 请保持对话语言为中文
|
||||
2. 我的系统为 macos
|
||||
3. 远程服务器为centos10 64位
|
||||
4. 项目文件夹结构为:
|
||||
- docs 文档目录
|
||||
- admin-system 管理后台目录
|
||||
- mini-program 小程序app目录
|
||||
- backend 后端服务目录
|
||||
- website 官网目录
|
||||
- scripts 脚本目录 放置一些脚本,如:
|
||||
- 数据库脚本
|
||||
- 部署脚本
|
||||
- 测试脚本
|
||||
- 运维脚本
|
||||
5. 整个项目入口文档为根目录下的readme.md,其他文档请放在docs目录下
|
||||
6. 请使用markdown格式编写文档,整个项目文档包括:
|
||||
- 需求文档:整个项目需求文档.md 官网需求文档.md 后端管理需求文档.md 管理后台需求文档.md 小程序app需求文档.md
|
||||
- 架构文档:整个项目的架构文档.md 后端架构文档.md 小程序架构文档.md 管理后台架构文档.md
|
||||
- 详细设计文档:
|
||||
- 数据库设计文档.md
|
||||
- 管理后台接口设计文档.md
|
||||
- 小程序app接口设计文档.md
|
||||
- 开发文档:
|
||||
- 后端开发文档.md 包含:细分到每个子任务的开发计划
|
||||
- 小程序app开发文档.md 包含:细分到每个子任务的开发计划
|
||||
- 管理后台开发文档.md 包含:细分到每个子任务的开发计划
|
||||
- 后端管理开发文档.md 包含:细分到每个子任务的开发计划
|
||||
- 测试文档.md
|
||||
- 部署文档.md
|
||||
- 运维文档.md
|
||||
- 安全文档.md
|
||||
- 用户手册文档.md
|
||||
323
README.md
323
README.md
@@ -49,245 +49,166 @@
|
||||
|
||||
```
|
||||
jiebanke/
|
||||
├── 📁 backend/ # 后端服务 (Node.js + Express)
|
||||
├── 📁 admin-system/ # 后台管理系统 (Vue 3 + Element Plus)
|
||||
├── 📁 website/ # 官方网站 (Vue 3)
|
||||
├── 📁 mini-program/ # 微信小程序矩阵 (原生小程序)
|
||||
├── 📁 docs/ # 项目文档
|
||||
├── 📁 scripts/ # 工具脚本
|
||||
├── 📁 test/ # 测试文件目录
|
||||
└── 📄 README.md # 项目说明 (当前文件)
|
||||
├── README.md # 项目入口文档
|
||||
├── docs/ # 项目文档目录
|
||||
│ ├── 整个项目需求文档.md # 项目整体需求
|
||||
│ ├── 官网需求文档.md # 官网需求
|
||||
│ ├── 后端管理需求文档.md # 后端管理需求
|
||||
│ ├── 管理后台需求文档.md # 管理后台需求
|
||||
│ ├── 小程序app需求文档.md # 小程序需求
|
||||
│ ├── 整个项目的架构文档.md # 项目整体架构
|
||||
│ ├── 后端架构文档.md # 后端架构
|
||||
│ ├── 小程序架构文档.md # 小程序架构
|
||||
│ ├── 管理后台架构文档.md # 管理后台架构
|
||||
│ ├── 数据库设计文档.md # 数据库设计
|
||||
│ ├── 管理后台接口设计文档.md # 管理后台接口
|
||||
│ ├── 小程序app接口设计文档.md # 小程序接口
|
||||
│ ├── 后端开发文档.md # 后端开发指南
|
||||
│ ├── 小程序app开发文档.md # 小程序开发指南
|
||||
│ ├── 管理后台开发文档.md # 管理后台开发指南
|
||||
│ ├── 后端管理开发文档.md # 后端管理开发指南
|
||||
│ ├── 测试文档.md # 测试策略和规范
|
||||
│ ├── 部署文档.md # 部署指南
|
||||
│ ├── 运维文档.md # 运维手册
|
||||
│ ├── 安全文档.md # 安全规范
|
||||
│ └── 用户手册文档.md # 用户操作手册
|
||||
├── admin-system/ # 管理后台目录
|
||||
├── mini-program/ # 小程序app目录
|
||||
├── backend/ # 后端服务目录
|
||||
├── website/ # 官网目录
|
||||
└── scripts/ # 脚本目录
|
||||
├── database/ # 数据库脚本
|
||||
├── deploy/ # 部署脚本
|
||||
├── test/ # 测试脚本
|
||||
└── ops/ # 运维脚本
|
||||
```
|
||||
|
||||
## 📚 文档导航
|
||||
|
||||
### 需求文档
|
||||
- [整个项目需求文档](./docs/整个项目需求文档.md) - 项目整体需求和功能规划
|
||||
- [官网需求文档](./docs/官网需求文档.md) - 官网功能需求
|
||||
- [后端管理需求文档](./docs/后端管理需求文档.md) - 后端管理系统需求
|
||||
- [管理后台需求文档](./docs/管理后台需求文档.md) - 管理后台功能需求
|
||||
- [小程序app需求文档](./docs/小程序app需求文档.md) - 小程序功能需求
|
||||
|
||||
### 架构文档
|
||||
- [整个项目的架构文档](./docs/整个项目的架构文档.md) - 项目整体架构设计
|
||||
- [后端架构文档](./docs/后端架构文档.md) - 后端服务架构
|
||||
- [小程序架构文档](./docs/小程序架构文档.md) - 小程序架构设计
|
||||
- [管理后台架构文档](./docs/管理后台架构文档.md) - 管理后台架构
|
||||
|
||||
### 详细设计文档
|
||||
- [数据库设计文档](./docs/数据库设计文档.md) - 数据库表结构和关系设计
|
||||
- [管理后台接口设计文档](./docs/管理后台接口设计文档.md) - 管理后台API接口
|
||||
- [小程序app接口设计文档](./docs/小程序app接口设计文档.md) - 小程序API接口
|
||||
|
||||
### 开发文档
|
||||
- [后端开发文档](./docs/后端开发文档.md) - 后端开发指南和任务计划
|
||||
- [小程序app开发文档](./docs/小程序app开发文档.md) - 小程序开发指南和任务计划
|
||||
- [管理后台开发文档](./docs/管理后台开发文档.md) - 管理后台开发指南和任务计划
|
||||
- [后端管理开发文档](./docs/后端管理开发文档.md) - 后端管理开发指南和任务计划
|
||||
|
||||
### 运维文档
|
||||
- [测试文档](./docs/测试文档.md) - 测试策略、用例和自动化测试
|
||||
- [部署文档](./docs/部署文档.md) - 环境部署和配置指南
|
||||
- [运维文档](./docs/运维文档.md) - 系统监控、维护和故障处理
|
||||
- [安全文档](./docs/安全文档.md) - 安全策略和防护措施
|
||||
- [用户手册文档](./docs/用户手册文档.md) - 用户操作指南
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 环境要求
|
||||
- Node.js 16.x+
|
||||
- Node.js 18+
|
||||
- MySQL 8.0+
|
||||
- npm 8.x+
|
||||
- Redis 6.0+
|
||||
- Docker & Docker Compose (可选)
|
||||
|
||||
### 安装依赖
|
||||
### 本地开发
|
||||
|
||||
1. **克隆项目**
|
||||
```bash
|
||||
# 安装后端依赖
|
||||
cd backend && npm install
|
||||
|
||||
# 安装后台管理依赖
|
||||
cd admin-system && npm install
|
||||
|
||||
# 安装官网依赖
|
||||
cd website && npm install
|
||||
|
||||
# 安装小程序依赖
|
||||
cd mini-program && npm install
|
||||
git clone https://github.com/your-org/jiebanke.git
|
||||
cd jiebanke
|
||||
```
|
||||
|
||||
### 启动开发环境
|
||||
2. **安装依赖**
|
||||
```bash
|
||||
# 启动后端服务
|
||||
cd backend && npm run dev
|
||||
# 后端服务
|
||||
cd backend
|
||||
npm install
|
||||
|
||||
# 启动后台管理 (新终端)
|
||||
cd admin-system && npm run dev
|
||||
# 管理后台
|
||||
cd ../admin-system
|
||||
npm install
|
||||
|
||||
# 启动官方网站 (新终端)
|
||||
cd website && npm run dev
|
||||
# 小程序
|
||||
cd ../mini-program
|
||||
npm install
|
||||
```
|
||||
|
||||
## 📖 项目文档
|
||||
|
||||
所有详细文档位于 `docs/` 目录:
|
||||
|
||||
### 📖 快速导航
|
||||
|
||||
| 文档类型 | 文档名称 | 描述 | 适用人员 |
|
||||
|---------|---------|------|---------|
|
||||
| 🚀 快速开始 | [系统集成和部署文档](docs/系统集成和部署文档.md) | 环境搭建、部署流程 | 开发者、运维 |
|
||||
| 🔧 开发指南 | [前端开发文档](docs/前端开发文档.md) | 前端开发规范和指南 | 前端开发者 |
|
||||
| 🔧 开发指南 | [后端开发文档](docs/后端开发文档.md) | 后端开发规范和指南 | 后端开发者 |
|
||||
| 📋 API参考 | [API接口文档](docs/API接口文档.md) | 完整的API接口文档 | 全栈开发者 |
|
||||
| 🗄️ 数据设计 | [数据库设计文档](docs/数据库设计文档.md) | 数据库结构设计 | 后端开发者、DBA |
|
||||
| 👨💼 管理功能 | [管理员后台系统API文档](docs/管理员后台系统API文档.md) | 管理后台功能说明 | 管理员、开发者 |
|
||||
| 📁 文件系统 | [文件上传系统文档](docs/文件上传系统文档.md) | 文件上传和管理 | 全栈开发者 |
|
||||
| 🔍 监控运维 | [错误处理和日志系统文档](docs/错误处理和日志系统文档.md) | 错误处理和日志 | 开发者、运维 |
|
||||
| 🧪 质量保证 | [测试文档](docs/测试文档.md) | 测试策略、用例设计和质量保证 | 测试工程师、开发者 |
|
||||
| 🔒 安全管理 | [安全和权限管理文档](docs/安全和权限管理文档.md) | 安全策略、权限控制、安全防护措施 | 安全工程师、系统管理员 |
|
||||
| ⚡ 性能优化 | [性能优化文档](docs/性能优化文档.md) | 系统性能优化策略、监控方案和优化实践 | 性能工程师、运维工程师 |
|
||||
| 🚀 部署运维 | [部署和运维文档](docs/部署和运维文档.md) | 系统部署流程和运维管理方案 | 运维工程师、DevOps工程师 |
|
||||
| 📊 项目管理 | [项目开发进度报告](docs/项目开发进度报告.md) | 项目进度和规划 | 项目经理、开发者 |
|
||||
| 📝 开发规范 | [开发规范和最佳实践](docs/开发规范和最佳实践.md) | 代码规范和标准 | 全体开发者 |
|
||||
|
||||
### 核心文档
|
||||
- 📄 [项目概述](docs/项目概述.md) - 项目背景、目标和整体介绍
|
||||
- 📄 [系统架构文档](docs/系统架构文档.md) - 系统架构设计和技术栈
|
||||
- 📄 [API接口文档](docs/API接口文档.md) - 完整的API接口说明
|
||||
- 📄 [数据库设计文档](docs/数据库设计文档.md) - 数据库表结构和关系设计
|
||||
- 📄 [开发指南](docs/开发指南.md) - 开发环境搭建和开发规范
|
||||
- 📄 [部署指南](docs/部署指南.md) - 开发、测试、生产环境部署指南
|
||||
|
||||
### 功能模块文档
|
||||
|
||||
| 文档名称 | 描述 | 链接 |
|
||||
|---------|------|------|
|
||||
| API接口文档 | 详细的API接口说明和使用示例 | [查看文档](./docs/API接口文档.md) |
|
||||
| 管理员后台文档 | 管理员功能和操作指南 | [查看文档](./docs/管理员后台文档.md) |
|
||||
| 用户认证系统文档 | 用户注册、登录、权限管理 | [查看文档](./docs/用户认证系统文档.md) |
|
||||
| 动物管理系统文档 | 动物信息管理和认领流程 | [查看文档](./docs/动物管理系统文档.md) |
|
||||
| 文件上传系统文档 | 文件上传、存储和管理 | [查看文档](./docs/文件上传系统文档.md) |
|
||||
| 数据库设计文档 | 数据库架构、表结构和关系设计 | [查看文档](./docs/数据库设计文档.md) |
|
||||
| 错误处理和日志系统文档 | 错误处理机制和日志记录 | [查看文档](./docs/错误处理和日志系统文档.md) |
|
||||
| 系统集成和部署文档 | 系统部署和运维指南 | [查看文档](./docs/系统集成和部署文档.md) |
|
||||
| 前端开发文档 | 前端技术架构、组件设计和开发规范 | [查看文档](./docs/前端开发文档.md) |
|
||||
|
||||
#### 项目管理文档
|
||||
- **[项目开发进度报告](docs/项目开发进度报告.md)** - 项目进度跟踪和里程碑规划
|
||||
- **[开发规范和最佳实践](docs/开发规范和最佳实践.md)** - 团队开发规范和代码标准
|
||||
- **[测试文档](docs/测试文档.md)** - 测试策略、用例设计和质量保证
|
||||
|
||||
### 补充文档
|
||||
- 📄 [变更日志](CHANGELOG.md) - 项目版本变更记录
|
||||
- 📄 [贡献指南](docs/贡献指南.md) - 如何参与项目开发
|
||||
- 📄 [常见问题](docs/常见问题.md) - 开发和使用中的常见问题解答
|
||||
- 📄 [许可证](LICENSE.md) - 项目许可证信息
|
||||
|
||||
## 🛠️ 开发工具
|
||||
|
||||
### 脚本工具
|
||||
项目提供了一些有用的开发脚本:
|
||||
|
||||
3. **配置环境**
|
||||
```bash
|
||||
# 数据库连接测试
|
||||
cd backend && npm run test-db
|
||||
|
||||
# API接口测试
|
||||
cd backend && npm run test-api
|
||||
|
||||
# 数据库初始化
|
||||
cd backend && npm run db:reset
|
||||
|
||||
# 部署脚本 (Linux/Mac)
|
||||
cd scripts && ./deploy.sh all
|
||||
|
||||
# 部署脚本 (Windows PowerShell)
|
||||
cd scripts && .\deploy.ps1 all
|
||||
```
|
||||
|
||||
### 环境配置
|
||||
复制环境变量模板并配置:
|
||||
|
||||
```bash
|
||||
# 后端环境配置
|
||||
# 复制环境配置文件
|
||||
cp backend/.env.example backend/.env
|
||||
|
||||
# 后台管理环境配置
|
||||
cp admin-system/.env.example admin-system/.env
|
||||
```
|
||||
|
||||
## ☁️ 部署
|
||||
|
||||
项目支持多种部署方式:
|
||||
|
||||
### 自动部署脚本
|
||||
在 `scripts/` 目录中提供了自动部署脚本,支持 Linux/Mac 和 Windows 系统:
|
||||
|
||||
4. **启动服务**
|
||||
```bash
|
||||
# Linux/Mac 部署所有模块
|
||||
cd scripts && chmod +x deploy.sh && ./deploy.sh all
|
||||
# 启动后端服务
|
||||
cd backend
|
||||
npm run dev
|
||||
|
||||
# Windows PowerShell 部署所有模块
|
||||
cd scripts && .\deploy.ps1 all
|
||||
# 启动管理后台
|
||||
cd admin-system
|
||||
npm run dev
|
||||
|
||||
# 启动小程序开发工具
|
||||
cd mini-program
|
||||
npm run dev
|
||||
```
|
||||
|
||||
支持的部署选项:
|
||||
- `all` - 部署所有模块
|
||||
- `backend` - 部署后端服务
|
||||
- `admin` - 部署后台管理系统
|
||||
- `website` - 部署官方网站
|
||||
- `mini-program` - 构建微信小程序
|
||||
|
||||
### Docker 容器化部署
|
||||
每个模块都提供了 Docker 配置文件,可以使用 docker-compose 进行部署:
|
||||
### Docker 部署
|
||||
|
||||
```bash
|
||||
# 启动所有服务
|
||||
# 构建并启动所有服务
|
||||
docker-compose up -d
|
||||
|
||||
# 启动指定服务
|
||||
docker-compose up -d backend
|
||||
|
||||
# 查看服务状态
|
||||
docker-compose ps
|
||||
|
||||
# 查看日志
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
### 手动部署
|
||||
每个模块也可以手动部署到服务器,具体说明请参考各模块目录中的 DEPLOYMENT.md 文件。
|
||||
## 📋 开发规范
|
||||
|
||||
## 🌐 访问地址
|
||||
- **代码规范**: 遵循 ESLint + Prettier 配置
|
||||
- **提交规范**: 使用 Conventional Commits 格式
|
||||
- **分支策略**: Git Flow 工作流
|
||||
- **测试要求**: 单元测试覆盖率 ≥ 80%
|
||||
- **文档更新**: 代码变更需同步更新文档
|
||||
|
||||
- **后端API**: https://webapi.jiebanke.com
|
||||
- **后台管理**: https://admin.jiebanke.com
|
||||
- **官方网站**: https://www.jiebanke.com
|
||||
- **小程序**: 使用微信开发者工具打开 `mini-program/` 目录
|
||||
## 🤝 贡献指南
|
||||
|
||||
## 📦 依赖管理
|
||||
1. Fork 项目
|
||||
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
|
||||
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
||||
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||||
5. 创建 Pull Request
|
||||
|
||||
### 主要技术栈
|
||||
## 📄 许可证
|
||||
|
||||
**后端**:
|
||||
- Node.js + Express.js
|
||||
- Sequelize ORM
|
||||
- JWT 认证
|
||||
- MySQL 数据库
|
||||
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情
|
||||
|
||||
**前端**:
|
||||
- Vue 3 + TypeScript
|
||||
- Element Plus UI
|
||||
- Vite 构建工具
|
||||
- Pinia 状态管理
|
||||
## 📞 联系我们
|
||||
|
||||
**小程序**:
|
||||
- 微信原生小程序
|
||||
- Vant Weapp UI
|
||||
- Uni-app 框架
|
||||
|
||||
## 🔧 开发规范
|
||||
|
||||
### 代码风格
|
||||
- 使用 ESLint + Prettier 统一代码风格
|
||||
- 遵循 Git Commit 消息规范
|
||||
- 实行代码审查流程
|
||||
|
||||
### 分支策略
|
||||
- 采用 Git Flow 工作流
|
||||
- 功能分支开发
|
||||
- 发布分支管理
|
||||
|
||||
## 🚀 部署说明
|
||||
|
||||
详细部署指南请参考 [DEPLOYMENT.md](docs/DEPLOYMENT.md),包含:
|
||||
|
||||
- 开发环境部署
|
||||
- 测试环境部署
|
||||
- 生产环境部署
|
||||
- 容器化部署 (Docker)
|
||||
- 安全配置指南
|
||||
|
||||
## 📞 支持与维护
|
||||
|
||||
### 开发团队
|
||||
- 后端开发: backend@jiebanke.com
|
||||
- 前端开发: frontend@jiebanke.com
|
||||
- 小程序开发: miniprogram@jiebanke.com
|
||||
|
||||
### 运维支持
|
||||
- 运维团队: ops@jiebanke.com
|
||||
- 紧急联系: +86-138-0013-8000
|
||||
|
||||
## 📊 版本信息
|
||||
|
||||
- **当前版本**: v1.0.0
|
||||
- **Node.js**: 16.20.2
|
||||
- **Vue**: 3.3.4
|
||||
- **MySQL**: 8.0.33
|
||||
- 项目维护者: [团队名称]
|
||||
- 邮箱: contact@jiebanke.com
|
||||
- 项目地址: https://github.com/your-org/jiebanke
|
||||
- 文档地址: https://docs.jiebanke.com
|
||||
|
||||
---
|
||||
*最后更新: 2024年* 📅
|
||||
|
||||
**注意**: 详细的开发、部署和使用说明请参考 `docs/` 目录下的相关文档。
|
||||
226
backend/scripts/check-database-structure.js
Normal file
226
backend/scripts/check-database-structure.js
Normal file
@@ -0,0 +1,226 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* 数据库结构检查脚本
|
||||
* 检查数据库表结构和数据完整性
|
||||
*/
|
||||
|
||||
const mysql = require('mysql2/promise');
|
||||
const config = require('../config/env');
|
||||
|
||||
async function checkDatabaseStructure() {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
console.log('🔍 开始检查数据库结构...');
|
||||
|
||||
// 创建数据库连接
|
||||
const dbConfig = {
|
||||
host: config.mysql.host,
|
||||
port: config.mysql.port,
|
||||
user: config.mysql.user,
|
||||
password: config.mysql.password,
|
||||
database: config.mysql.database,
|
||||
charset: config.mysql.charset,
|
||||
timezone: config.mysql.timezone
|
||||
};
|
||||
|
||||
connection = await mysql.createConnection(dbConfig);
|
||||
console.log('✅ 数据库连接成功');
|
||||
console.log(`📊 数据库: ${dbConfig.database}`);
|
||||
console.log('='.repeat(60));
|
||||
|
||||
// 测试基本查询
|
||||
const [testRows] = await connection.execute('SELECT 1 + 1 AS result');
|
||||
console.log(`✅ 基本查询测试: ${testRows[0].result}`);
|
||||
|
||||
// 检查数据库版本和字符集
|
||||
const [versionRows] = await connection.execute('SELECT VERSION() as version');
|
||||
console.log(`📊 MySQL版本: ${versionRows[0].version}`);
|
||||
|
||||
// 获取所有表
|
||||
console.log('\n📋 检查数据库表结构:');
|
||||
const [tables] = await connection.execute(`
|
||||
SELECT TABLE_NAME, TABLE_ROWS, DATA_LENGTH, INDEX_LENGTH, TABLE_COMMENT
|
||||
FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = ?
|
||||
ORDER BY TABLE_NAME
|
||||
`, [dbConfig.database]);
|
||||
|
||||
if (tables.length === 0) {
|
||||
console.log('⚠️ 数据库中没有找到任何表');
|
||||
console.log('💡 建议运行数据库结构创建脚本');
|
||||
return { success: false, message: '数据库为空' };
|
||||
}
|
||||
|
||||
console.log(`📊 找到 ${tables.length} 个表:`);
|
||||
let totalRows = 0;
|
||||
|
||||
for (const table of tables) {
|
||||
const rowCount = table.TABLE_ROWS || 0;
|
||||
totalRows += rowCount;
|
||||
const dataSize = (table.DATA_LENGTH / 1024).toFixed(2);
|
||||
const indexSize = (table.INDEX_LENGTH / 1024).toFixed(2);
|
||||
|
||||
console.log(` 📄 ${table.TABLE_NAME.padEnd(25)} | ${String(rowCount).padStart(6)} 行 | ${dataSize.padStart(8)} KB | ${table.TABLE_COMMENT || '无注释'}`);
|
||||
}
|
||||
|
||||
console.log(`\n📊 总记录数: ${totalRows}`);
|
||||
|
||||
// 检查核心表的详细结构
|
||||
console.log('\n🔍 检查核心表结构:');
|
||||
const coreTables = ['admins', 'users', 'merchants', 'animals', 'orders', 'payments'];
|
||||
|
||||
for (const tableName of coreTables) {
|
||||
const tableExists = tables.find(t => t.TABLE_NAME === tableName);
|
||||
|
||||
if (tableExists) {
|
||||
console.log(`\n📋 表: ${tableName}`);
|
||||
|
||||
// 获取表结构
|
||||
const [columns] = await connection.execute(`
|
||||
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_COMMENT
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
|
||||
ORDER BY ORDINAL_POSITION
|
||||
`, [dbConfig.database, tableName]);
|
||||
|
||||
console.log(' 字段结构:');
|
||||
for (const col of columns.slice(0, 10)) { // 只显示前10个字段
|
||||
const nullable = col.IS_NULLABLE === 'YES' ? '可空' : '非空';
|
||||
const defaultVal = col.COLUMN_DEFAULT ? `默认:${col.COLUMN_DEFAULT}` : '';
|
||||
console.log(` ${col.COLUMN_NAME.padEnd(20)} | ${col.DATA_TYPE.padEnd(15)} | ${nullable.padEnd(4)} | ${col.COLUMN_COMMENT || '无注释'}`);
|
||||
}
|
||||
|
||||
if (columns.length > 10) {
|
||||
console.log(` ... 还有 ${columns.length - 10} 个字段`);
|
||||
}
|
||||
|
||||
// 检查索引
|
||||
const [indexes] = await connection.execute(`
|
||||
SELECT INDEX_NAME, COLUMN_NAME, NON_UNIQUE
|
||||
FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
|
||||
ORDER BY INDEX_NAME, SEQ_IN_INDEX
|
||||
`, [dbConfig.database, tableName]);
|
||||
|
||||
if (indexes.length > 0) {
|
||||
console.log(' 索引:');
|
||||
const indexGroups = {};
|
||||
indexes.forEach(idx => {
|
||||
if (!indexGroups[idx.INDEX_NAME]) {
|
||||
indexGroups[idx.INDEX_NAME] = [];
|
||||
}
|
||||
indexGroups[idx.INDEX_NAME].push(idx.COLUMN_NAME);
|
||||
});
|
||||
|
||||
Object.entries(indexGroups).forEach(([indexName, columns]) => {
|
||||
const type = indexName === 'PRIMARY' ? '主键' : '索引';
|
||||
console.log(` ${type}: ${indexName} (${columns.join(', ')})`);
|
||||
});
|
||||
}
|
||||
|
||||
// 检查数据样例
|
||||
try {
|
||||
const [sampleData] = await connection.execute(`SELECT * FROM ${tableName} LIMIT 3`);
|
||||
if (sampleData.length > 0) {
|
||||
console.log(` 📊 数据样例: ${sampleData.length} 条记录`);
|
||||
} else {
|
||||
console.log(' 📊 数据样例: 表为空');
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(` ❌ 无法获取数据样例: ${error.message}`);
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log(`❌ 核心表不存在: ${tableName}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查外键约束
|
||||
console.log('\n🔗 检查外键约束:');
|
||||
const [foreignKeys] = await connection.execute(`
|
||||
SELECT
|
||||
TABLE_NAME,
|
||||
COLUMN_NAME,
|
||||
REFERENCED_TABLE_NAME,
|
||||
REFERENCED_COLUMN_NAME,
|
||||
CONSTRAINT_NAME
|
||||
FROM information_schema.KEY_COLUMN_USAGE
|
||||
WHERE TABLE_SCHEMA = ? AND REFERENCED_TABLE_NAME IS NOT NULL
|
||||
ORDER BY TABLE_NAME
|
||||
`, [dbConfig.database]);
|
||||
|
||||
if (foreignKeys.length > 0) {
|
||||
console.log(`📊 找到 ${foreignKeys.length} 个外键约束:`);
|
||||
foreignKeys.forEach(fk => {
|
||||
console.log(` ${fk.TABLE_NAME}.${fk.COLUMN_NAME} -> ${fk.REFERENCED_TABLE_NAME}.${fk.REFERENCED_COLUMN_NAME}`);
|
||||
});
|
||||
} else {
|
||||
console.log('⚠️ 没有找到外键约束');
|
||||
}
|
||||
|
||||
// 数据完整性检查
|
||||
console.log('\n🔍 数据完整性检查:');
|
||||
|
||||
// 检查管理员数据
|
||||
if (tables.find(t => t.TABLE_NAME === 'admins')) {
|
||||
const [adminCount] = await connection.execute('SELECT COUNT(*) as count FROM admins');
|
||||
console.log(`👨💼 管理员数量: ${adminCount[0].count}`);
|
||||
|
||||
if (adminCount[0].count > 0) {
|
||||
const [admins] = await connection.execute('SELECT username, role, status FROM admins LIMIT 5');
|
||||
admins.forEach(admin => {
|
||||
console.log(` - ${admin.username} (${admin.role}, 状态: ${admin.status})`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 检查用户数据
|
||||
if (tables.find(t => t.TABLE_NAME === 'users')) {
|
||||
const [userCount] = await connection.execute('SELECT COUNT(*) as count FROM users');
|
||||
console.log(`👥 用户数量: ${userCount[0].count}`);
|
||||
|
||||
if (userCount[0].count > 0) {
|
||||
const [userStats] = await connection.execute(`
|
||||
SELECT user_type, COUNT(*) as count
|
||||
FROM users
|
||||
GROUP BY user_type
|
||||
`);
|
||||
userStats.forEach(stat => {
|
||||
console.log(` - ${stat.user_type}: ${stat.count} 人`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n🎉 数据库结构检查完成!');
|
||||
|
||||
return {
|
||||
success: true,
|
||||
tableCount: tables.length,
|
||||
totalRows: totalRows,
|
||||
tables: tables.map(t => t.TABLE_NAME)
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 数据库结构检查失败:', error.message);
|
||||
console.error('🔍 错误代码:', error.code);
|
||||
return { success: false, error: error.message };
|
||||
} finally {
|
||||
if (connection) {
|
||||
await connection.end();
|
||||
console.log('🔒 数据库连接已关闭');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是直接运行此文件,则执行检查
|
||||
if (require.main === module) {
|
||||
checkDatabaseStructure()
|
||||
.then((result) => {
|
||||
process.exit(result.success ? 0 : 1);
|
||||
})
|
||||
.catch(() => process.exit(1));
|
||||
}
|
||||
|
||||
module.exports = { checkDatabaseStructure };
|
||||
370
backend/scripts/create-database-schema.sql
Normal file
370
backend/scripts/create-database-schema.sql
Normal file
@@ -0,0 +1,370 @@
|
||||
-- 解班客数据库完整结构创建脚本
|
||||
-- 创建时间: 2024年
|
||||
-- 数据库: jbkdata
|
||||
|
||||
-- 设置字符集
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- 使用数据库
|
||||
USE jbkdata;
|
||||
|
||||
-- ================================
|
||||
-- 1. 管理员表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `admins` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(50) NOT NULL COMMENT '用户名',
|
||||
`password` varchar(255) NOT NULL COMMENT '密码',
|
||||
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
|
||||
`nickname` varchar(50) DEFAULT NULL COMMENT '昵称',
|
||||
`avatar` varchar(255) DEFAULT NULL COMMENT '头像',
|
||||
`role` enum('super_admin','admin','operator') DEFAULT 'admin' COMMENT '角色',
|
||||
`status` tinyint(1) DEFAULT 1 COMMENT '状态 1:启用 0:禁用',
|
||||
`last_login` timestamp NULL DEFAULT NULL COMMENT '最后登录时间',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `username` (`username`),
|
||||
KEY `idx_email` (`email`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='管理员表';
|
||||
|
||||
-- ================================
|
||||
-- 2. 用户表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(50) NOT NULL COMMENT '用户名',
|
||||
`password_hash` varchar(255) NOT NULL COMMENT '密码哈希',
|
||||
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
|
||||
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
|
||||
`real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名',
|
||||
`avatar_url` varchar(255) DEFAULT NULL COMMENT '头像URL',
|
||||
`user_type` enum('farmer','tourist','merchant','admin') DEFAULT 'tourist' COMMENT '用户类型',
|
||||
`status` enum('active','inactive','banned') DEFAULT 'active' COMMENT '状态',
|
||||
`balance` decimal(15,2) DEFAULT 0.00 COMMENT '余额',
|
||||
`points` int(11) DEFAULT 0 COMMENT '积分',
|
||||
`level` tinyint(4) DEFAULT 1 COMMENT '用户等级',
|
||||
`last_login_at` timestamp NULL DEFAULT NULL COMMENT '最后登录时间',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `username` (`username`),
|
||||
UNIQUE KEY `email` (`email`),
|
||||
UNIQUE KEY `phone` (`phone`),
|
||||
KEY `idx_user_type` (`user_type`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_created_at` (`created_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
|
||||
|
||||
-- ================================
|
||||
-- 3. 商家表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `merchants` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(11) NOT NULL COMMENT '关联用户ID',
|
||||
`business_name` varchar(100) NOT NULL COMMENT '商家名称',
|
||||
`business_type` enum('restaurant','hotel','farm','attraction','transport') NOT NULL COMMENT '商家类型',
|
||||
`description` text COMMENT '商家描述',
|
||||
`address` varchar(255) DEFAULT NULL COMMENT '地址',
|
||||
`latitude` decimal(10,8) DEFAULT NULL COMMENT '纬度',
|
||||
`longitude` decimal(11,8) DEFAULT NULL COMMENT '经度',
|
||||
`contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
|
||||
`business_hours` json DEFAULT NULL COMMENT '营业时间',
|
||||
`images` json DEFAULT NULL COMMENT '商家图片',
|
||||
`rating` decimal(3,2) DEFAULT 0.00 COMMENT '评分',
|
||||
`review_count` int(11) DEFAULT 0 COMMENT '评价数量',
|
||||
`status` enum('pending','approved','rejected','suspended') DEFAULT 'pending' COMMENT '状态',
|
||||
`verified_at` timestamp NULL DEFAULT NULL COMMENT '认证时间',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `idx_business_type` (`business_type`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_location` (`latitude`,`longitude`),
|
||||
CONSTRAINT `merchants_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='商家表';
|
||||
|
||||
-- ================================
|
||||
-- 4. 动物表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `animals` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(50) NOT NULL COMMENT '动物名称',
|
||||
`type` enum('chicken','duck','pig','cow','sheep','rabbit','fish') NOT NULL COMMENT '动物类型',
|
||||
`breed` varchar(50) DEFAULT NULL COMMENT '品种',
|
||||
`age` int(11) DEFAULT NULL COMMENT '年龄(月)',
|
||||
`weight` decimal(8,2) DEFAULT NULL COMMENT '重量(kg)',
|
||||
`gender` enum('male','female','unknown') DEFAULT 'unknown' COMMENT '性别',
|
||||
`description` text COMMENT '描述',
|
||||
`image` varchar(255) DEFAULT NULL COMMENT '图片URL',
|
||||
`images` json DEFAULT NULL COMMENT '多张图片',
|
||||
`price` decimal(10,2) NOT NULL COMMENT '认领价格',
|
||||
`daily_cost` decimal(8,2) DEFAULT 0.00 COMMENT '每日费用',
|
||||
`location` varchar(100) DEFAULT NULL COMMENT '所在位置',
|
||||
`farmer_id` int(11) DEFAULT NULL COMMENT '农户ID',
|
||||
`status` enum('available','claimed','sold','deceased') DEFAULT 'available' COMMENT '状态',
|
||||
`health_status` enum('healthy','sick','recovering') DEFAULT 'healthy' COMMENT '健康状态',
|
||||
`vaccination_records` json DEFAULT NULL COMMENT '疫苗记录',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_type` (`type`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_farmer_id` (`farmer_id`),
|
||||
KEY `idx_price` (`price`),
|
||||
CONSTRAINT `animals_ibfk_1` FOREIGN KEY (`farmer_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='动物表';
|
||||
|
||||
-- ================================
|
||||
-- 5. 动物认领表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `animal_claims` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`claim_no` varchar(50) NOT NULL COMMENT '认领订单号',
|
||||
`animal_id` int(11) NOT NULL COMMENT '动物ID',
|
||||
`user_id` int(11) NOT NULL COMMENT '认领用户ID',
|
||||
`claim_reason` text COMMENT '认领原因',
|
||||
`claim_duration` int(11) NOT NULL COMMENT '认领时长(天)',
|
||||
`total_amount` decimal(10,2) NOT NULL COMMENT '总费用',
|
||||
`contact_info` json DEFAULT NULL COMMENT '联系信息',
|
||||
`status` enum('pending','approved','rejected','cancelled','completed') DEFAULT 'pending' COMMENT '状态',
|
||||
`reviewed_by` int(11) DEFAULT NULL COMMENT '审核人ID',
|
||||
`reviewed_at` timestamp NULL DEFAULT NULL COMMENT '审核时间',
|
||||
`review_note` text COMMENT '审核备注',
|
||||
`start_date` date DEFAULT NULL COMMENT '开始日期',
|
||||
`end_date` date DEFAULT NULL COMMENT '结束日期',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `claim_no` (`claim_no`),
|
||||
KEY `animal_id` (`animal_id`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_created_at` (`created_at`),
|
||||
CONSTRAINT `animal_claims_ibfk_1` FOREIGN KEY (`animal_id`) REFERENCES `animals` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `animal_claims_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='动物认领表';
|
||||
|
||||
-- ================================
|
||||
-- 6. 旅行计划表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `travel_plans` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`title` varchar(100) NOT NULL COMMENT '标题',
|
||||
`description` text COMMENT '描述',
|
||||
`destination` varchar(100) NOT NULL COMMENT '目的地',
|
||||
`start_date` date NOT NULL COMMENT '开始日期',
|
||||
`end_date` date NOT NULL COMMENT '结束日期',
|
||||
`max_participants` int(11) DEFAULT 20 COMMENT '最大参与人数',
|
||||
`current_participants` int(11) DEFAULT 0 COMMENT '当前参与人数',
|
||||
`price_per_person` decimal(10,2) NOT NULL COMMENT '每人价格',
|
||||
`includes` json DEFAULT NULL COMMENT '包含项目',
|
||||
`excludes` json DEFAULT NULL COMMENT '不包含项目',
|
||||
`itinerary` json DEFAULT NULL COMMENT '行程安排',
|
||||
`images` json DEFAULT NULL COMMENT '图片',
|
||||
`requirements` text COMMENT '参与要求',
|
||||
`created_by` int(11) NOT NULL COMMENT '创建者ID',
|
||||
`status` enum('draft','published','cancelled','completed') DEFAULT 'draft' COMMENT '状态',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `created_by` (`created_by`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_start_date` (`start_date`),
|
||||
KEY `idx_destination` (`destination`),
|
||||
CONSTRAINT `travel_plans_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='旅行计划表';
|
||||
|
||||
-- ================================
|
||||
-- 7. 旅行报名表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `travel_registrations` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`travel_plan_id` int(11) NOT NULL COMMENT '旅行计划ID',
|
||||
`user_id` int(11) NOT NULL COMMENT '用户ID',
|
||||
`participants` int(11) DEFAULT 1 COMMENT '参与人数',
|
||||
`message` text COMMENT '留言',
|
||||
`emergency_contact` varchar(50) DEFAULT NULL COMMENT '紧急联系人',
|
||||
`emergency_phone` varchar(20) DEFAULT NULL COMMENT '紧急联系电话',
|
||||
`status` enum('pending','approved','rejected','cancelled') DEFAULT 'pending' COMMENT '状态',
|
||||
`reject_reason` text COMMENT '拒绝原因',
|
||||
`applied_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '申请时间',
|
||||
`responded_at` timestamp NULL DEFAULT NULL COMMENT '响应时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `unique_registration` (`travel_plan_id`,`user_id`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `idx_status` (`status`),
|
||||
CONSTRAINT `travel_registrations_ibfk_1` FOREIGN KEY (`travel_plan_id`) REFERENCES `travel_plans` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `travel_registrations_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='旅行报名表';
|
||||
|
||||
-- ================================
|
||||
-- 8. 鲜花表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `flowers` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(50) NOT NULL COMMENT '花卉名称',
|
||||
`scientific_name` varchar(100) DEFAULT NULL COMMENT '学名',
|
||||
`category` enum('rose','lily','tulip','sunflower','orchid','carnation','other') NOT NULL COMMENT '花卉类别',
|
||||
`color` varchar(30) DEFAULT NULL COMMENT '颜色',
|
||||
`description` text COMMENT '描述',
|
||||
`care_instructions` text COMMENT '养护说明',
|
||||
`image` varchar(255) DEFAULT NULL COMMENT '主图片',
|
||||
`images` json DEFAULT NULL COMMENT '多张图片',
|
||||
`price` decimal(8,2) NOT NULL COMMENT '价格',
|
||||
`stock_quantity` int(11) DEFAULT 0 COMMENT '库存数量',
|
||||
`farmer_id` int(11) DEFAULT NULL COMMENT '农户ID',
|
||||
`status` enum('available','out_of_stock','discontinued') DEFAULT 'available' COMMENT '状态',
|
||||
`seasonal_availability` json DEFAULT NULL COMMENT '季节性供应',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_category` (`category`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_farmer_id` (`farmer_id`),
|
||||
KEY `idx_price` (`price`),
|
||||
CONSTRAINT `flowers_ibfk_1` FOREIGN KEY (`farmer_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='鲜花表';
|
||||
|
||||
-- ================================
|
||||
-- 9. 订单表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `orders` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`order_no` varchar(50) NOT NULL COMMENT '订单号',
|
||||
`user_id` int(11) NOT NULL COMMENT '用户ID',
|
||||
`type` enum('animal_claim','travel','flower','service') NOT NULL COMMENT '订单类型',
|
||||
`related_id` int(11) DEFAULT NULL COMMENT '关联ID',
|
||||
`title` varchar(200) NOT NULL COMMENT '订单标题',
|
||||
`description` text COMMENT '订单描述',
|
||||
`total_amount` decimal(15,2) NOT NULL COMMENT '总金额',
|
||||
`discount_amount` decimal(15,2) DEFAULT 0.00 COMMENT '优惠金额',
|
||||
`final_amount` decimal(15,2) NOT NULL COMMENT '实付金额',
|
||||
`status` enum('pending','paid','processing','shipped','completed','cancelled','refunded') DEFAULT 'pending' COMMENT '订单状态',
|
||||
`payment_status` enum('unpaid','paid','refunded','partial_refund') DEFAULT 'unpaid' COMMENT '支付状态',
|
||||
`payment_method` varchar(50) DEFAULT NULL COMMENT '支付方式',
|
||||
`payment_time` timestamp NULL DEFAULT NULL COMMENT '支付时间',
|
||||
`shipping_address` json DEFAULT NULL COMMENT '收货地址',
|
||||
`contact_info` json DEFAULT NULL COMMENT '联系信息',
|
||||
`notes` text COMMENT '备注',
|
||||
`ordered_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '下单时间',
|
||||
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `order_no` (`order_no`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `idx_type` (`type`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_payment_status` (`payment_status`),
|
||||
KEY `idx_ordered_at` (`ordered_at`),
|
||||
CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单表';
|
||||
|
||||
-- ================================
|
||||
-- 10. 支付表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `payments` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`payment_no` varchar(50) NOT NULL COMMENT '支付订单号',
|
||||
`order_id` int(11) NOT NULL COMMENT '订单ID',
|
||||
`user_id` int(11) NOT NULL COMMENT '用户ID',
|
||||
`amount` decimal(15,2) NOT NULL COMMENT '支付金额',
|
||||
`payment_method` enum('wechat','alipay','bank_card','balance') NOT NULL COMMENT '支付方式',
|
||||
`status` enum('pending','paid','failed','cancelled','refunded') DEFAULT 'pending' COMMENT '支付状态',
|
||||
`transaction_id` varchar(100) DEFAULT NULL COMMENT '第三方交易号',
|
||||
`paid_amount` decimal(15,2) DEFAULT NULL COMMENT '实际支付金额',
|
||||
`paid_at` timestamp NULL DEFAULT NULL COMMENT '支付时间',
|
||||
`failure_reason` varchar(255) DEFAULT NULL COMMENT '失败原因',
|
||||
`return_url` varchar(255) DEFAULT NULL COMMENT '返回URL',
|
||||
`notify_url` varchar(255) DEFAULT NULL COMMENT '通知URL',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `payment_no` (`payment_no`),
|
||||
KEY `order_id` (`order_id`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_payment_method` (`payment_method`),
|
||||
KEY `idx_created_at` (`created_at`),
|
||||
CONSTRAINT `payments_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `payments_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='支付表';
|
||||
|
||||
-- ================================
|
||||
-- 11. 退款表
|
||||
-- ================================
|
||||
CREATE TABLE IF NOT EXISTS `refunds` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`refund_no` varchar(50) NOT NULL COMMENT '退款订单号',
|
||||
`payment_id` int(11) NOT NULL COMMENT '支付ID',
|
||||
`user_id` int(11) NOT NULL COMMENT '用户ID',
|
||||
`refund_amount` decimal(15,2) NOT NULL COMMENT '退款金额',
|
||||
`refund_reason` varchar(255) NOT NULL COMMENT '退款原因',
|
||||
`status` enum('pending','processing','completed','rejected') DEFAULT 'pending' COMMENT '退款状态',
|
||||
`processed_by` int(11) DEFAULT NULL COMMENT '处理人ID',
|
||||
`processed_at` timestamp NULL DEFAULT NULL COMMENT '处理时间',
|
||||
`process_remark` text COMMENT '处理备注',
|
||||
`refund_transaction_id` varchar(100) DEFAULT NULL COMMENT '退款交易号',
|
||||
`refunded_at` timestamp NULL DEFAULT NULL COMMENT '退款完成时间',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `refund_no` (`refund_no`),
|
||||
KEY `payment_id` (`payment_id`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `idx_status` (`status`),
|
||||
CONSTRAINT `refunds_ibfk_1` FOREIGN KEY (`payment_id`) REFERENCES `payments` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `refunds_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='退款表';
|
||||
|
||||
-- ================================
|
||||
-- 12. 辅助表
|
||||
-- ================================
|
||||
|
||||
-- 邮箱验证表
|
||||
CREATE TABLE IF NOT EXISTS `email_verifications` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`email` varchar(100) NOT NULL COMMENT '邮箱',
|
||||
`code` varchar(10) NOT NULL COMMENT '验证码',
|
||||
`expires_at` timestamp NOT NULL COMMENT '过期时间',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `email` (`email`),
|
||||
KEY `idx_expires_at` (`expires_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='邮箱验证表';
|
||||
|
||||
-- 密码重置表
|
||||
CREATE TABLE IF NOT EXISTS `password_resets` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(11) NOT NULL COMMENT '用户ID',
|
||||
`token` varchar(255) NOT NULL COMMENT '重置令牌',
|
||||
`expires_at` timestamp NOT NULL COMMENT '过期时间',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `user_id` (`user_id`),
|
||||
UNIQUE KEY `token` (`token`),
|
||||
KEY `idx_expires_at` (`expires_at`),
|
||||
CONSTRAINT `password_resets_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='密码重置表';
|
||||
|
||||
-- 登录尝试表
|
||||
CREATE TABLE IF NOT EXISTS `login_attempts` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`identifier` varchar(100) NOT NULL COMMENT '标识符(用户名/邮箱/IP)',
|
||||
`attempts` int(11) DEFAULT 1 COMMENT '尝试次数',
|
||||
`last_attempt` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '最后尝试时间',
|
||||
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `identifier` (`identifier`),
|
||||
KEY `idx_last_attempt` (`last_attempt`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='登录尝试表';
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
-- 创建完成提示
|
||||
SELECT '数据库表结构创建完成!' as message;
|
||||
219
backend/scripts/init-test-data-complete.js
Normal file
219
backend/scripts/init-test-data-complete.js
Normal file
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* 完整测试数据初始化脚本
|
||||
* 用于开发环境创建完整的测试数据
|
||||
*/
|
||||
|
||||
const mysql = require('mysql2/promise');
|
||||
const bcrypt = require('bcryptjs');
|
||||
const config = require('../config/env');
|
||||
|
||||
async function initCompleteTestData() {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
console.log('🚀 开始初始化完整测试数据...');
|
||||
|
||||
// 创建数据库连接
|
||||
const dbConfig = {
|
||||
host: config.mysql.host,
|
||||
port: config.mysql.port,
|
||||
user: config.mysql.user,
|
||||
password: config.mysql.password,
|
||||
database: config.mysql.database,
|
||||
charset: config.mysql.charset,
|
||||
timezone: config.mysql.timezone
|
||||
};
|
||||
|
||||
connection = await mysql.createConnection(dbConfig);
|
||||
console.log('✅ 数据库连接成功');
|
||||
|
||||
// 清理现有测试数据(可选)
|
||||
console.log('🧹 清理现有测试数据...');
|
||||
const tablesToClean = [
|
||||
'refunds', 'payments', 'orders', 'travel_registrations', 'travel_plans',
|
||||
'animal_claims', 'animals', 'flowers', 'merchants', 'users', 'admins',
|
||||
'email_verifications', 'password_resets', 'login_attempts'
|
||||
];
|
||||
|
||||
for (const table of tablesToClean) {
|
||||
try {
|
||||
await connection.execute(`DELETE FROM ${table} WHERE id > 0`);
|
||||
await connection.execute(`ALTER TABLE ${table} AUTO_INCREMENT = 1`);
|
||||
console.log(` 清理表: ${table}`);
|
||||
} catch (error) {
|
||||
console.log(` 跳过表: ${table} (${error.message})`);
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 插入管理员数据
|
||||
console.log('👨💼 插入管理员数据...');
|
||||
const adminPassword = await bcrypt.hash('admin123', 10);
|
||||
const managerPassword = await bcrypt.hash('manager123', 10);
|
||||
|
||||
await connection.execute(`
|
||||
INSERT INTO admins (username, password, email, nickname, role, status) VALUES
|
||||
('admin', ?, 'admin@jiebanke.com', '超级管理员', 'super_admin', 1),
|
||||
('manager', ?, 'manager@jiebanke.com', '运营经理', 'admin', 1),
|
||||
('operator', ?, 'operator@jiebanke.com', '运营专员', 'operator', 1)
|
||||
`, [adminPassword, managerPassword, await bcrypt.hash('operator123', 10)]);
|
||||
console.log(' ✅ 管理员数据插入完成');
|
||||
|
||||
// 2. 插入用户数据
|
||||
console.log('👥 插入用户数据...');
|
||||
const userPassword = await bcrypt.hash('user123', 10);
|
||||
const farmerPassword = await bcrypt.hash('farmer123', 10);
|
||||
const merchantPassword = await bcrypt.hash('merchant123', 10);
|
||||
|
||||
await connection.execute(`
|
||||
INSERT INTO users (username, password_hash, email, phone, real_name, user_type, status, balance, points) VALUES
|
||||
('tourist1', ?, 'tourist1@jiebanke.com', '13800138001', '张三', 'tourist', 'active', 1000.00, 100),
|
||||
('tourist2', ?, 'tourist2@jiebanke.com', '13800138002', '李四', 'tourist', 'active', 500.00, 50),
|
||||
('farmer1', ?, 'farmer1@jiebanke.com', '13800138003', '王农夫', 'farmer', 'active', 2000.00, 200),
|
||||
('farmer2', ?, 'farmer2@jiebanke.com', '13800138004', '赵农民', 'farmer', 'active', 1500.00, 150),
|
||||
('merchant1', ?, 'merchant1@jiebanke.com', '13800138005', '刘老板', 'merchant', 'active', 5000.00, 500),
|
||||
('merchant2', ?, 'merchant2@jiebanke.com', '13800138006', '陈经理', 'merchant', 'active', 3000.00, 300)
|
||||
`, [userPassword, userPassword, farmerPassword, farmerPassword, merchantPassword, merchantPassword]);
|
||||
console.log(' ✅ 用户数据插入完成');
|
||||
|
||||
// 3. 插入商家数据
|
||||
console.log('🏪 插入商家数据...');
|
||||
await connection.execute(`
|
||||
INSERT INTO merchants (user_id, business_name, business_type, description, address, contact_phone, status) VALUES
|
||||
(5, '山水农家乐', 'restaurant', '提供正宗农家菜和住宿服务', '北京市密云区某某村', '13800138005', 'approved'),
|
||||
(6, '绿野仙踪度假村', 'hotel', '生态度假村,环境优美', '河北省承德市某某镇', '13800138006', 'approved')
|
||||
`);
|
||||
console.log(' ✅ 商家数据插入完成');
|
||||
|
||||
// 4. 插入动物数据
|
||||
console.log('🐷 插入动物数据...');
|
||||
await connection.execute(`
|
||||
INSERT INTO animals (name, type, breed, age, weight, gender, description, price, daily_cost, farmer_id, status) VALUES
|
||||
('小花', 'pig', '土猪', 6, 50.5, 'female', '健康活泼的小母猪', 800.00, 5.00, 3, 'available'),
|
||||
('大黄', 'chicken', '土鸡', 8, 2.5, 'male', '散养公鸡,肉质鲜美', 120.00, 2.00, 3, 'available'),
|
||||
('小白', 'sheep', '绵羊', 12, 35.0, 'female', '温顺的小绵羊', 600.00, 4.00, 4, 'available'),
|
||||
('老黑', 'cow', '黄牛', 24, 300.0, 'male', '强壮的耕牛', 2000.00, 10.00, 4, 'available'),
|
||||
('小灰', 'rabbit', '肉兔', 3, 1.8, 'female', '可爱的小兔子', 80.00, 1.50, 3, 'available')
|
||||
`);
|
||||
console.log(' ✅ 动物数据插入完成');
|
||||
|
||||
// 5. 插入鲜花数据
|
||||
console.log('🌸 插入鲜花数据...');
|
||||
await connection.execute(`
|
||||
INSERT INTO flowers (name, category, color, description, price, stock_quantity, farmer_id, status) VALUES
|
||||
('红玫瑰', 'rose', '红色', '经典红玫瑰,象征爱情', 15.00, 100, 3, 'available'),
|
||||
('白百合', 'lily', '白色', '纯洁的白百合,适合送礼', 25.00, 50, 3, 'available'),
|
||||
('黄郁金香', 'tulip', '黄色', '明亮的黄郁金香', 20.00, 80, 4, 'available'),
|
||||
('向日葵', 'sunflower', '黄色', '阳光般的向日葵', 12.00, 120, 4, 'available'),
|
||||
('粉康乃馨', 'carnation', '粉色', '温馨的粉色康乃馨', 18.00, 90, 3, 'available')
|
||||
`);
|
||||
console.log(' ✅ 鲜花数据插入完成');
|
||||
|
||||
// 6. 插入旅行计划数据
|
||||
console.log('✈️ 插入旅行计划数据...');
|
||||
await connection.execute(`
|
||||
INSERT INTO travel_plans (title, description, destination, start_date, end_date, max_participants, price_per_person, created_by, status) VALUES
|
||||
('密云水库生态游', '体验密云水库的自然风光,品尝农家美食', '北京密云', '2024-05-01', '2024-05-03', 20, 299.00, 5, 'published'),
|
||||
('承德避暑山庄文化游', '探访承德避暑山庄,了解清朝历史文化', '河北承德', '2024-06-15', '2024-06-17', 15, 599.00, 6, 'published'),
|
||||
('农场体验亲子游', '带孩子体验农场生活,学习农业知识', '北京郊区', '2024-07-01', '2024-07-02', 25, 199.00, 3, 'published')
|
||||
`);
|
||||
console.log(' ✅ 旅行计划数据插入完成');
|
||||
|
||||
// 7. 插入动物认领数据
|
||||
console.log('🐾 插入动物认领数据...');
|
||||
await connection.execute(`
|
||||
INSERT INTO animal_claims (claim_no, animal_id, user_id, claim_reason, claim_duration, total_amount, status, start_date, end_date) VALUES
|
||||
('AC202401001', 1, 1, '想体验养猪的乐趣', 30, 950.00, 'approved', '2024-04-01', '2024-04-30'),
|
||||
('AC202401002', 2, 2, '孩子喜欢小鸡', 15, 150.00, 'pending', '2024-04-15', '2024-04-29'),
|
||||
('AC202401003', 3, 1, '认领小羊作为宠物', 60, 840.00, 'approved', '2024-03-01', '2024-04-29')
|
||||
`);
|
||||
console.log(' ✅ 动物认领数据插入完成');
|
||||
|
||||
// 8. 插入旅行报名数据
|
||||
console.log('📝 插入旅行报名数据...');
|
||||
await connection.execute(`
|
||||
INSERT INTO travel_registrations (travel_plan_id, user_id, participants, message, emergency_contact, emergency_phone, status) VALUES
|
||||
(1, 1, 2, '期待这次旅行', '张三妻子', '13900139001', 'approved'),
|
||||
(1, 2, 1, '第一次参加农家游', '李四父亲', '13900139002', 'pending'),
|
||||
(2, 1, 3, '全家一起出游', '张三妻子', '13900139001', 'approved'),
|
||||
(3, 2, 2, '带孩子体验农场', '李四妻子', '13900139003', 'pending')
|
||||
`);
|
||||
console.log(' ✅ 旅行报名数据插入完成');
|
||||
|
||||
// 9. 插入订单数据
|
||||
console.log('📦 插入订单数据...');
|
||||
await connection.execute(`
|
||||
INSERT INTO orders (order_no, user_id, type, related_id, title, total_amount, final_amount, status, payment_status) VALUES
|
||||
('ORD202401001', 1, 'animal_claim', 1, '认领小花猪30天', 950.00, 950.00, 'completed', 'paid'),
|
||||
('ORD202401002', 2, 'animal_claim', 2, '认领大黄鸡15天', 150.00, 150.00, 'pending', 'unpaid'),
|
||||
('ORD202401003', 1, 'travel', 1, '密云水库生态游 2人', 598.00, 598.00, 'completed', 'paid'),
|
||||
('ORD202401004', 1, 'flower', 1, '红玫瑰 10支', 150.00, 150.00, 'completed', 'paid')
|
||||
`);
|
||||
console.log(' ✅ 订单数据插入完成');
|
||||
|
||||
// 10. 插入支付数据
|
||||
console.log('💳 插入支付数据...');
|
||||
await connection.execute(`
|
||||
INSERT INTO payments (payment_no, order_id, user_id, amount, payment_method, status, paid_amount, paid_at) VALUES
|
||||
('PAY202401001', 1, 1, 950.00, 'wechat', 'paid', 950.00, '2024-04-01 10:30:00'),
|
||||
('PAY202401002', 3, 1, 598.00, 'alipay', 'paid', 598.00, '2024-04-02 14:20:00'),
|
||||
('PAY202401003', 4, 1, 150.00, 'wechat', 'paid', 150.00, '2024-04-03 16:45:00')
|
||||
`);
|
||||
console.log(' ✅ 支付数据插入完成');
|
||||
|
||||
// 统计插入的数据
|
||||
console.log('\n📊 数据统计:');
|
||||
const tables = ['admins', 'users', 'merchants', 'animals', 'flowers', 'travel_plans', 'animal_claims', 'travel_registrations', 'orders', 'payments'];
|
||||
|
||||
for (const table of tables) {
|
||||
try {
|
||||
const [rows] = await connection.execute(`SELECT COUNT(*) as count FROM ${table}`);
|
||||
console.log(` ${table}: ${rows[0].count} 条记录`);
|
||||
} catch (error) {
|
||||
console.log(` ${table}: 表不存在或查询失败`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n🎉 完整测试数据初始化完成!');
|
||||
console.log('📋 测试账号信息:');
|
||||
console.log(' 管理员账号:');
|
||||
console.log(' admin / admin123 (超级管理员)');
|
||||
console.log(' manager / manager123 (运营经理)');
|
||||
console.log(' operator / operator123 (运营专员)');
|
||||
console.log(' 用户账号:');
|
||||
console.log(' tourist1 / user123 (游客)');
|
||||
console.log(' tourist2 / user123 (游客)');
|
||||
console.log(' farmer1 / farmer123 (农户)');
|
||||
console.log(' farmer2 / farmer123 (农户)');
|
||||
console.log(' merchant1 / merchant123 (商家)');
|
||||
console.log(' merchant2 / merchant123 (商家)');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 初始化测试数据失败:', error.message);
|
||||
if (error.code === 'ER_NO_SUCH_TABLE') {
|
||||
console.log('💡 提示: 请先运行数据库结构创建脚本');
|
||||
}
|
||||
throw error;
|
||||
} finally {
|
||||
if (connection) {
|
||||
await connection.end();
|
||||
console.log('🔒 数据库连接已关闭');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是直接运行此文件,则执行初始化
|
||||
if (require.main === module) {
|
||||
initCompleteTestData()
|
||||
.then(() => {
|
||||
console.log('✅ 脚本执行成功');
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('❌ 脚本执行失败:', error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { initCompleteTestData };
|
||||
124
backend/scripts/test-backend-connection.js
Normal file
124
backend/scripts/test-backend-connection.js
Normal file
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* 后端数据库连接测试脚本
|
||||
* 测试backend中的数据库连接配置是否正常工作
|
||||
*/
|
||||
|
||||
const { testConnection, query } = require('../src/config/database');
|
||||
|
||||
async function testBackendConnection() {
|
||||
console.log('🚀 测试后端数据库连接配置...');
|
||||
console.log('='.repeat(50));
|
||||
|
||||
try {
|
||||
// 测试数据库连接
|
||||
console.log('🔍 测试数据库连接...');
|
||||
const isConnected = await testConnection();
|
||||
|
||||
if (!isConnected) {
|
||||
console.error('❌ 数据库连接失败');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 测试查询功能
|
||||
console.log('🔍 测试查询功能...');
|
||||
const testResult = await query('SELECT 1 + 1 as result, NOW() as server_time');
|
||||
console.log(`✅ 查询测试成功: ${testResult[0].result}, 时间: ${testResult[0].server_time}`);
|
||||
|
||||
// 测试管理员数据查询
|
||||
console.log('🔍 测试管理员数据查询...');
|
||||
const admins = await query('SELECT id, username, role, status FROM admins LIMIT 3');
|
||||
console.log(`📊 管理员数据: ${admins.length} 条记录`);
|
||||
admins.forEach(admin => {
|
||||
console.log(` - ID:${admin.id} ${admin.username} (${admin.role}, 状态:${admin.status})`);
|
||||
});
|
||||
|
||||
// 测试用户数据查询
|
||||
console.log('🔍 测试用户数据查询...');
|
||||
const users = await query('SELECT id, username, user_type, status, balance FROM users LIMIT 5');
|
||||
console.log(`📊 用户数据: ${users.length} 条记录`);
|
||||
users.forEach(user => {
|
||||
console.log(` - ID:${user.id} ${user.username} (${user.user_type}, 余额:${user.balance})`);
|
||||
});
|
||||
|
||||
// 测试动物数据查询
|
||||
console.log('🔍 测试动物数据查询...');
|
||||
const animals = await query('SELECT id, name, type, price, status FROM animals LIMIT 5');
|
||||
console.log(`📊 动物数据: ${animals.length} 条记录`);
|
||||
animals.forEach(animal => {
|
||||
console.log(` - ID:${animal.id} ${animal.name} (${animal.type}, 价格:${animal.price})`);
|
||||
});
|
||||
|
||||
// 测试订单数据查询
|
||||
console.log('🔍 测试订单数据查询...');
|
||||
const orders = await query(`
|
||||
SELECT o.id, o.order_no, o.type, o.final_amount, o.status, u.username
|
||||
FROM orders o
|
||||
LEFT JOIN users u ON o.user_id = u.id
|
||||
LIMIT 5
|
||||
`);
|
||||
console.log(`📊 订单数据: ${orders.length} 条记录`);
|
||||
orders.forEach(order => {
|
||||
console.log(` - ${order.order_no} (${order.type}, ¥${order.final_amount}, ${order.status}) - ${order.username}`);
|
||||
});
|
||||
|
||||
// 测试支付数据查询
|
||||
console.log('🔍 测试支付数据查询...');
|
||||
const payments = await query(`
|
||||
SELECT p.id, p.payment_no, p.amount, p.payment_method, p.status, u.username
|
||||
FROM payments p
|
||||
LEFT JOIN users u ON p.user_id = u.id
|
||||
LIMIT 5
|
||||
`);
|
||||
console.log(`📊 支付数据: ${payments.length} 条记录`);
|
||||
payments.forEach(payment => {
|
||||
console.log(` - ${payment.payment_no} (¥${payment.amount}, ${payment.payment_method}, ${payment.status}) - ${payment.username}`);
|
||||
});
|
||||
|
||||
// 统计数据
|
||||
console.log('\n📊 数据库统计:');
|
||||
const stats = await query(`
|
||||
SELECT
|
||||
(SELECT COUNT(*) FROM admins) as admin_count,
|
||||
(SELECT COUNT(*) FROM users) as user_count,
|
||||
(SELECT COUNT(*) FROM merchants) as merchant_count,
|
||||
(SELECT COUNT(*) FROM animals) as animal_count,
|
||||
(SELECT COUNT(*) FROM flowers) as flower_count,
|
||||
(SELECT COUNT(*) FROM travel_plans) as travel_plan_count,
|
||||
(SELECT COUNT(*) FROM orders) as order_count,
|
||||
(SELECT COUNT(*) FROM payments) as payment_count
|
||||
`);
|
||||
|
||||
const stat = stats[0];
|
||||
console.log(` 管理员: ${stat.admin_count} 个`);
|
||||
console.log(` 用户: ${stat.user_count} 个`);
|
||||
console.log(` 商家: ${stat.merchant_count} 个`);
|
||||
console.log(` 动物: ${stat.animal_count} 个`);
|
||||
console.log(` 鲜花: ${stat.flower_count} 个`);
|
||||
console.log(` 旅行计划: ${stat.travel_plan_count} 个`);
|
||||
console.log(` 订单: ${stat.order_count} 个`);
|
||||
console.log(` 支付记录: ${stat.payment_count} 个`);
|
||||
|
||||
console.log('\n🎉 后端数据库连接测试完成!');
|
||||
console.log('✅ 所有功能正常');
|
||||
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 后端数据库连接测试失败:', error.message);
|
||||
console.error('🔍 错误详情:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是直接运行此文件,则执行测试
|
||||
if (require.main === module) {
|
||||
testBackendConnection()
|
||||
.then((success) => {
|
||||
process.exit(success ? 0 : 1);
|
||||
})
|
||||
.catch(() => process.exit(1));
|
||||
}
|
||||
|
||||
module.exports = { testBackendConnection };
|
||||
204
backend/scripts/test-database-connection-fixed.js
Normal file
204
backend/scripts/test-database-connection-fixed.js
Normal file
@@ -0,0 +1,204 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* 数据库连接测试脚本 - 修复版
|
||||
* 用于验证MySQL数据库连接配置的正确性
|
||||
*/
|
||||
|
||||
const mysql = require('mysql2/promise');
|
||||
const config = require('../config/env');
|
||||
|
||||
async function testDatabaseConnection() {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
console.log('🚀 开始数据库连接测试...');
|
||||
console.log(`📊 环境: ${process.env.NODE_ENV || 'development'}`);
|
||||
|
||||
// 使用env.js中的mysql配置
|
||||
const dbConfig = {
|
||||
host: config.mysql.host,
|
||||
port: config.mysql.port,
|
||||
user: config.mysql.user,
|
||||
password: config.mysql.password,
|
||||
database: config.mysql.database,
|
||||
charset: config.mysql.charset,
|
||||
timezone: config.mysql.timezone
|
||||
};
|
||||
|
||||
console.log(`🔗 连接信息: ${dbConfig.host}:${dbConfig.port}/${dbConfig.database}`);
|
||||
console.log('='.repeat(50));
|
||||
|
||||
// 测试连接
|
||||
console.log('🔍 测试数据库连接...');
|
||||
connection = await mysql.createConnection(dbConfig);
|
||||
console.log('✅ 数据库连接成功');
|
||||
|
||||
// 测试查询
|
||||
console.log('🔍 测试基本查询...');
|
||||
const [rows] = await connection.execute('SELECT 1 + 1 AS result, NOW() as current_time');
|
||||
console.log(`✅ 查询测试成功: ${rows[0].result}, 服务器时间: ${rows[0].current_time}`);
|
||||
|
||||
// 检查数据库版本
|
||||
console.log('🔍 检查数据库版本...');
|
||||
const [versionRows] = await connection.execute('SELECT VERSION() as version');
|
||||
console.log(`📊 MySQL版本: ${versionRows[0].version}`);
|
||||
|
||||
// 检查数据库字符集
|
||||
console.log('🔍 检查数据库字符集...');
|
||||
const [charsetRows] = await connection.execute(
|
||||
'SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = ?',
|
||||
[dbConfig.database]
|
||||
);
|
||||
if (charsetRows.length > 0) {
|
||||
console.log(`📝 数据库字符集: ${charsetRows[0].DEFAULT_CHARACTER_SET_NAME}`);
|
||||
console.log(`📝 数据库排序规则: ${charsetRows[0].DEFAULT_COLLATION_NAME}`);
|
||||
}
|
||||
|
||||
// 检查表结构
|
||||
console.log('🔍 检查核心表结构...');
|
||||
const tablesToCheck = [
|
||||
'admins', 'users', 'merchants', 'orders', 'payments',
|
||||
'animals', 'animal_claims', 'travel_plans', 'travel_registrations',
|
||||
'flowers', 'flower_orders'
|
||||
];
|
||||
|
||||
const existingTables = [];
|
||||
const missingTables = [];
|
||||
|
||||
for (const table of tablesToCheck) {
|
||||
try {
|
||||
const [tableInfo] = await connection.execute(
|
||||
`SELECT COUNT(*) as count FROM information_schema.tables
|
||||
WHERE table_schema = ? AND table_name = ?`,
|
||||
[dbConfig.database, table]
|
||||
);
|
||||
|
||||
if (tableInfo[0].count > 0) {
|
||||
console.log(`✅ 表存在: ${table}`);
|
||||
existingTables.push(table);
|
||||
|
||||
// 检查表记录数
|
||||
const [countRows] = await connection.execute(`SELECT COUNT(*) as count FROM ${table}`);
|
||||
console.log(` 📊 记录数: ${countRows[0].count}`);
|
||||
} else {
|
||||
console.log(`⚠️ 表不存在: ${table}`);
|
||||
missingTables.push(table);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(`❌ 检查表失败: ${table} - ${error.message}`);
|
||||
missingTables.push(table);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查管理员表数据
|
||||
if (existingTables.includes('admins')) {
|
||||
console.log('🔍 检查管理员数据...');
|
||||
try {
|
||||
const [adminCount] = await connection.execute('SELECT COUNT(*) as count FROM admins');
|
||||
console.log(`📊 管理员记录数: ${adminCount[0].count}`);
|
||||
|
||||
if (adminCount[0].count > 0) {
|
||||
const [admins] = await connection.execute('SELECT username, role, status FROM admins LIMIT 5');
|
||||
console.log('👥 管理员样例:');
|
||||
admins.forEach(admin => {
|
||||
console.log(` - ${admin.username} (${admin.role}, 状态: ${admin.status})`);
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('❌ 检查管理员数据失败:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查用户表数据
|
||||
if (existingTables.includes('users')) {
|
||||
console.log('🔍 检查用户数据...');
|
||||
try {
|
||||
const [userCount] = await connection.execute('SELECT COUNT(*) as count FROM users');
|
||||
console.log(`📊 用户记录数: ${userCount[0].count}`);
|
||||
|
||||
if (userCount[0].count > 0) {
|
||||
const [users] = await connection.execute('SELECT username, user_type, status FROM users LIMIT 5');
|
||||
console.log('👤 用户样例:');
|
||||
users.forEach(user => {
|
||||
console.log(` - ${user.username} (${user.user_type || '未知'}, 状态: ${user.status})`);
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('❌ 检查用户数据失败:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查连接池配置
|
||||
console.log('🔍 检查连接配置...');
|
||||
console.log(`📈 连接池限制: ${config.mysql.connectionLimit || 10}`);
|
||||
console.log(`🔤 字符集: ${config.mysql.charset}`);
|
||||
console.log(`⏰ 时区: ${config.mysql.timezone}`);
|
||||
|
||||
console.log('\n📋 数据库状态总结:');
|
||||
console.log(`✅ 存在的表: ${existingTables.length}/${tablesToCheck.length}`);
|
||||
if (missingTables.length > 0) {
|
||||
console.log(`⚠️ 缺失的表: ${missingTables.join(', ')}`);
|
||||
console.log('💡 建议运行数据库迁移脚本创建缺失的表');
|
||||
}
|
||||
|
||||
console.log('\n🎉 数据库连接测试完成!');
|
||||
console.log('✅ 数据库连接正常');
|
||||
|
||||
return {
|
||||
success: true,
|
||||
existingTables,
|
||||
missingTables,
|
||||
dbConfig: {
|
||||
host: dbConfig.host,
|
||||
port: dbConfig.port,
|
||||
database: dbConfig.database,
|
||||
user: dbConfig.user
|
||||
}
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 数据库连接测试失败:', error.message);
|
||||
console.error('💡 可能的原因:');
|
||||
console.error(' - 数据库服务未启动');
|
||||
console.error(' - 连接配置错误');
|
||||
console.error(' - 网络连接问题');
|
||||
console.error(' - 数据库权限不足');
|
||||
console.error(' - 防火墙限制');
|
||||
console.error(' - IP地址未授权');
|
||||
|
||||
if (error.code) {
|
||||
console.error(`🔍 错误代码: ${error.code}`);
|
||||
}
|
||||
|
||||
console.error('🔍 连接详情:', {
|
||||
host: config.mysql.host,
|
||||
port: config.mysql.port,
|
||||
user: config.mysql.user,
|
||||
database: config.mysql.database
|
||||
});
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: error.message,
|
||||
code: error.code
|
||||
};
|
||||
|
||||
} finally {
|
||||
if (connection) {
|
||||
await connection.end();
|
||||
console.log('🔒 数据库连接已关闭');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是直接运行此文件,则执行测试
|
||||
if (require.main === module) {
|
||||
testDatabaseConnection()
|
||||
.then((result) => {
|
||||
process.exit(result.success ? 0 : 1);
|
||||
})
|
||||
.catch(() => process.exit(1));
|
||||
}
|
||||
|
||||
module.exports = { testDatabaseConnection };
|
||||
466
docs/API接口文档.md
466
docs/API接口文档.md
@@ -1,466 +0,0 @@
|
||||
# 📚 结伴客API接口文档
|
||||
|
||||
## 📋 文档说明
|
||||
|
||||
本文档详细描述了结伴客项目的所有API接口,包括请求参数、响应格式和错误代码。结伴客是一个专注于结伴旅行和动物认领的社交平台。
|
||||
|
||||
**基础信息:**
|
||||
- 基础URL:`https://api.jiebanke.com`
|
||||
- API版本:`v1`
|
||||
- 数据格式:`JSON`
|
||||
- 字符编码:`UTF-8`
|
||||
|
||||
## 🔐 认证方式
|
||||
|
||||
### JWT Token 认证
|
||||
所有需要认证的API必须在请求头中携带Token:
|
||||
```http
|
||||
Authorization: Bearer <your_jwt_token>
|
||||
```
|
||||
|
||||
### Token 获取
|
||||
通过微信登录接口获取Token,Token有效期为7天。
|
||||
|
||||
## 📊 通用响应格式
|
||||
|
||||
### 成功响应
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
// 具体数据内容
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 错误响应
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"message": "错误描述",
|
||||
"error": "详细错误信息"
|
||||
}
|
||||
```
|
||||
|
||||
### 状态码说明
|
||||
- `200`: 请求成功
|
||||
- `400`: 请求参数错误
|
||||
- `401`: 未授权访问
|
||||
- `403`: 权限不足
|
||||
- `404`: 资源不存在
|
||||
- `500`: 服务器内部错误
|
||||
|
||||
## 👥 用户管理模块
|
||||
|
||||
### 微信用户登录
|
||||
|
||||
**接口地址:** `POST /api/v1/auth/wechat-login`
|
||||
|
||||
**接口描述:** 用户通过微信授权登录系统
|
||||
|
||||
**请求参数:**
|
||||
```json
|
||||
{
|
||||
"code": "string, required, 微信登录授权码",
|
||||
"userInfo": {
|
||||
"nickName": "string, required, 用户昵称",
|
||||
"avatarUrl": "string, required, 用户头像URL",
|
||||
"gender": "number, optional, 性别(0:未知,1:男,2:女)",
|
||||
"province": "string, optional, 省份",
|
||||
"city": "string, optional, 城市"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例:**
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "登录成功",
|
||||
"data": {
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"user": {
|
||||
"id": 1,
|
||||
"openid": "wx1234567890",
|
||||
"nickname": "旅行达人",
|
||||
"avatar": "https://avatar.url",
|
||||
"gender": "male",
|
||||
"phone": "13800138000",
|
||||
"isNewUser": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 获取用户信息
|
||||
|
||||
**接口地址:** `GET /api/v1/users/profile`
|
||||
|
||||
**接口描述:** 获取当前登录用户的详细信息
|
||||
|
||||
**请求头:**
|
||||
```http
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**响应示例:**
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"openid": "wx1234567890",
|
||||
"nickname": "旅行达人",
|
||||
"avatar": "https://avatar.url",
|
||||
"gender": "male",
|
||||
"birthday": "1990-01-01",
|
||||
"phone": "13800138000",
|
||||
"email": "user@jiebanke.com",
|
||||
"travelCount": 5,
|
||||
"animalClaimCount": 2,
|
||||
"createdAt": "2024-01-01T00:00:00.000Z",
|
||||
"updatedAt": "2024-01-01T00:00:00.000Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 更新用户信息
|
||||
|
||||
**接口地址:** `PUT /api/v1/users/profile`
|
||||
|
||||
**接口描述:** 更新用户个人信息
|
||||
|
||||
**请求参数:**
|
||||
```json
|
||||
{
|
||||
"nickname": "string, optional, 用户昵称",
|
||||
"avatar": "string, optional, 头像URL",
|
||||
"birthday": "string, optional, 生日(YYYY-MM-DD)",
|
||||
"phone": "string, optional, 手机号码",
|
||||
"email": "string, optional, 邮箱地址",
|
||||
"interests": "array, optional, 兴趣爱好标签"
|
||||
}
|
||||
```
|
||||
|
||||
## 🧳 旅行结伴模块
|
||||
|
||||
### 发布旅行计划
|
||||
|
||||
**接口地址:** `POST /api/v1/travel/plans`
|
||||
|
||||
**接口描述:** 用户发布新的旅行计划
|
||||
|
||||
**请求参数:**
|
||||
```json
|
||||
{
|
||||
"destination": "string, required, 目的地",
|
||||
"startDate": "string, required, 开始日期(YYYY-MM-DD)",
|
||||
"endDate": "string, required, 结束日期(YYYY-MM-DD)",
|
||||
"budget": "number, optional, 预算金额",
|
||||
"interests": "string, optional, 兴趣偏好",
|
||||
"description": "string, optional, 行程描述",
|
||||
"visibility": "string, optional, 可见性(public/friends/private)",
|
||||
"maxParticipants": "number, optional, 最大参与人数"
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例:**
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "旅行计划发布成功",
|
||||
"data": {
|
||||
"id": 1001,
|
||||
"userId": 1,
|
||||
"destination": "云南大理",
|
||||
"startDate": "2024-06-01",
|
||||
"endDate": "2024-06-07",
|
||||
"budget": 2000,
|
||||
"interests": "美食,摄影,文化",
|
||||
"status": "active",
|
||||
"participantCount": 1,
|
||||
"maxParticipants": 4,
|
||||
"createdAt": "2024-01-01T00:00:00.000Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 获取旅行计划列表
|
||||
|
||||
**接口地址:** `GET /api/v1/travel/plans`
|
||||
|
||||
**接口描述:** 获取旅行计划列表,支持筛选和分页
|
||||
|
||||
**查询参数:**
|
||||
```
|
||||
page: number, optional, 页码(默认1)
|
||||
limit: number, optional, 每页数量(默认10)
|
||||
destination: string, optional, 目的地筛选
|
||||
startDate: string, optional, 开始日期筛选
|
||||
endDate: string, optional, 结束日期筛选
|
||||
budget: number, optional, 预算筛选
|
||||
status: string, optional, 状态筛选(active/completed/cancelled)
|
||||
```
|
||||
|
||||
**响应示例:**
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取成功",
|
||||
"data": {
|
||||
"plans": [
|
||||
{
|
||||
"id": 1001,
|
||||
"user": {
|
||||
"id": 1,
|
||||
"nickname": "旅行达人",
|
||||
"avatar": "https://avatar.url"
|
||||
},
|
||||
"destination": "云南大理",
|
||||
"startDate": "2024-06-01",
|
||||
"endDate": "2024-06-07",
|
||||
"budget": 2000,
|
||||
"participantCount": 2,
|
||||
"maxParticipants": 4,
|
||||
"status": "active"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"total": 25,
|
||||
"totalPages": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 申请加入旅行计划
|
||||
|
||||
**接口地址:** `POST /api/v1/travel/plans/{planId}/join`
|
||||
|
||||
**接口描述:** 申请加入指定的旅行计划
|
||||
|
||||
**请求参数:**
|
||||
```json
|
||||
{
|
||||
"message": "string, optional, 申请留言"
|
||||
}
|
||||
```
|
||||
|
||||
## 🐄 动物认领模块
|
||||
|
||||
### 获取可认领动物列表
|
||||
|
||||
**接口地址:** `GET /api/v1/animals/available`
|
||||
|
||||
**接口描述:** 获取可认领的动物列表
|
||||
|
||||
**查询参数:**
|
||||
```
|
||||
type: string, optional, 动物类型(cow/sheep/pig/chicken)
|
||||
farmId: number, optional, 农场ID筛选
|
||||
page: number, optional, 页码
|
||||
limit: number, optional, 每页数量
|
||||
```
|
||||
|
||||
**响应示例:**
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "获取成功",
|
||||
"data": {
|
||||
"animals": [
|
||||
{
|
||||
"id": 2001,
|
||||
"name": "小花牛",
|
||||
"type": "cow",
|
||||
"age": 6,
|
||||
"gender": "female",
|
||||
"description": "温顺可爱的小花牛",
|
||||
"images": ["https://image1.url", "https://image2.url"],
|
||||
"price": 1200,
|
||||
"farm": {
|
||||
"id": 101,
|
||||
"name": "阳光农场",
|
||||
"location": "四川成都"
|
||||
},
|
||||
"status": "available"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"total": 15
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 认领动物
|
||||
|
||||
**接口地址:** `POST /api/v1/animals/{animalId}/claim`
|
||||
|
||||
**接口描述:** 认领指定的动物
|
||||
|
||||
**请求参数:**
|
||||
```json
|
||||
{
|
||||
"duration": "number, required, 认领时长(月)",
|
||||
"message": "string, optional, 认领留言"
|
||||
}
|
||||
```
|
||||
|
||||
### 获取我的认领记录
|
||||
|
||||
**接口地址:** `GET /api/v1/animals/my-claims`
|
||||
|
||||
**接口描述:** 获取当前用户的动物认领记录
|
||||
|
||||
## 🏪 商家服务模块
|
||||
|
||||
### 商家注册
|
||||
|
||||
**接口地址:** `POST /api/v1/merchants/register`
|
||||
|
||||
**接口描述:** 商家用户注册
|
||||
|
||||
**请求参数:**
|
||||
```json
|
||||
{
|
||||
"businessName": "string, required, 商家名称",
|
||||
"businessType": "string, required, 商家类型(flower_shop/farm/activity_organizer)",
|
||||
"contactName": "string, required, 联系人姓名",
|
||||
"contactPhone": "string, required, 联系电话",
|
||||
"businessLicense": "string, required, 营业执照号",
|
||||
"address": "string, required, 经营地址",
|
||||
"description": "string, optional, 商家描述"
|
||||
}
|
||||
```
|
||||
|
||||
### 获取商家产品列表
|
||||
|
||||
**接口地址:** `GET /api/v1/merchants/{merchantId}/products`
|
||||
|
||||
**接口描述:** 获取指定商家的产品列表
|
||||
|
||||
## 📦 订单管理模块
|
||||
|
||||
### 创建订单
|
||||
|
||||
**接口地址:** `POST /api/v1/orders`
|
||||
|
||||
**接口描述:** 创建新订单
|
||||
|
||||
**请求参数:**
|
||||
```json
|
||||
{
|
||||
"type": "string, required, 订单类型(animal_claim/product_purchase/activity_booking)",
|
||||
"items": [
|
||||
{
|
||||
"itemId": "number, required, 商品/服务ID",
|
||||
"quantity": "number, required, 数量",
|
||||
"price": "number, required, 单价"
|
||||
}
|
||||
],
|
||||
"totalAmount": "number, required, 总金额",
|
||||
"deliveryAddress": "object, optional, 配送地址信息"
|
||||
}
|
||||
```
|
||||
|
||||
### 获取订单列表
|
||||
|
||||
**接口地址:** `GET /api/v1/orders`
|
||||
|
||||
**接口描述:** 获取用户订单列表
|
||||
|
||||
**查询参数:**
|
||||
```
|
||||
status: string, optional, 订单状态筛选
|
||||
type: string, optional, 订单类型筛选
|
||||
page: number, optional, 页码
|
||||
limit: number, optional, 每页数量
|
||||
```
|
||||
|
||||
## 🎯 活动管理模块
|
||||
|
||||
### 获取活动列表
|
||||
|
||||
**接口地址:** `GET /api/v1/activities`
|
||||
|
||||
**接口描述:** 获取活动列表
|
||||
|
||||
**查询参数:**
|
||||
```
|
||||
type: string, optional, 活动类型
|
||||
location: string, optional, 地点筛选
|
||||
date: string, optional, 日期筛选
|
||||
status: string, optional, 状态筛选
|
||||
```
|
||||
|
||||
### 报名参加活动
|
||||
|
||||
**接口地址:** `POST /api/v1/activities/{activityId}/register`
|
||||
|
||||
**接口描述:** 报名参加指定活动
|
||||
|
||||
## 💬 消息通知模块
|
||||
|
||||
### 获取消息列表
|
||||
|
||||
**接口地址:** `GET /api/v1/messages`
|
||||
|
||||
**接口描述:** 获取用户消息列表
|
||||
|
||||
### 发送消息
|
||||
|
||||
**接口地址:** `POST /api/v1/messages`
|
||||
|
||||
**接口描述:** 发送消息给其他用户
|
||||
|
||||
## 🔧 系统管理模块
|
||||
|
||||
### 获取系统配置
|
||||
|
||||
**接口地址:** `GET /api/v1/system/config`
|
||||
|
||||
**接口描述:** 获取系统配置信息
|
||||
|
||||
### 文件上传
|
||||
|
||||
**接口地址:** `POST /api/v1/upload`
|
||||
|
||||
**接口描述:** 上传文件(图片、文档等)
|
||||
|
||||
**请求格式:** `multipart/form-data`
|
||||
|
||||
**请求参数:**
|
||||
```
|
||||
file: File, required, 上传的文件
|
||||
type: string, optional, 文件类型(avatar/product/document)
|
||||
```
|
||||
|
||||
## 📱 错误代码参考
|
||||
|
||||
| 错误代码 | 错误描述 | 解决方案 |
|
||||
|---------|---------|---------|
|
||||
| 400 | 请求参数错误 | 检查请求参数格式和必填项 |
|
||||
| 401 | 未授权访问 | 检查Token是否有效 |
|
||||
| 403 | 权限不足 | 检查用户权限 |
|
||||
| 404 | 资源不存在 | 检查请求的资源ID |
|
||||
| 409 | 资源冲突 | 检查是否重复操作 |
|
||||
| 429 | 请求频率限制 | 降低请求频率 |
|
||||
| 500 | 服务器内部错误 | 联系技术支持 |
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如有API使用问题,请联系技术支持:
|
||||
- 邮箱:tech-support@jiebanke.com
|
||||
- 微信群:结伴客开发者群
|
||||
|
||||
---
|
||||
|
||||
*文档版本:v1.0*
|
||||
*最后更新:2025年1月*
|
||||
1659
docs/前端开发文档.md
1659
docs/前端开发文档.md
File diff suppressed because it is too large
Load Diff
@@ -1,478 +0,0 @@
|
||||
# 动物认领系统API文档
|
||||
|
||||
## 概述
|
||||
|
||||
动物认领系统提供了完整的动物认领申请、审核、管理功能,支持用户申请认领动物、管理员审核申请、认领续期等功能。
|
||||
|
||||
## 基础信息
|
||||
|
||||
- **基础URL**: `/api/v1/animal-claims`
|
||||
- **认证方式**: Bearer Token
|
||||
- **数据格式**: JSON
|
||||
- **字符编码**: UTF-8
|
||||
|
||||
## 数据模型
|
||||
|
||||
### 认领申请 (AnimalClaim)
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"claim_no": "CLAIM20241201001",
|
||||
"animal_id": 1,
|
||||
"animal_name": "小白",
|
||||
"animal_type": "狗",
|
||||
"animal_image": "/uploads/animals/dog1.jpg",
|
||||
"user_id": 2,
|
||||
"username": "张三",
|
||||
"user_phone": "13800138001",
|
||||
"claim_reason": "我很喜欢这只小狗",
|
||||
"claim_duration": 12,
|
||||
"total_amount": 1200.00,
|
||||
"contact_info": "手机:13800138001,微信:user001",
|
||||
"status": "pending",
|
||||
"start_date": "2024-12-01T11:30:00.000Z",
|
||||
"end_date": "2025-12-01T11:30:00.000Z",
|
||||
"reviewed_by": 1,
|
||||
"reviewer_name": "管理员",
|
||||
"review_remark": "申请材料完整,同意认领",
|
||||
"reviewed_at": "2024-12-01T11:30:00.000Z",
|
||||
"approved_at": "2024-12-01T11:30:00.000Z",
|
||||
"cancelled_at": null,
|
||||
"cancel_reason": null,
|
||||
"created_at": "2024-12-01T10:00:00.000Z",
|
||||
"updated_at": "2024-12-01T11:30:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 认领统计 (ClaimStatistics)
|
||||
|
||||
```json
|
||||
{
|
||||
"basic": {
|
||||
"total_claims": 100,
|
||||
"pending_claims": 10,
|
||||
"approved_claims": 80,
|
||||
"rejected_claims": 8,
|
||||
"cancelled_claims": 2,
|
||||
"total_amount": 120000.00,
|
||||
"avg_duration": 12.5
|
||||
},
|
||||
"by_type": [
|
||||
{
|
||||
"type": "狗",
|
||||
"claim_count": 50,
|
||||
"approved_count": 45,
|
||||
"total_amount": 60000.00
|
||||
}
|
||||
],
|
||||
"by_month": [
|
||||
{
|
||||
"month": "2024-12",
|
||||
"claim_count": 20,
|
||||
"approved_count": 18,
|
||||
"total_amount": 24000.00
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## API接口
|
||||
|
||||
### 1. 申请认领动物
|
||||
|
||||
**接口地址**: `POST /api/v1/animal-claims`
|
||||
|
||||
**请求头**:
|
||||
```
|
||||
Authorization: Bearer {token}
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"animal_id": 1,
|
||||
"claim_reason": "我很喜欢这只小狗,希望能够认领它",
|
||||
"claim_duration": 12,
|
||||
"contact_info": "手机:13800138001,微信:user001"
|
||||
}
|
||||
```
|
||||
|
||||
**参数说明**:
|
||||
- `animal_id` (必填): 动物ID
|
||||
- `claim_reason` (可选): 认领理由
|
||||
- `claim_duration` (可选): 认领时长(月),默认12个月,范围1-60
|
||||
- `contact_info` (必填): 联系方式
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "认领申请提交成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"claim_no": "CLAIM20241201001",
|
||||
"animal_id": 1,
|
||||
"user_id": 2,
|
||||
"status": "pending",
|
||||
"total_amount": 1200.00
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 获取我的认领申请列表
|
||||
|
||||
**接口地址**: `GET /api/v1/animal-claims/my`
|
||||
|
||||
**请求参数**:
|
||||
- `page` (可选): 页码,默认1
|
||||
- `limit` (可选): 每页数量,默认10,最大100
|
||||
- `status` (可选): 申请状态 (pending/approved/rejected/cancelled)
|
||||
- `animal_type` (可选): 动物类型
|
||||
- `start_date` (可选): 开始日期 (YYYY-MM-DD)
|
||||
- `end_date` (可选): 结束日期 (YYYY-MM-DD)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "获取认领申请列表成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"claim_no": "CLAIM20241201001",
|
||||
"animal_name": "小白",
|
||||
"status": "pending"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"total": 1,
|
||||
"pages": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 取消认领申请
|
||||
|
||||
**接口地址**: `PUT /api/v1/animal-claims/{id}/cancel`
|
||||
|
||||
**路径参数**:
|
||||
- `id`: 认领申请ID
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "认领申请已取消",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"status": "cancelled",
|
||||
"cancelled_at": "2024-12-01T15:00:00.000Z",
|
||||
"cancel_reason": "用户主动取消"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 审核认领申请(管理员)
|
||||
|
||||
**接口地址**: `PUT /api/v1/animal-claims/{id}/review`
|
||||
|
||||
**权限要求**: 管理员或经理
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"status": "approved",
|
||||
"review_remark": "申请材料完整,同意认领"
|
||||
}
|
||||
```
|
||||
|
||||
**参数说明**:
|
||||
- `status` (必填): 审核状态 (approved/rejected)
|
||||
- `review_remark` (可选): 审核备注
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "认领申请审核通过",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"status": "approved",
|
||||
"reviewed_at": "2024-12-01T11:30:00.000Z",
|
||||
"start_date": "2024-12-01T11:30:00.000Z",
|
||||
"end_date": "2025-12-01T11:30:00.000Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 获取所有认领申请列表(管理员)
|
||||
|
||||
**接口地址**: `GET /api/v1/animal-claims`
|
||||
|
||||
**权限要求**: 管理员或经理
|
||||
|
||||
**请求参数**:
|
||||
- `page` (可选): 页码,默认1
|
||||
- `limit` (可选): 每页数量,默认10,最大100
|
||||
- `status` (可选): 申请状态
|
||||
- `animal_type` (可选): 动物类型
|
||||
- `user_id` (可选): 用户ID
|
||||
- `start_date` (可选): 开始日期
|
||||
- `end_date` (可选): 结束日期
|
||||
- `keyword` (可选): 关键词搜索(订单号、动物名称、用户名)
|
||||
|
||||
### 6. 获取动物的认领申请列表(管理员)
|
||||
|
||||
**接口地址**: `GET /api/v1/animal-claims/animal/{animal_id}`
|
||||
|
||||
**权限要求**: 管理员或经理
|
||||
|
||||
**路径参数**:
|
||||
- `animal_id`: 动物ID
|
||||
|
||||
### 7. 检查认领权限
|
||||
|
||||
**接口地址**: `GET /api/v1/animal-claims/check-permission/{animal_id}`
|
||||
|
||||
**路径参数**:
|
||||
- `animal_id`: 动物ID
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "检查认领权限成功",
|
||||
"data": {
|
||||
"can_claim": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8. 续期认领
|
||||
|
||||
**接口地址**: `POST /api/v1/animal-claims/{id}/renew`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"duration": 6,
|
||||
"payment_method": "wechat"
|
||||
}
|
||||
```
|
||||
|
||||
**参数说明**:
|
||||
- `duration` (必填): 续期时长(月),范围1-60
|
||||
- `payment_method` (必填): 支付方式 (wechat/alipay/bank_transfer)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "续期申请已提交,请完成支付",
|
||||
"data": {
|
||||
"renewal": {
|
||||
"id": 1,
|
||||
"claim_id": 1,
|
||||
"duration": 6,
|
||||
"amount": 600.00,
|
||||
"status": "pending"
|
||||
},
|
||||
"amount": 600.00,
|
||||
"message": "续期申请已提交,请完成支付"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 9. 获取认领统计信息(管理员)
|
||||
|
||||
**接口地址**: `GET /api/v1/animal-claims/statistics`
|
||||
|
||||
**权限要求**: 管理员或经理
|
||||
|
||||
**请求参数**:
|
||||
- `start_date` (可选): 开始日期
|
||||
- `end_date` (可选): 结束日期
|
||||
- `animal_type` (可选): 动物类型
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "获取认领统计信息成功",
|
||||
"data": {
|
||||
"basic": {
|
||||
"total_claims": 100,
|
||||
"pending_claims": 10,
|
||||
"approved_claims": 80,
|
||||
"rejected_claims": 8,
|
||||
"cancelled_claims": 2,
|
||||
"total_amount": 120000.00,
|
||||
"avg_duration": 12.5
|
||||
},
|
||||
"by_type": [...],
|
||||
"by_month": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 状态说明
|
||||
|
||||
### 认领申请状态
|
||||
|
||||
- `pending`: 待审核
|
||||
- `approved`: 已通过
|
||||
- `rejected`: 已拒绝
|
||||
- `cancelled`: 已取消
|
||||
- `expired`: 已过期(系统自动设置)
|
||||
|
||||
### 续期状态
|
||||
|
||||
- `pending`: 待支付
|
||||
- `paid`: 已支付
|
||||
- `cancelled`: 已取消
|
||||
|
||||
## 支付方式
|
||||
|
||||
- `wechat`: 微信支付
|
||||
- `alipay`: 支付宝
|
||||
- `bank_transfer`: 银行转账
|
||||
|
||||
## 错误码说明
|
||||
|
||||
| 错误码 | 说明 |
|
||||
|--------|------|
|
||||
| 400 | 请求参数错误 |
|
||||
| 401 | 未授权,需要登录 |
|
||||
| 403 | 权限不足 |
|
||||
| 404 | 资源不存在 |
|
||||
| 500 | 服务器内部错误 |
|
||||
| 503 | 服务不可用(无数据库模式) |
|
||||
|
||||
## 业务规则
|
||||
|
||||
### 认领申请规则
|
||||
|
||||
1. 每个用户对同一动物只能有一个有效的认领申请
|
||||
2. 只有状态为"可认领"的动物才能被申请认领
|
||||
3. 认领时长范围为1-60个月
|
||||
4. 认领申请通过后,动物状态自动变为"已认领"
|
||||
|
||||
### 审核规则
|
||||
|
||||
1. 只有待审核状态的申请才能被审核
|
||||
2. 审核通过后自动设置开始和结束时间
|
||||
3. 审核拒绝后动物状态保持不变
|
||||
|
||||
### 续期规则
|
||||
|
||||
1. 只有已通过的认领申请才能续期
|
||||
2. 距离到期30天内才能申请续期
|
||||
3. 续期需要完成支付才能生效
|
||||
|
||||
### 取消规则
|
||||
|
||||
1. 待审核和已通过的申请可以取消
|
||||
2. 取消已通过的申请会恢复动物为可认领状态
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 所有时间字段均为UTC时间,前端需要根据时区进行转换
|
||||
2. 金额字段为浮点数,建议前端使用专门的货币处理库
|
||||
3. 图片路径为相对路径,需要拼接完整的URL
|
||||
4. 分页查询建议设置合理的limit值,避免一次性查询过多数据
|
||||
5. 关键词搜索支持模糊匹配,会搜索订单号、动物名称、用户名
|
||||
|
||||
## 集成示例
|
||||
|
||||
### JavaScript示例
|
||||
|
||||
```javascript
|
||||
// 申请认领动物
|
||||
async function claimAnimal(animalId, claimData) {
|
||||
const response = await fetch('/api/v1/animal-claims', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
animal_id: animalId,
|
||||
...claimData
|
||||
})
|
||||
});
|
||||
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
// 获取我的认领申请列表
|
||||
async function getMyClaimList(params = {}) {
|
||||
const queryString = new URLSearchParams(params).toString();
|
||||
const response = await fetch(`/api/v1/animal-claims/my?${queryString}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
// 取消认领申请
|
||||
async function cancelClaim(claimId) {
|
||||
const response = await fetch(`/api/v1/animal-claims/${claimId}/cancel`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
return await response.json();
|
||||
}
|
||||
```
|
||||
|
||||
### 前端状态管理示例
|
||||
|
||||
```javascript
|
||||
// 认领申请状态管理
|
||||
const claimStore = {
|
||||
state: {
|
||||
myClaimList: [],
|
||||
currentClaim: null,
|
||||
loading: false
|
||||
},
|
||||
|
||||
mutations: {
|
||||
SET_CLAIM_LIST(state, list) {
|
||||
state.myClaimList = list;
|
||||
},
|
||||
|
||||
SET_CURRENT_CLAIM(state, claim) {
|
||||
state.currentClaim = claim;
|
||||
},
|
||||
|
||||
UPDATE_CLAIM_STATUS(state, { claimId, status }) {
|
||||
const claim = state.myClaimList.find(c => c.id === claimId);
|
||||
if (claim) {
|
||||
claim.status = status;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
async fetchMyClaimList({ commit }, params) {
|
||||
commit('SET_LOADING', true);
|
||||
try {
|
||||
const result = await getMyClaimList(params);
|
||||
if (result.success) {
|
||||
commit('SET_CLAIM_LIST', result.data);
|
||||
}
|
||||
} finally {
|
||||
commit('SET_LOADING', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
862
docs/后端开发文档.md
Normal file
862
docs/后端开发文档.md
Normal file
@@ -0,0 +1,862 @@
|
||||
# 后端开发文档
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
### 1.1 项目简介
|
||||
解班客后端服务是一个基于Node.js + TypeScript + Express的微服务架构系统,为小程序端、管理后台和官网提供API服务支持。
|
||||
|
||||
### 1.2 技术栈
|
||||
- **运行环境**:Node.js 18.x
|
||||
- **开发语言**:TypeScript 5.x
|
||||
- **Web框架**:Express.js 4.x
|
||||
- **数据库**:MySQL 8.0 + Redis 7.x
|
||||
- **ORM框架**:TypeORM 0.3.x
|
||||
- **认证授权**:JWT + 微信授权
|
||||
- **文件存储**:阿里云OSS
|
||||
- **消息队列**:Redis + Bull Queue
|
||||
- **监控日志**:Winston + PM2
|
||||
- **测试框架**:Jest + Supertest
|
||||
- **代码规范**:ESLint + Prettier
|
||||
|
||||
### 1.3 项目结构
|
||||
```
|
||||
backend/
|
||||
├── src/
|
||||
│ ├── config/ # 配置文件
|
||||
│ ├── controllers/ # 控制器
|
||||
│ ├── services/ # 业务逻辑层
|
||||
│ ├── models/ # 数据模型
|
||||
│ ├── middlewares/ # 中间件
|
||||
│ ├── utils/ # 工具函数
|
||||
│ ├── types/ # 类型定义
|
||||
│ ├── routes/ # 路由定义
|
||||
│ ├── jobs/ # 队列任务
|
||||
│ └── app.ts # 应用入口
|
||||
├── tests/ # 测试文件
|
||||
├── docs/ # 接口文档
|
||||
├── scripts/ # 脚本文件
|
||||
├── docker/ # Docker配置
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
├── .env.example
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 2. 开发环境搭建
|
||||
|
||||
### 2.1 环境要求
|
||||
- Node.js >= 18.0.0
|
||||
- npm >= 9.0.0
|
||||
- MySQL >= 8.0
|
||||
- Redis >= 7.0
|
||||
- Git >= 2.30
|
||||
|
||||
### 2.2 环境搭建步骤
|
||||
|
||||
#### 2.2.1 克隆项目
|
||||
```bash
|
||||
git clone https://github.com/your-org/jiebanke-backend.git
|
||||
cd jiebanke-backend
|
||||
```
|
||||
|
||||
#### 2.2.2 安装依赖
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
#### 2.2.3 配置环境变量
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# 编辑 .env 文件,配置数据库连接等信息
|
||||
```
|
||||
|
||||
#### 2.2.4 数据库初始化
|
||||
```bash
|
||||
# 创建数据库
|
||||
npm run db:create
|
||||
|
||||
# 运行迁移
|
||||
npm run db:migrate
|
||||
|
||||
# 填充测试数据
|
||||
npm run db:seed
|
||||
```
|
||||
|
||||
#### 2.2.5 启动开发服务器
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### 2.3 开发工具配置
|
||||
|
||||
#### 2.3.1 VSCode配置
|
||||
推荐安装以下插件:
|
||||
- TypeScript Importer
|
||||
- ESLint
|
||||
- Prettier
|
||||
- REST Client
|
||||
- GitLens
|
||||
|
||||
#### 2.3.2 代码规范配置
|
||||
```json
|
||||
// .eslintrc.json
|
||||
{
|
||||
"extends": [
|
||||
"@typescript-eslint/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unused-vars": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": "warn"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 开发计划与任务分解
|
||||
|
||||
### 3.1 开发阶段划分
|
||||
|
||||
#### 阶段一:基础架构搭建(预计15个工作日)
|
||||
- 项目初始化和环境配置
|
||||
- 数据库设计和迁移
|
||||
- 基础中间件和工具类开发
|
||||
- 认证授权系统
|
||||
|
||||
#### 阶段二:核心业务模块(预计25个工作日)
|
||||
- 用户管理模块
|
||||
- 旅行结伴模块
|
||||
- 动物认领模块
|
||||
- 支付系统模块
|
||||
|
||||
#### 阶段三:辅助功能模块(预计15个工作日)
|
||||
- 文件上传模块
|
||||
- 消息通知模块
|
||||
- 搜索功能模块
|
||||
- 统计分析模块
|
||||
|
||||
#### 阶段四:系统优化和测试(预计10个工作日)
|
||||
- 性能优化
|
||||
- 安全加固
|
||||
- 单元测试和集成测试
|
||||
- 部署和运维配置
|
||||
|
||||
### 3.2 详细任务分解
|
||||
|
||||
#### 3.2.1 阶段一:基础架构搭建
|
||||
|
||||
##### 任务1.1:项目初始化(2个工作日)
|
||||
**负责人**:架构师 + 后端开发工程师
|
||||
**工时估算**:16人时
|
||||
**任务描述**:
|
||||
- 创建项目目录结构
|
||||
- 配置TypeScript和构建工具
|
||||
- 设置代码规范和Git hooks
|
||||
- 配置开发环境和调试工具
|
||||
|
||||
**具体子任务**:
|
||||
1. 初始化npm项目和依赖安装(4人时)
|
||||
2. 配置TypeScript编译选项(2人时)
|
||||
3. 设置ESLint和Prettier规范(2人时)
|
||||
4. 配置Webpack/Vite构建工具(4人时)
|
||||
5. 设置Git hooks和CI/CD基础配置(4人时)
|
||||
|
||||
**验收标准**:
|
||||
- 项目可以正常启动和热重载
|
||||
- 代码规范检查通过
|
||||
- Git提交触发自动化检查
|
||||
|
||||
##### 任务1.2:数据库设计和迁移(3个工作日)
|
||||
**负责人**:数据库设计师 + 后端开发工程师
|
||||
**工时估算**:24人时
|
||||
**任务描述**:
|
||||
- 设计数据库表结构
|
||||
- 创建TypeORM实体模型
|
||||
- 编写数据库迁移脚本
|
||||
- 创建种子数据
|
||||
|
||||
**具体子任务**:
|
||||
1. 设计用户相关表结构(6人时)
|
||||
2. 设计旅行和动物相关表结构(8人时)
|
||||
3. 设计订单和支付相关表结构(4人时)
|
||||
4. 创建TypeORM实体和关系映射(4人时)
|
||||
5. 编写迁移脚本和种子数据(2人时)
|
||||
|
||||
**验收标准**:
|
||||
- 数据库表结构符合设计要求
|
||||
- 实体关系映射正确
|
||||
- 迁移脚本可以正常执行
|
||||
|
||||
##### 任务1.3:基础中间件开发(4个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:32人时
|
||||
**任务描述**:
|
||||
- 开发认证中间件
|
||||
- 开发权限控制中间件
|
||||
- 开发日志记录中间件
|
||||
- 开发错误处理中间件
|
||||
|
||||
**具体子任务**:
|
||||
1. JWT认证中间件开发(8人时)
|
||||
2. 权限控制中间件开发(6人时)
|
||||
3. 请求日志中间件开发(4人时)
|
||||
4. 全局错误处理中间件开发(6人时)
|
||||
5. 参数验证中间件开发(4人时)
|
||||
6. 限流中间件开发(4人时)
|
||||
|
||||
**验收标准**:
|
||||
- 中间件功能正常
|
||||
- 单元测试覆盖率达到80%
|
||||
- 性能测试通过
|
||||
|
||||
##### 任务1.4:工具类和配置管理(2个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:16人时
|
||||
**任务描述**:
|
||||
- 开发通用工具类
|
||||
- 配置管理系统
|
||||
- 缓存工具类
|
||||
- 文件处理工具类
|
||||
|
||||
**具体子任务**:
|
||||
1. 加密解密工具类(4人时)
|
||||
2. 日期时间工具类(2人时)
|
||||
3. 字符串处理工具类(2人时)
|
||||
4. 配置管理工具(4人时)
|
||||
5. Redis缓存工具类(4人时)
|
||||
|
||||
**验收标准**:
|
||||
- 工具类功能完整
|
||||
- 配置可以动态加载
|
||||
- 缓存操作正常
|
||||
|
||||
##### 任务1.5:认证授权系统(4个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:32人时
|
||||
**任务描述**:
|
||||
- 微信登录集成
|
||||
- JWT Token管理
|
||||
- 用户权限系统
|
||||
- 会话管理
|
||||
|
||||
**具体子任务**:
|
||||
1. 微信小程序登录接口(8人时)
|
||||
2. JWT Token生成和验证(6人时)
|
||||
3. 用户权限模型设计(6人时)
|
||||
4. 会话管理和刷新机制(6人时)
|
||||
5. 权限装饰器开发(6人时)
|
||||
|
||||
**验收标准**:
|
||||
- 微信登录流程正常
|
||||
- Token验证机制完善
|
||||
- 权限控制精确
|
||||
|
||||
#### 3.2.2 阶段二:核心业务模块
|
||||
|
||||
##### 任务2.1:用户管理模块(6个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:48人时
|
||||
**任务描述**:
|
||||
- 用户信息管理
|
||||
- 用户认证和授权
|
||||
- 用户资料完善
|
||||
- 用户状态管理
|
||||
|
||||
**具体子任务**:
|
||||
1. 用户注册和登录接口(8人时)
|
||||
2. 用户信息CRUD接口(8人时)
|
||||
3. 用户头像上传功能(6人时)
|
||||
4. 用户实名认证功能(8人时)
|
||||
5. 用户状态管理(6人时)
|
||||
6. 用户统计信息接口(6人时)
|
||||
7. 用户关注和粉丝功能(6人时)
|
||||
|
||||
**验收标准**:
|
||||
- 用户注册登录流程完整
|
||||
- 用户信息管理功能正常
|
||||
- 实名认证流程通畅
|
||||
|
||||
##### 任务2.2:旅行结伴模块(8个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:64人时
|
||||
**任务描述**:
|
||||
- 旅行活动管理
|
||||
- 参与申请处理
|
||||
- 活动状态管理
|
||||
- 评论和互动功能
|
||||
|
||||
**具体子任务**:
|
||||
1. 旅行活动CRUD接口(12人时)
|
||||
2. 活动搜索和筛选功能(8人时)
|
||||
3. 参与申请管理接口(10人时)
|
||||
4. 活动状态流转管理(8人时)
|
||||
5. 活动评论和点赞功能(8人时)
|
||||
6. 活动图片和视频管理(6人时)
|
||||
7. 活动推荐算法(8人时)
|
||||
8. 活动统计分析接口(4人时)
|
||||
|
||||
**验收标准**:
|
||||
- 旅行活动管理功能完整
|
||||
- 申请审核流程正常
|
||||
- 搜索和推荐准确
|
||||
|
||||
##### 任务2.3:动物认领模块(7个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:56人时
|
||||
**任务描述**:
|
||||
- 动物信息管理
|
||||
- 认领申请处理
|
||||
- 认领状态跟踪
|
||||
- 动物成长记录
|
||||
|
||||
**具体子任务**:
|
||||
1. 动物信息CRUD接口(10人时)
|
||||
2. 动物搜索和筛选功能(8人时)
|
||||
3. 认领申请管理接口(10人时)
|
||||
4. 认领状态管理(8人时)
|
||||
5. 动物成长记录功能(8人时)
|
||||
6. 动物健康档案管理(6人时)
|
||||
7. 认领费用计算(6人时)
|
||||
|
||||
**验收标准**:
|
||||
- 动物信息管理完整
|
||||
- 认领流程顺畅
|
||||
- 成长记录功能正常
|
||||
|
||||
##### 任务2.4:支付系统模块(4个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:32人时
|
||||
**任务描述**:
|
||||
- 订单管理系统
|
||||
- 微信支付集成
|
||||
- 支付状态跟踪
|
||||
- 退款处理
|
||||
|
||||
**具体子任务**:
|
||||
1. 订单创建和管理接口(8人时)
|
||||
2. 微信支付接口集成(10人时)
|
||||
3. 支付回调处理(6人时)
|
||||
4. 退款功能开发(6人时)
|
||||
5. 支付状态同步(2人时)
|
||||
|
||||
**验收标准**:
|
||||
- 订单管理功能完整
|
||||
- 微信支付流程正常
|
||||
- 退款处理准确
|
||||
|
||||
#### 3.2.3 阶段三:辅助功能模块
|
||||
|
||||
##### 任务3.1:文件上传模块(3个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:24人时
|
||||
**任务描述**:
|
||||
- 文件上传接口
|
||||
- 图片处理功能
|
||||
- 文件存储管理
|
||||
- CDN集成
|
||||
|
||||
**具体子任务**:
|
||||
1. 文件上传接口开发(8人时)
|
||||
2. 图片压缩和处理(6人时)
|
||||
3. 阿里云OSS集成(6人时)
|
||||
4. 文件管理接口(4人时)
|
||||
|
||||
**验收标准**:
|
||||
- 文件上传功能正常
|
||||
- 图片处理效果良好
|
||||
- 存储和访问稳定
|
||||
|
||||
##### 任务3.2:消息通知模块(4个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:32人时
|
||||
**任务描述**:
|
||||
- 站内消息系统
|
||||
- 微信模板消息
|
||||
- 消息推送功能
|
||||
- 消息状态管理
|
||||
|
||||
**具体子任务**:
|
||||
1. 站内消息CRUD接口(8人时)
|
||||
2. 微信模板消息集成(8人时)
|
||||
3. 消息推送队列(8人时)
|
||||
4. 消息状态管理(4人时)
|
||||
5. 消息统计功能(4人时)
|
||||
|
||||
**验收标准**:
|
||||
- 消息发送接收正常
|
||||
- 推送功能稳定
|
||||
- 状态管理准确
|
||||
|
||||
##### 任务3.3:搜索功能模块(4个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:32人时
|
||||
**任务描述**:
|
||||
- 全文搜索功能
|
||||
- 搜索建议
|
||||
- 搜索统计
|
||||
- 搜索优化
|
||||
|
||||
**具体子任务**:
|
||||
1. 搜索接口开发(10人时)
|
||||
2. 搜索建议功能(6人时)
|
||||
3. 搜索结果排序(8人时)
|
||||
4. 搜索统计分析(4人时)
|
||||
5. 搜索性能优化(4人时)
|
||||
|
||||
**验收标准**:
|
||||
- 搜索结果准确
|
||||
- 响应速度快
|
||||
- 建议功能智能
|
||||
|
||||
##### 任务3.4:统计分析模块(4个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:32人时
|
||||
**任务描述**:
|
||||
- 用户行为统计
|
||||
- 业务数据分析
|
||||
- 报表生成
|
||||
- 数据可视化接口
|
||||
|
||||
**具体子任务**:
|
||||
1. 用户行为统计接口(8人时)
|
||||
2. 业务数据统计接口(8人时)
|
||||
3. 报表生成功能(8人时)
|
||||
4. 数据导出功能(4人时)
|
||||
5. 统计数据缓存优化(4人时)
|
||||
|
||||
**验收标准**:
|
||||
- 统计数据准确
|
||||
- 报表生成正常
|
||||
- 性能满足要求
|
||||
|
||||
#### 3.2.4 阶段四:系统优化和测试
|
||||
|
||||
##### 任务4.1:性能优化(3个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:24人时
|
||||
**任务描述**:
|
||||
- 数据库查询优化
|
||||
- 缓存策略优化
|
||||
- 接口性能优化
|
||||
- 系统监控
|
||||
|
||||
**具体子任务**:
|
||||
1. SQL查询优化(8人时)
|
||||
2. Redis缓存策略优化(6人时)
|
||||
3. 接口响应时间优化(6人时)
|
||||
4. 系统监控配置(4人时)
|
||||
|
||||
**验收标准**:
|
||||
- 接口响应时间<200ms
|
||||
- 数据库查询效率提升50%
|
||||
- 缓存命中率>80%
|
||||
|
||||
##### 任务4.2:安全加固(2个工作日)
|
||||
**负责人**:后端开发工程师
|
||||
**工时估算**:16人时
|
||||
**任务描述**:
|
||||
- 安全漏洞检查
|
||||
- 数据加密处理
|
||||
- 接口安全加固
|
||||
- 安全审计
|
||||
|
||||
**具体子任务**:
|
||||
1. SQL注入防护(4人时)
|
||||
2. XSS攻击防护(4人时)
|
||||
3. 敏感数据加密(4人时)
|
||||
4. 接口访问控制(4人时)
|
||||
|
||||
**验收标准**:
|
||||
- 安全扫描无高危漏洞
|
||||
- 敏感数据加密存储
|
||||
- 接口访问控制完善
|
||||
|
||||
##### 任务4.3:测试开发(3个工作日)
|
||||
**负责人**:后端开发工程师 + 测试工程师
|
||||
**工时估算**:24人时
|
||||
**任务描述**:
|
||||
- 单元测试编写
|
||||
- 集成测试开发
|
||||
- 接口测试自动化
|
||||
- 性能测试
|
||||
|
||||
**具体子任务**:
|
||||
1. 单元测试编写(10人时)
|
||||
2. 集成测试开发(8人时)
|
||||
3. 接口自动化测试(4人时)
|
||||
4. 性能测试脚本(2人时)
|
||||
|
||||
**验收标准**:
|
||||
- 单元测试覆盖率>80%
|
||||
- 集成测试通过率100%
|
||||
- 接口测试自动化完成
|
||||
|
||||
##### 任务4.4:部署和运维配置(2个工作日)
|
||||
**负责人**:运维工程师 + 后端开发工程师
|
||||
**工时估算**:16人时
|
||||
**任务描述**:
|
||||
- Docker容器化
|
||||
- CI/CD流水线
|
||||
- 监控告警配置
|
||||
- 日志收集配置
|
||||
|
||||
**具体子任务**:
|
||||
1. Docker镜像构建(4人时)
|
||||
2. CI/CD流水线配置(6人时)
|
||||
3. 监控告警配置(4人时)
|
||||
4. 日志收集配置(2人时)
|
||||
|
||||
**验收标准**:
|
||||
- 容器化部署成功
|
||||
- CI/CD流水线正常
|
||||
- 监控告警及时
|
||||
|
||||
## 4. 开发规范
|
||||
|
||||
### 4.1 代码规范
|
||||
|
||||
#### 4.1.1 命名规范
|
||||
- **文件命名**:使用kebab-case,如`user-service.ts`
|
||||
- **类命名**:使用PascalCase,如`UserService`
|
||||
- **方法命名**:使用camelCase,如`getUserById`
|
||||
- **常量命名**:使用UPPER_SNAKE_CASE,如`MAX_FILE_SIZE`
|
||||
|
||||
#### 4.1.2 目录结构规范
|
||||
```
|
||||
src/
|
||||
├── controllers/
|
||||
│ ├── user.controller.ts
|
||||
│ ├── travel.controller.ts
|
||||
│ └── animal.controller.ts
|
||||
├── services/
|
||||
│ ├── user.service.ts
|
||||
│ ├── travel.service.ts
|
||||
│ └── animal.service.ts
|
||||
├── models/
|
||||
│ ├── user.model.ts
|
||||
│ ├── travel.model.ts
|
||||
│ └── animal.model.ts
|
||||
└── routes/
|
||||
├── user.routes.ts
|
||||
├── travel.routes.ts
|
||||
└── animal.routes.ts
|
||||
```
|
||||
|
||||
#### 4.1.3 注释规范
|
||||
```typescript
|
||||
/**
|
||||
* 用户服务类
|
||||
* 处理用户相关的业务逻辑
|
||||
*/
|
||||
export class UserService {
|
||||
/**
|
||||
* 根据ID获取用户信息
|
||||
* @param id 用户ID
|
||||
* @returns 用户信息对象
|
||||
* @throws {NotFoundError} 用户不存在时抛出
|
||||
*/
|
||||
async getUserById(id: number): Promise<User> {
|
||||
// 实现逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 API设计规范
|
||||
|
||||
#### 4.2.1 RESTful接口规范
|
||||
- **GET** `/api/v1/users` - 获取用户列表
|
||||
- **GET** `/api/v1/users/{id}` - 获取单个用户
|
||||
- **POST** `/api/v1/users` - 创建用户
|
||||
- **PUT** `/api/v1/users/{id}` - 更新用户
|
||||
- **DELETE** `/api/v1/users/{id}` - 删除用户
|
||||
|
||||
#### 4.2.2 响应格式规范
|
||||
```typescript
|
||||
interface ApiResponse<T> {
|
||||
code: number;
|
||||
message: string;
|
||||
data?: T;
|
||||
timestamp: string;
|
||||
request_id: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2.3 错误处理规范
|
||||
```typescript
|
||||
export class ApiError extends Error {
|
||||
constructor(
|
||||
public code: number,
|
||||
public message: string,
|
||||
public details?: any
|
||||
) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 数据库操作规范
|
||||
|
||||
#### 4.3.1 实体定义规范
|
||||
```typescript
|
||||
@Entity('users')
|
||||
export class User {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column({ length: 50, unique: true })
|
||||
username: string;
|
||||
|
||||
@CreateDateColumn()
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updated_at: Date;
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.2 查询规范
|
||||
```typescript
|
||||
// 使用Repository模式
|
||||
const user = await this.userRepository.findOne({
|
||||
where: { id },
|
||||
relations: ['profile']
|
||||
});
|
||||
|
||||
// 使用QueryBuilder进行复杂查询
|
||||
const users = await this.userRepository
|
||||
.createQueryBuilder('user')
|
||||
.leftJoinAndSelect('user.profile', 'profile')
|
||||
.where('user.status = :status', { status: 1 })
|
||||
.getMany();
|
||||
```
|
||||
|
||||
### 4.4 测试规范
|
||||
|
||||
#### 4.4.1 单元测试规范
|
||||
```typescript
|
||||
describe('UserService', () => {
|
||||
let service: UserService;
|
||||
let repository: Repository<User>;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
providers: [UserService, mockUserRepository]
|
||||
}).compile();
|
||||
|
||||
service = module.get<UserService>(UserService);
|
||||
repository = module.get<Repository<User>>(getRepositoryToken(User));
|
||||
});
|
||||
|
||||
it('should create a user', async () => {
|
||||
const userData = { username: 'test', email: 'test@example.com' };
|
||||
const result = await service.createUser(userData);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result.username).toBe(userData.username);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
#### 4.4.2 集成测试规范
|
||||
```typescript
|
||||
describe('User API', () => {
|
||||
let app: INestApplication;
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleFixture = await Test.createTestingModule({
|
||||
imports: [AppModule]
|
||||
}).compile();
|
||||
|
||||
app = moduleFixture.createNestApplication();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it('/users (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/users')
|
||||
.send({ username: 'test', email: 'test@example.com' })
|
||||
.expect(201)
|
||||
.expect((res) => {
|
||||
expect(res.body.data.username).toBe('test');
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 5. 质量保证
|
||||
|
||||
### 5.1 代码质量检查
|
||||
|
||||
#### 5.1.1 静态代码分析
|
||||
- **ESLint**:代码风格和潜在问题检查
|
||||
- **Prettier**:代码格式化
|
||||
- **SonarQube**:代码质量分析
|
||||
- **TypeScript**:类型检查
|
||||
|
||||
#### 5.1.2 代码审查流程
|
||||
1. 开发者提交Pull Request
|
||||
2. 自动化检查(ESLint、测试、构建)
|
||||
3. 同行代码审查
|
||||
4. 技术负责人最终审查
|
||||
5. 合并到主分支
|
||||
|
||||
### 5.2 测试策略
|
||||
|
||||
#### 5.2.1 测试金字塔
|
||||
- **单元测试**:70% - 测试单个函数和类
|
||||
- **集成测试**:20% - 测试模块间交互
|
||||
- **端到端测试**:10% - 测试完整业务流程
|
||||
|
||||
#### 5.2.2 测试覆盖率要求
|
||||
- **代码覆盖率**:>80%
|
||||
- **分支覆盖率**:>70%
|
||||
- **函数覆盖率**:>90%
|
||||
|
||||
### 5.3 性能要求
|
||||
|
||||
#### 5.3.1 响应时间要求
|
||||
- **简单查询接口**:<100ms
|
||||
- **复杂查询接口**:<500ms
|
||||
- **文件上传接口**:<2s
|
||||
- **支付接口**:<1s
|
||||
|
||||
#### 5.3.2 并发性能要求
|
||||
- **并发用户数**:1000+
|
||||
- **QPS**:500+
|
||||
- **数据库连接池**:20-50
|
||||
- **内存使用**:<512MB
|
||||
|
||||
## 6. 部署和运维
|
||||
|
||||
### 6.1 环境配置
|
||||
|
||||
#### 6.1.1 开发环境
|
||||
- **Node.js**:18.x
|
||||
- **MySQL**:8.0
|
||||
- **Redis**:7.x
|
||||
- **端口**:3000
|
||||
|
||||
#### 6.1.2 测试环境
|
||||
- **服务器**:2核4GB
|
||||
- **数据库**:独立实例
|
||||
- **域名**:api-test.jiebanke.com
|
||||
- **HTTPS**:Let's Encrypt
|
||||
|
||||
#### 6.1.3 生产环境
|
||||
- **服务器**:4核8GB(可扩展)
|
||||
- **数据库**:主从复制
|
||||
- **缓存**:Redis集群
|
||||
- **CDN**:阿里云CDN
|
||||
- **监控**:Prometheus + Grafana
|
||||
|
||||
### 6.2 CI/CD流程
|
||||
|
||||
#### 6.2.1 持续集成
|
||||
```yaml
|
||||
# .github/workflows/ci.yml
|
||||
name: CI
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
- run: npm ci
|
||||
- run: npm run lint
|
||||
- run: npm run test
|
||||
- run: npm run build
|
||||
```
|
||||
|
||||
#### 6.2.2 持续部署
|
||||
```yaml
|
||||
# .github/workflows/cd.yml
|
||||
name: CD
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build Docker image
|
||||
run: docker build -t jiebanke-backend .
|
||||
- name: Deploy to server
|
||||
run: |
|
||||
docker stop jiebanke-backend || true
|
||||
docker rm jiebanke-backend || true
|
||||
docker run -d --name jiebanke-backend -p 3000:3000 jiebanke-backend
|
||||
```
|
||||
|
||||
### 6.3 监控和日志
|
||||
|
||||
#### 6.3.1 应用监控
|
||||
- **健康检查**:/health端点
|
||||
- **性能监控**:响应时间、吞吐量
|
||||
- **错误监控**:错误率、异常堆栈
|
||||
- **业务监控**:用户活跃度、订单量
|
||||
|
||||
#### 6.3.2 日志管理
|
||||
```typescript
|
||||
// 日志配置
|
||||
const logger = winston.createLogger({
|
||||
level: 'info',
|
||||
format: winston.format.combine(
|
||||
winston.format.timestamp(),
|
||||
winston.format.json()
|
||||
),
|
||||
transports: [
|
||||
new winston.transports.File({ filename: 'error.log', level: 'error' }),
|
||||
new winston.transports.File({ filename: 'combined.log' })
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
## 7. 风险管理
|
||||
|
||||
### 7.1 技术风险
|
||||
|
||||
#### 7.1.1 性能风险
|
||||
- **风险**:高并发下性能下降
|
||||
- **应对**:负载测试、缓存优化、数据库优化
|
||||
- **监控**:响应时间、QPS、资源使用率
|
||||
|
||||
#### 7.1.2 安全风险
|
||||
- **风险**:数据泄露、攻击
|
||||
- **应对**:安全审计、加密存储、访问控制
|
||||
- **监控**:异常访问、安全事件
|
||||
|
||||
### 7.2 业务风险
|
||||
|
||||
#### 7.2.1 数据一致性风险
|
||||
- **风险**:分布式事务失败
|
||||
- **应对**:事务补偿、幂等性设计
|
||||
- **监控**:数据一致性检查
|
||||
|
||||
#### 7.2.2 第三方依赖风险
|
||||
- **风险**:微信API、支付接口不可用
|
||||
- **应对**:降级方案、重试机制
|
||||
- **监控**:第三方服务可用性
|
||||
|
||||
## 8. 总结
|
||||
|
||||
本开发文档详细规划了解班客后端系统的开发计划,包括:
|
||||
|
||||
### 8.1 开发计划
|
||||
- **总工期**:65个工作日
|
||||
- **团队规模**:3-4名后端开发工程师
|
||||
- **关键里程碑**:基础架构、核心业务、辅助功能、系统优化
|
||||
|
||||
### 8.2 质量保证
|
||||
- **代码规范**:统一的编码标准和最佳实践
|
||||
- **测试策略**:完整的测试金字塔和覆盖率要求
|
||||
- **性能要求**:明确的性能指标和优化方案
|
||||
|
||||
### 8.3 风险控制
|
||||
- **技术风险**:性能、安全、稳定性
|
||||
- **业务风险**:数据一致性、第三方依赖
|
||||
- **应对措施**:监控、降级、补偿机制
|
||||
|
||||
通过严格按照本开发文档执行,可以确保后端系统的高质量交付和稳定运行。
|
||||
1886
docs/后端架构文档.md
Normal file
1886
docs/后端架构文档.md
Normal file
File diff suppressed because it is too large
Load Diff
1655
docs/后端管理开发文档.md
Normal file
1655
docs/后端管理开发文档.md
Normal file
File diff suppressed because it is too large
Load Diff
851
docs/后端管理需求文档.md
Normal file
851
docs/后端管理需求文档.md
Normal file
@@ -0,0 +1,851 @@
|
||||
# 解班客后端管理需求文档
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
### 1.1 系统定位
|
||||
后端管理系统是解班客平台的核心服务层,负责提供所有业务逻辑处理、数据管理、API服务以及与第三方系统的集成。系统采用RESTful API架构,为前端应用、小程序和管理后台提供统一的数据服务。
|
||||
|
||||
### 1.2 核心职责
|
||||
- 提供完整的API服务接口
|
||||
- 处理业务逻辑和数据验证
|
||||
- 管理用户认证和权限控制
|
||||
- 集成第三方服务(支付、短信、地图等)
|
||||
- 确保数据安全和系统稳定性
|
||||
|
||||
### 1.3 技术架构
|
||||
- **运行环境**:Node.js 18+
|
||||
- **Web框架**:Express.js
|
||||
- **数据库**:MySQL 8.0 + Redis 6.0
|
||||
- **认证方式**:JWT + Passport
|
||||
- **API文档**:Swagger/OpenAPI
|
||||
|
||||
## 2. 用户管理模块
|
||||
|
||||
### 2.1 用户认证服务
|
||||
#### 2.1.1 微信登录
|
||||
```
|
||||
POST /api/auth/wechat/login
|
||||
功能:微信小程序登录
|
||||
参数:
|
||||
- code: 微信授权码
|
||||
- encryptedData: 加密用户信息
|
||||
- iv: 初始向量
|
||||
返回:JWT token和用户基本信息
|
||||
```
|
||||
|
||||
#### 2.1.2 手机号验证
|
||||
```
|
||||
POST /api/auth/phone/verify
|
||||
功能:发送手机验证码
|
||||
参数:
|
||||
- phone: 手机号码
|
||||
- type: 验证类型(register/login/reset)
|
||||
|
||||
POST /api/auth/phone/login
|
||||
功能:手机号验证码登录
|
||||
参数:
|
||||
- phone: 手机号码
|
||||
- code: 验证码
|
||||
```
|
||||
|
||||
#### 2.1.3 Token管理
|
||||
```
|
||||
POST /api/auth/refresh
|
||||
功能:刷新访问令牌
|
||||
参数:
|
||||
- refreshToken: 刷新令牌
|
||||
|
||||
POST /api/auth/logout
|
||||
功能:用户登出
|
||||
参数:
|
||||
- token: 访问令牌
|
||||
```
|
||||
|
||||
### 2.2 用户信息管理
|
||||
#### 2.2.1 用户资料
|
||||
```
|
||||
GET /api/users/profile
|
||||
功能:获取用户详细信息
|
||||
|
||||
PUT /api/users/profile
|
||||
功能:更新用户资料
|
||||
参数:
|
||||
- nickname: 昵称
|
||||
- avatar: 头像URL
|
||||
- gender: 性别
|
||||
- birthday: 生日
|
||||
- location: 所在地
|
||||
- bio: 个人简介
|
||||
- interests: 兴趣标签
|
||||
```
|
||||
|
||||
#### 2.2.2 实名认证
|
||||
```
|
||||
POST /api/users/identity/verify
|
||||
功能:提交实名认证
|
||||
参数:
|
||||
- realName: 真实姓名
|
||||
- idCard: 身份证号
|
||||
- idCardFront: 身份证正面照
|
||||
- idCardBack: 身份证背面照
|
||||
|
||||
GET /api/users/identity/status
|
||||
功能:查询认证状态
|
||||
```
|
||||
|
||||
#### 2.2.3 用户设置
|
||||
```
|
||||
PUT /api/users/settings
|
||||
功能:更新用户设置
|
||||
参数:
|
||||
- privacy: 隐私设置
|
||||
- notification: 通知设置
|
||||
- security: 安全设置
|
||||
|
||||
GET /api/users/settings
|
||||
功能:获取用户设置
|
||||
```
|
||||
|
||||
### 2.3 用户关系管理
|
||||
#### 2.3.1 关注功能
|
||||
```
|
||||
POST /api/users/{userId}/follow
|
||||
功能:关注用户
|
||||
|
||||
DELETE /api/users/{userId}/follow
|
||||
功能:取消关注
|
||||
|
||||
GET /api/users/following
|
||||
功能:获取关注列表
|
||||
|
||||
GET /api/users/followers
|
||||
功能:获取粉丝列表
|
||||
```
|
||||
|
||||
#### 2.3.2 黑名单管理
|
||||
```
|
||||
POST /api/users/{userId}/block
|
||||
功能:拉黑用户
|
||||
|
||||
DELETE /api/users/{userId}/block
|
||||
功能:取消拉黑
|
||||
|
||||
GET /api/users/blocked
|
||||
功能:获取黑名单列表
|
||||
```
|
||||
|
||||
## 3. 活动管理模块
|
||||
|
||||
### 3.1 活动发布管理
|
||||
#### 3.1.1 活动创建
|
||||
```
|
||||
POST /api/activities
|
||||
功能:创建新活动
|
||||
参数:
|
||||
- title: 活动标题
|
||||
- description: 活动描述
|
||||
- type: 活动类型
|
||||
- startTime: 开始时间
|
||||
- endTime: 结束时间
|
||||
- location: 活动地点
|
||||
- maxParticipants: 最大参与人数
|
||||
- fee: 活动费用
|
||||
- requirements: 参与要求
|
||||
- images: 活动图片
|
||||
- tags: 活动标签
|
||||
```
|
||||
|
||||
#### 3.1.2 活动编辑
|
||||
```
|
||||
PUT /api/activities/{activityId}
|
||||
功能:编辑活动信息
|
||||
|
||||
DELETE /api/activities/{activityId}
|
||||
功能:删除活动
|
||||
|
||||
PATCH /api/activities/{activityId}/status
|
||||
功能:更新活动状态
|
||||
参数:
|
||||
- status: 活动状态(draft/published/cancelled/completed)
|
||||
```
|
||||
|
||||
### 3.2 活动搜索和筛选
|
||||
#### 3.2.1 活动列表
|
||||
```
|
||||
GET /api/activities
|
||||
功能:获取活动列表
|
||||
参数:
|
||||
- page: 页码
|
||||
- limit: 每页数量
|
||||
- type: 活动类型
|
||||
- location: 地理位置
|
||||
- startDate: 开始日期
|
||||
- endDate: 结束日期
|
||||
- priceMin: 最低价格
|
||||
- priceMax: 最高价格
|
||||
- keyword: 关键词搜索
|
||||
- sort: 排序方式
|
||||
```
|
||||
|
||||
#### 3.2.2 活动详情
|
||||
```
|
||||
GET /api/activities/{activityId}
|
||||
功能:获取活动详细信息
|
||||
|
||||
GET /api/activities/{activityId}/participants
|
||||
功能:获取活动参与者列表
|
||||
|
||||
GET /api/activities/nearby
|
||||
功能:获取附近活动
|
||||
参数:
|
||||
- latitude: 纬度
|
||||
- longitude: 经度
|
||||
- radius: 搜索半径
|
||||
```
|
||||
|
||||
### 3.3 活动报名管理
|
||||
#### 3.3.1 报名流程
|
||||
```
|
||||
POST /api/activities/{activityId}/join
|
||||
功能:报名参加活动
|
||||
参数:
|
||||
- message: 报名留言
|
||||
- emergencyContact: 紧急联系人
|
||||
|
||||
GET /api/activities/{activityId}/join/status
|
||||
功能:查询报名状态
|
||||
|
||||
DELETE /api/activities/{activityId}/join
|
||||
功能:取消报名
|
||||
```
|
||||
|
||||
#### 3.3.2 报名审核
|
||||
```
|
||||
PUT /api/activities/{activityId}/participants/{userId}/approve
|
||||
功能:审核通过报名
|
||||
|
||||
PUT /api/activities/{activityId}/participants/{userId}/reject
|
||||
功能:拒绝报名
|
||||
参数:
|
||||
- reason: 拒绝原因
|
||||
|
||||
GET /api/activities/my/applications
|
||||
功能:获取我的报名记录
|
||||
|
||||
GET /api/activities/my/created
|
||||
功能:获取我创建的活动
|
||||
```
|
||||
|
||||
## 4. 动物认领模块
|
||||
|
||||
### 4.1 动物信息管理
|
||||
#### 4.1.1 动物档案
|
||||
```
|
||||
POST /api/animals
|
||||
功能:添加动物信息
|
||||
参数:
|
||||
- name: 动物名称
|
||||
- type: 动物类型
|
||||
- breed: 品种
|
||||
- age: 年龄
|
||||
- gender: 性别
|
||||
- weight: 体重
|
||||
- health: 健康状况
|
||||
- description: 描述
|
||||
- images: 动物照片
|
||||
- farmId: 所属农场ID
|
||||
- price: 认领价格
|
||||
```
|
||||
|
||||
#### 4.1.2 动物状态管理
|
||||
```
|
||||
PUT /api/animals/{animalId}
|
||||
功能:更新动物信息
|
||||
|
||||
PATCH /api/animals/{animalId}/status
|
||||
功能:更新动物状态
|
||||
参数:
|
||||
- status: 状态(available/adopted/reserved/unavailable)
|
||||
|
||||
GET /api/animals
|
||||
功能:获取动物列表
|
||||
参数:
|
||||
- type: 动物类型
|
||||
- status: 状态筛选
|
||||
- farmId: 农场筛选
|
||||
- priceMin: 最低价格
|
||||
- priceMax: 最高价格
|
||||
```
|
||||
|
||||
### 4.2 认领流程管理
|
||||
#### 4.2.1 认领申请
|
||||
```
|
||||
POST /api/animals/{animalId}/adopt
|
||||
功能:提交认领申请
|
||||
参数:
|
||||
- reason: 认领原因
|
||||
- experience: 养殖经验
|
||||
- visitPlan: 探访计划
|
||||
- duration: 认领期限
|
||||
|
||||
GET /api/adoptions/my
|
||||
功能:获取我的认领记录
|
||||
|
||||
GET /api/adoptions/{adoptionId}
|
||||
功能:获取认领详情
|
||||
```
|
||||
|
||||
#### 4.2.2 认领审核
|
||||
```
|
||||
PUT /api/adoptions/{adoptionId}/approve
|
||||
功能:审核通过认领
|
||||
|
||||
PUT /api/adoptions/{adoptionId}/reject
|
||||
功能:拒绝认领申请
|
||||
参数:
|
||||
- reason: 拒绝原因
|
||||
|
||||
POST /api/adoptions/{adoptionId}/contract
|
||||
功能:生成认领合同
|
||||
```
|
||||
|
||||
### 4.3 农场管理
|
||||
#### 4.3.1 农场信息
|
||||
```
|
||||
POST /api/farms
|
||||
功能:添加农场信息
|
||||
参数:
|
||||
- name: 农场名称
|
||||
- address: 农场地址
|
||||
- description: 农场描述
|
||||
- contact: 联系方式
|
||||
- facilities: 设施介绍
|
||||
- images: 农场照片
|
||||
|
||||
GET /api/farms
|
||||
功能:获取农场列表
|
||||
|
||||
GET /api/farms/{farmId}/animals
|
||||
功能:获取农场动物列表
|
||||
```
|
||||
|
||||
#### 4.3.2 探访管理
|
||||
```
|
||||
POST /api/farms/{farmId}/visits
|
||||
功能:预约农场探访
|
||||
参数:
|
||||
- visitDate: 探访日期
|
||||
- visitTime: 探访时间
|
||||
- visitors: 探访人数
|
||||
- purpose: 探访目的
|
||||
|
||||
GET /api/visits/my
|
||||
功能:获取我的探访记录
|
||||
|
||||
PUT /api/visits/{visitId}/confirm
|
||||
功能:确认探访预约
|
||||
```
|
||||
|
||||
## 5. 商家服务模块
|
||||
|
||||
### 5.1 商家入驻管理
|
||||
#### 5.1.1 入驻申请
|
||||
```
|
||||
POST /api/merchants/apply
|
||||
功能:提交入驻申请
|
||||
参数:
|
||||
- businessName: 商家名称
|
||||
- businessType: 商家类型
|
||||
- contactPerson: 联系人
|
||||
- contactPhone: 联系电话
|
||||
- businessLicense: 营业执照
|
||||
- address: 经营地址
|
||||
- description: 商家描述
|
||||
- qualifications: 资质证明
|
||||
```
|
||||
|
||||
#### 5.1.2 入驻审核
|
||||
```
|
||||
GET /api/merchants/applications
|
||||
功能:获取入驻申请列表
|
||||
|
||||
PUT /api/merchants/applications/{applicationId}/approve
|
||||
功能:审核通过入驻
|
||||
|
||||
PUT /api/merchants/applications/{applicationId}/reject
|
||||
功能:拒绝入驻申请
|
||||
参数:
|
||||
- reason: 拒绝原因
|
||||
```
|
||||
|
||||
### 5.2 商家信息管理
|
||||
#### 5.2.1 商家资料
|
||||
```
|
||||
GET /api/merchants/profile
|
||||
功能:获取商家资料
|
||||
|
||||
PUT /api/merchants/profile
|
||||
功能:更新商家资料
|
||||
参数:
|
||||
- businessName: 商家名称
|
||||
- description: 商家描述
|
||||
- logo: 商家Logo
|
||||
- images: 商家图片
|
||||
- businessHours: 营业时间
|
||||
- contactInfo: 联系信息
|
||||
```
|
||||
|
||||
#### 5.2.2 商家状态
|
||||
```
|
||||
PATCH /api/merchants/{merchantId}/status
|
||||
功能:更新商家状态
|
||||
参数:
|
||||
- status: 状态(active/inactive/suspended)
|
||||
|
||||
GET /api/merchants
|
||||
功能:获取商家列表
|
||||
参数:
|
||||
- type: 商家类型
|
||||
- status: 状态筛选
|
||||
- location: 地理位置
|
||||
```
|
||||
|
||||
### 5.3 商品服务管理
|
||||
#### 5.3.1 商品管理
|
||||
```
|
||||
POST /api/merchants/products
|
||||
功能:添加商品
|
||||
参数:
|
||||
- name: 商品名称
|
||||
- category: 商品分类
|
||||
- price: 商品价格
|
||||
- description: 商品描述
|
||||
- images: 商品图片
|
||||
- stock: 库存数量
|
||||
- specifications: 商品规格
|
||||
|
||||
PUT /api/merchants/products/{productId}
|
||||
功能:更新商品信息
|
||||
|
||||
DELETE /api/merchants/products/{productId}
|
||||
功能:删除商品
|
||||
```
|
||||
|
||||
#### 5.3.2 订单管理
|
||||
```
|
||||
GET /api/merchants/orders
|
||||
功能:获取商家订单列表
|
||||
|
||||
PUT /api/merchants/orders/{orderId}/confirm
|
||||
功能:确认订单
|
||||
|
||||
PUT /api/merchants/orders/{orderId}/ship
|
||||
功能:发货
|
||||
参数:
|
||||
- trackingNumber: 快递单号
|
||||
- carrier: 快递公司
|
||||
|
||||
PUT /api/merchants/orders/{orderId}/complete
|
||||
功能:完成订单
|
||||
```
|
||||
|
||||
## 6. 支付系统模块
|
||||
|
||||
### 6.1 支付接口
|
||||
#### 6.1.1 微信支付
|
||||
```
|
||||
POST /api/payments/wechat/create
|
||||
功能:创建微信支付订单
|
||||
参数:
|
||||
- orderId: 订单ID
|
||||
- amount: 支付金额
|
||||
- description: 支付描述
|
||||
- openid: 用户openid
|
||||
|
||||
POST /api/payments/wechat/notify
|
||||
功能:微信支付回调处理
|
||||
|
||||
GET /api/payments/wechat/query/{orderId}
|
||||
功能:查询支付状态
|
||||
```
|
||||
|
||||
#### 6.1.2 支付宝支付
|
||||
```
|
||||
POST /api/payments/alipay/create
|
||||
功能:创建支付宝支付订单
|
||||
|
||||
POST /api/payments/alipay/notify
|
||||
功能:支付宝支付回调处理
|
||||
|
||||
GET /api/payments/alipay/query/{orderId}
|
||||
功能:查询支付状态
|
||||
```
|
||||
|
||||
### 6.2 订单管理
|
||||
#### 6.2.1 订单创建
|
||||
```
|
||||
POST /api/orders
|
||||
功能:创建订单
|
||||
参数:
|
||||
- type: 订单类型(activity/product/adoption)
|
||||
- items: 订单项目
|
||||
- amount: 订单金额
|
||||
- paymentMethod: 支付方式
|
||||
- deliveryAddress: 配送地址
|
||||
|
||||
GET /api/orders/{orderId}
|
||||
功能:获取订单详情
|
||||
|
||||
GET /api/orders/my
|
||||
功能:获取我的订单列表
|
||||
```
|
||||
|
||||
#### 6.2.2 订单状态管理
|
||||
```
|
||||
PATCH /api/orders/{orderId}/status
|
||||
功能:更新订单状态
|
||||
参数:
|
||||
- status: 订单状态
|
||||
|
||||
POST /api/orders/{orderId}/refund
|
||||
功能:申请退款
|
||||
参数:
|
||||
- reason: 退款原因
|
||||
- amount: 退款金额
|
||||
|
||||
PUT /api/orders/{orderId}/refund/approve
|
||||
功能:审核退款申请
|
||||
```
|
||||
|
||||
### 6.3 财务管理
|
||||
#### 6.3.1 账户管理
|
||||
```
|
||||
GET /api/wallet/balance
|
||||
功能:获取账户余额
|
||||
|
||||
POST /api/wallet/recharge
|
||||
功能:账户充值
|
||||
参数:
|
||||
- amount: 充值金额
|
||||
- paymentMethod: 支付方式
|
||||
|
||||
POST /api/wallet/withdraw
|
||||
功能:申请提现
|
||||
参数:
|
||||
- amount: 提现金额
|
||||
- bankAccount: 银行账户
|
||||
```
|
||||
|
||||
#### 6.3.2 交易记录
|
||||
```
|
||||
GET /api/transactions
|
||||
功能:获取交易记录
|
||||
参数:
|
||||
- type: 交易类型
|
||||
- startDate: 开始日期
|
||||
- endDate: 结束日期
|
||||
- status: 交易状态
|
||||
|
||||
GET /api/transactions/{transactionId}
|
||||
功能:获取交易详情
|
||||
```
|
||||
|
||||
## 7. 消息通知模块
|
||||
|
||||
### 7.1 消息系统
|
||||
#### 7.1.1 站内消息
|
||||
```
|
||||
POST /api/messages
|
||||
功能:发送站内消息
|
||||
参数:
|
||||
- receiverId: 接收者ID
|
||||
- type: 消息类型
|
||||
- title: 消息标题
|
||||
- content: 消息内容
|
||||
|
||||
GET /api/messages
|
||||
功能:获取消息列表
|
||||
参数:
|
||||
- type: 消息类型
|
||||
- status: 读取状态
|
||||
|
||||
PUT /api/messages/{messageId}/read
|
||||
功能:标记消息已读
|
||||
```
|
||||
|
||||
#### 7.1.2 推送通知
|
||||
```
|
||||
POST /api/notifications/push
|
||||
功能:发送推送通知
|
||||
参数:
|
||||
- userIds: 用户ID列表
|
||||
- title: 通知标题
|
||||
- content: 通知内容
|
||||
- type: 通知类型
|
||||
|
||||
GET /api/notifications/settings
|
||||
功能:获取通知设置
|
||||
|
||||
PUT /api/notifications/settings
|
||||
功能:更新通知设置
|
||||
```
|
||||
|
||||
### 7.2 短信服务
|
||||
#### 7.2.1 验证码短信
|
||||
```
|
||||
POST /api/sms/verification
|
||||
功能:发送验证码短信
|
||||
参数:
|
||||
- phone: 手机号码
|
||||
- type: 验证类型
|
||||
- template: 短信模板
|
||||
|
||||
POST /api/sms/verify
|
||||
功能:验证短信验证码
|
||||
参数:
|
||||
- phone: 手机号码
|
||||
- code: 验证码
|
||||
```
|
||||
|
||||
#### 7.2.2 通知短信
|
||||
```
|
||||
POST /api/sms/notification
|
||||
功能:发送通知短信
|
||||
参数:
|
||||
- phone: 手机号码
|
||||
- template: 短信模板
|
||||
- params: 模板参数
|
||||
|
||||
GET /api/sms/records
|
||||
功能:获取短信发送记录
|
||||
```
|
||||
|
||||
### 7.3 邮件服务
|
||||
#### 7.3.1 邮件发送
|
||||
```
|
||||
POST /api/emails/send
|
||||
功能:发送邮件
|
||||
参数:
|
||||
- to: 收件人邮箱
|
||||
- subject: 邮件主题
|
||||
- content: 邮件内容
|
||||
- template: 邮件模板
|
||||
|
||||
GET /api/emails/templates
|
||||
功能:获取邮件模板列表
|
||||
|
||||
POST /api/emails/templates
|
||||
功能:创建邮件模板
|
||||
```
|
||||
|
||||
## 8. 文件管理模块
|
||||
|
||||
### 8.1 文件上传
|
||||
#### 8.1.1 图片上传
|
||||
```
|
||||
POST /api/files/images/upload
|
||||
功能:上传图片文件
|
||||
参数:
|
||||
- file: 图片文件
|
||||
- type: 图片类型(avatar/product/activity等)
|
||||
- compress: 是否压缩
|
||||
|
||||
POST /api/files/images/batch
|
||||
功能:批量上传图片
|
||||
参数:
|
||||
- files: 图片文件数组
|
||||
```
|
||||
|
||||
#### 8.1.2 文档上传
|
||||
```
|
||||
POST /api/files/documents/upload
|
||||
功能:上传文档文件
|
||||
参数:
|
||||
- file: 文档文件
|
||||
- type: 文档类型
|
||||
|
||||
GET /api/files/{fileId}
|
||||
功能:获取文件信息
|
||||
|
||||
DELETE /api/files/{fileId}
|
||||
功能:删除文件
|
||||
```
|
||||
|
||||
### 8.2 文件管理
|
||||
#### 8.2.1 文件列表
|
||||
```
|
||||
GET /api/files
|
||||
功能:获取文件列表
|
||||
参数:
|
||||
- type: 文件类型
|
||||
- userId: 用户ID
|
||||
- page: 页码
|
||||
- limit: 每页数量
|
||||
|
||||
GET /api/files/storage/usage
|
||||
功能:获取存储使用情况
|
||||
```
|
||||
|
||||
#### 8.2.2 文件处理
|
||||
```
|
||||
POST /api/files/images/resize
|
||||
功能:图片尺寸调整
|
||||
参数:
|
||||
- fileId: 文件ID
|
||||
- width: 宽度
|
||||
- height: 高度
|
||||
|
||||
POST /api/files/images/watermark
|
||||
功能:添加水印
|
||||
参数:
|
||||
- fileId: 文件ID
|
||||
- watermark: 水印内容
|
||||
```
|
||||
|
||||
## 9. 数据统计模块
|
||||
|
||||
### 9.1 用户统计
|
||||
#### 9.1.1 用户数据
|
||||
```
|
||||
GET /api/statistics/users/overview
|
||||
功能:获取用户概览统计
|
||||
|
||||
GET /api/statistics/users/growth
|
||||
功能:获取用户增长统计
|
||||
参数:
|
||||
- startDate: 开始日期
|
||||
- endDate: 结束日期
|
||||
- granularity: 统计粒度(day/week/month)
|
||||
|
||||
GET /api/statistics/users/activity
|
||||
功能:获取用户活跃度统计
|
||||
```
|
||||
|
||||
#### 9.1.2 用户行为
|
||||
```
|
||||
GET /api/statistics/users/behavior
|
||||
功能:获取用户行为统计
|
||||
|
||||
POST /api/statistics/events/track
|
||||
功能:记录用户行为事件
|
||||
参数:
|
||||
- event: 事件名称
|
||||
- properties: 事件属性
|
||||
- userId: 用户ID
|
||||
```
|
||||
|
||||
### 9.2 业务统计
|
||||
#### 9.2.1 活动统计
|
||||
```
|
||||
GET /api/statistics/activities/overview
|
||||
功能:获取活动概览统计
|
||||
|
||||
GET /api/statistics/activities/popular
|
||||
功能:获取热门活动统计
|
||||
|
||||
GET /api/statistics/activities/conversion
|
||||
功能:获取活动转化率统计
|
||||
```
|
||||
|
||||
#### 9.2.2 交易统计
|
||||
```
|
||||
GET /api/statistics/transactions/overview
|
||||
功能:获取交易概览统计
|
||||
|
||||
GET /api/statistics/transactions/revenue
|
||||
功能:获取收入统计
|
||||
|
||||
GET /api/statistics/merchants/performance
|
||||
功能:获取商家业绩统计
|
||||
```
|
||||
|
||||
## 10. 系统管理模块
|
||||
|
||||
### 10.1 配置管理
|
||||
#### 10.1.1 系统配置
|
||||
```
|
||||
GET /api/system/config
|
||||
功能:获取系统配置
|
||||
|
||||
PUT /api/system/config
|
||||
功能:更新系统配置
|
||||
参数:
|
||||
- key: 配置键
|
||||
- value: 配置值
|
||||
- description: 配置描述
|
||||
|
||||
GET /api/system/config/{key}
|
||||
功能:获取指定配置项
|
||||
```
|
||||
|
||||
#### 10.1.2 参数管理
|
||||
```
|
||||
GET /api/system/parameters
|
||||
功能:获取系统参数列表
|
||||
|
||||
PUT /api/system/parameters/{key}
|
||||
功能:更新系统参数
|
||||
参数:
|
||||
- value: 参数值
|
||||
```
|
||||
|
||||
### 10.2 日志管理
|
||||
#### 10.2.1 操作日志
|
||||
```
|
||||
GET /api/system/logs/operations
|
||||
功能:获取操作日志
|
||||
参数:
|
||||
- userId: 用户ID
|
||||
- action: 操作类型
|
||||
- startDate: 开始日期
|
||||
- endDate: 结束日期
|
||||
|
||||
POST /api/system/logs/operations
|
||||
功能:记录操作日志
|
||||
参数:
|
||||
- action: 操作类型
|
||||
- resource: 操作资源
|
||||
- details: 操作详情
|
||||
```
|
||||
|
||||
#### 10.2.2 错误日志
|
||||
```
|
||||
GET /api/system/logs/errors
|
||||
功能:获取错误日志
|
||||
|
||||
POST /api/system/logs/errors
|
||||
功能:记录错误日志
|
||||
参数:
|
||||
- level: 错误级别
|
||||
- message: 错误消息
|
||||
- stack: 错误堆栈
|
||||
- context: 错误上下文
|
||||
```
|
||||
|
||||
### 10.3 监控管理
|
||||
#### 10.3.1 系统监控
|
||||
```
|
||||
GET /api/system/health
|
||||
功能:系统健康检查
|
||||
|
||||
GET /api/system/metrics
|
||||
功能:获取系统指标
|
||||
参数:
|
||||
- metric: 指标类型
|
||||
- timeRange: 时间范围
|
||||
|
||||
GET /api/system/status
|
||||
功能:获取系统状态
|
||||
```
|
||||
|
||||
#### 10.3.2 性能监控
|
||||
```
|
||||
GET /api/system/performance
|
||||
功能:获取性能数据
|
||||
|
||||
GET /api/system/performance/api
|
||||
功能:获取API性能统计
|
||||
|
||||
GET /api/system/performance/database
|
||||
功能:获取数据库性能统计
|
||||
```
|
||||
2515
docs/安全和权限管理文档.md
2515
docs/安全和权限管理文档.md
File diff suppressed because it is too large
Load Diff
1996
docs/安全文档.md
Normal file
1996
docs/安全文档.md
Normal file
File diff suppressed because it is too large
Load Diff
277
docs/官网需求文档.md
Normal file
277
docs/官网需求文档.md
Normal file
@@ -0,0 +1,277 @@
|
||||
# 解班客官网需求文档
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
### 1.1 官网定位
|
||||
解班客官网作为品牌展示和商家入驻的主要平台,承担着品牌宣传、用户引流、商家服务、信息展示等重要职能。
|
||||
|
||||
### 1.2 目标用户
|
||||
- **潜在用户**:了解平台服务,下载小程序
|
||||
- **商家用户**:了解入驻政策,提交入驻申请
|
||||
- **媒体记者**:获取品牌资讯和新闻素材
|
||||
- **投资者**:了解公司发展和商业模式
|
||||
|
||||
### 1.3 核心目标
|
||||
- 提升品牌知名度和影响力
|
||||
- 吸引更多用户下载使用小程序
|
||||
- 为商家提供便捷的入驻渠道
|
||||
- 建立权威的信息发布平台
|
||||
|
||||
## 2. 功能需求
|
||||
|
||||
### 2.1 首页
|
||||
#### 2.1.1 品牌展示区
|
||||
- **品牌Logo和Slogan**:突出显示解班客品牌标识
|
||||
- **核心价值主张**:简洁明了地传达平台价值
|
||||
- **视觉冲击力**:使用高质量的背景图片或视频
|
||||
- **行动召唤按钮**:引导用户下载小程序
|
||||
|
||||
#### 2.1.2 功能介绍区
|
||||
- **结伴旅行功能**:图文并茂展示结伴旅行特色
|
||||
- **动物认领功能**:突出创新的动物认领服务
|
||||
- **商家服务功能**:展示多元化的商家服务
|
||||
- **用户评价展示**:真实用户反馈和评价
|
||||
|
||||
#### 2.1.3 数据展示区
|
||||
- **用户数量统计**:实时显示注册用户数
|
||||
- **活动数量统计**:展示平台活动总数
|
||||
- **认领动物数量**:显示已认领动物数量
|
||||
- **商家数量统计**:展示入驻商家数量
|
||||
|
||||
#### 2.1.4 新闻资讯区
|
||||
- **最新动态**:平台最新功能和活动
|
||||
- **媒体报道**:权威媒体的相关报道
|
||||
- **用户故事**:精选用户使用体验分享
|
||||
- **行业资讯**:相关行业的新闻动态
|
||||
|
||||
### 2.2 关于我们页面
|
||||
#### 2.2.1 公司介绍
|
||||
- **发展历程**:公司成立和发展的重要节点
|
||||
- **企业文化**:公司价值观和使命愿景
|
||||
- **团队介绍**:核心团队成员介绍
|
||||
- **荣誉资质**:获得的奖项和认证
|
||||
|
||||
#### 2.2.2 联系方式
|
||||
- **公司地址**:详细的办公地址和地图
|
||||
- **联系电话**:客服电话和工作时间
|
||||
- **邮箱地址**:官方邮箱和各部门邮箱
|
||||
- **社交媒体**:微信公众号、微博等链接
|
||||
|
||||
### 2.3 服务介绍页面
|
||||
#### 2.3.1 结伴旅行服务
|
||||
- **服务特色**:详细介绍结伴旅行的优势
|
||||
- **使用流程**:图文展示使用步骤
|
||||
- **安全保障**:用户安全和权益保护措施
|
||||
- **成功案例**:精选的成功结伴案例
|
||||
|
||||
#### 2.3.2 动物认领服务
|
||||
- **认领流程**:详细的认领步骤说明
|
||||
- **动物种类**:可认领的动物类型介绍
|
||||
- **农场介绍**:合作农场的基本信息
|
||||
- **探访服务**:农场探访的安排和服务
|
||||
|
||||
#### 2.3.3 商家服务
|
||||
- **服务类型**:支持的商家类型和服务
|
||||
- **入驻优势**:平台为商家提供的价值
|
||||
- **成功案例**:优秀商家的成功故事
|
||||
- **支持政策**:平台对商家的扶持政策
|
||||
|
||||
### 2.4 商家入驻页面
|
||||
#### 2.4.1 入驻申请表单
|
||||
- **基本信息**:商家名称、联系人、联系方式
|
||||
- **业务信息**:经营范围、服务类型、营业执照
|
||||
- **资质证明**:相关行业资质和证书上传
|
||||
- **店铺信息**:店铺介绍、地址、营业时间
|
||||
|
||||
#### 2.4.2 入驻政策
|
||||
- **入驻条件**:明确的入驻门槛和要求
|
||||
- **费用说明**:入驻费用和分成政策
|
||||
- **服务支持**:平台提供的技术和运营支持
|
||||
- **合作流程**:从申请到正式入驻的流程
|
||||
|
||||
#### 2.4.3 商家权益
|
||||
- **流量支持**:平台流量倾斜和推广支持
|
||||
- **技术支持**:系统使用培训和技术服务
|
||||
- **运营支持**:营销活动和运营指导
|
||||
- **数据支持**:经营数据分析和报告
|
||||
|
||||
### 2.5 新闻资讯页面
|
||||
#### 2.5.1 新闻分类
|
||||
- **公司动态**:公司发展和重要事件
|
||||
- **产品更新**:新功能发布和产品优化
|
||||
- **行业资讯**:相关行业的新闻和趋势
|
||||
- **用户故事**:用户使用体验和成功案例
|
||||
|
||||
#### 2.5.2 内容管理
|
||||
- **文章发布**:支持富文本编辑和图片上传
|
||||
- **分类管理**:新闻分类和标签管理
|
||||
- **评论功能**:用户评论和互动功能
|
||||
- **分享功能**:社交媒体分享功能
|
||||
|
||||
### 2.6 帮助中心页面
|
||||
#### 2.6.1 常见问题
|
||||
- **使用指南**:平台使用的详细说明
|
||||
- **账户问题**:注册、登录、密码等问题
|
||||
- **支付问题**:支付方式、退款等问题
|
||||
- **技术问题**:常见技术故障和解决方案
|
||||
|
||||
#### 2.6.2 用户协议
|
||||
- **服务协议**:用户使用平台的协议条款
|
||||
- **隐私政策**:用户隐私保护政策
|
||||
- **免责声明**:平台免责条款
|
||||
- **投诉举报**:投诉举报渠道和处理流程
|
||||
|
||||
### 2.7 下载页面
|
||||
#### 2.7.1 小程序下载
|
||||
- **微信小程序码**:高清的小程序二维码
|
||||
- **使用说明**:扫码使用的详细步骤
|
||||
- **功能预览**:小程序主要功能截图
|
||||
- **用户评价**:小程序的用户评分和评价
|
||||
|
||||
#### 2.7.2 其他下载
|
||||
- **APP下载**:未来APP版本的下载链接
|
||||
- **宣传资料**:公司宣传册和产品介绍
|
||||
- **媒体资源**:高清Logo、产品图片等
|
||||
|
||||
## 3. 设计需求
|
||||
|
||||
### 3.1 视觉设计
|
||||
#### 3.1.1 设计风格
|
||||
- **现代简约**:简洁大方的设计风格
|
||||
- **温馨友好**:体现社交和温暖的品牌调性
|
||||
- **专业可信**:建立用户信任感
|
||||
- **响应式设计**:适配各种设备和屏幕
|
||||
|
||||
#### 3.1.2 色彩方案
|
||||
- **主色调**:品牌主色,体现活力和温暖
|
||||
- **辅助色**:搭配色彩,增强视觉层次
|
||||
- **中性色**:文字和背景色,保证可读性
|
||||
- **强调色**:按钮和重要信息的突出色彩
|
||||
|
||||
#### 3.1.3 字体规范
|
||||
- **标题字体**:醒目的标题字体
|
||||
- **正文字体**:易读的正文字体
|
||||
- **字号层级**:清晰的字号层级体系
|
||||
- **行间距**:合适的行间距和段落间距
|
||||
|
||||
### 3.2 交互设计
|
||||
#### 3.2.1 导航设计
|
||||
- **主导航**:清晰的主要页面导航
|
||||
- **面包屑导航**:页面层级导航
|
||||
- **搜索功能**:全站内容搜索
|
||||
- **快速链接**:常用功能的快速入口
|
||||
|
||||
#### 3.2.2 用户体验
|
||||
- **加载速度**:页面快速加载
|
||||
- **交互反馈**:清晰的操作反馈
|
||||
- **错误处理**:友好的错误提示
|
||||
- **无障碍设计**:支持无障碍访问
|
||||
|
||||
### 3.3 移动端适配
|
||||
#### 3.3.1 响应式布局
|
||||
- **断点设置**:合理的响应式断点
|
||||
- **布局调整**:不同屏幕的布局优化
|
||||
- **图片适配**:图片的响应式处理
|
||||
- **字体缩放**:移动端字体大小调整
|
||||
|
||||
#### 3.3.2 触控优化
|
||||
- **按钮大小**:适合触控的按钮尺寸
|
||||
- **间距设置**:合适的元素间距
|
||||
- **滑动操作**:支持触控滑动
|
||||
- **手势支持**:常用手势操作支持
|
||||
|
||||
## 4. 技术需求
|
||||
|
||||
### 4.1 前端技术
|
||||
- **开发框架**:Vue 3 + JavaScript
|
||||
- **UI框架**:自定义CSS + 响应式设计
|
||||
- **路由管理**:Vue Router
|
||||
- **构建工具**:Vite
|
||||
- **SEO优化**:Vue Meta
|
||||
|
||||
### 4.2 后端支持
|
||||
- **内容管理**:支持动态内容更新
|
||||
- **数据接口**:提供必要的数据API
|
||||
- **文件上传**:支持图片和文档上传
|
||||
- **表单处理**:处理用户提交的表单
|
||||
|
||||
### 4.3 SEO优化
|
||||
#### 4.3.1 搜索引擎优化
|
||||
- **关键词优化**:页面关键词布局
|
||||
- **Meta标签**:完善的Meta信息
|
||||
- **结构化数据**:Schema.org标记
|
||||
- **网站地图**:XML和HTML网站地图
|
||||
|
||||
#### 4.3.2 性能优化
|
||||
- **页面速度**:优化页面加载速度
|
||||
- **图片优化**:图片压缩和懒加载
|
||||
- **代码优化**:CSS和JS代码优化
|
||||
- **CDN加速**:使用CDN加速资源加载
|
||||
|
||||
## 5. 内容需求
|
||||
|
||||
### 5.1 文案内容
|
||||
- **品牌文案**:体现品牌价值的文案
|
||||
- **功能介绍**:清晰的功能说明文案
|
||||
- **用户指南**:详细的使用指南
|
||||
- **法律条款**:完善的法律条款文本
|
||||
|
||||
### 5.2 图片素材
|
||||
- **品牌图片**:高质量的品牌形象图片
|
||||
- **功能截图**:产品功能的截图展示
|
||||
- **用户照片**:真实用户的使用照片
|
||||
- **背景图片**:页面背景和装饰图片
|
||||
|
||||
### 5.3 视频内容
|
||||
- **产品介绍视频**:产品功能演示视频
|
||||
- **用户故事视频**:用户使用体验视频
|
||||
- **企业宣传视频**:公司形象宣传视频
|
||||
- **教程视频**:使用教程和指导视频
|
||||
|
||||
## 6. 运营需求
|
||||
|
||||
### 6.1 内容更新
|
||||
- **新闻发布**:定期发布新闻和动态
|
||||
- **内容维护**:及时更新过期内容
|
||||
- **图片更新**:定期更新产品图片
|
||||
- **数据更新**:实时更新统计数据
|
||||
|
||||
### 6.2 用户互动
|
||||
- **在线客服**:提供在线客服支持
|
||||
- **留言反馈**:用户留言和反馈功能
|
||||
- **社交分享**:支持社交媒体分享
|
||||
- **邮件订阅**:新闻邮件订阅功能
|
||||
|
||||
### 6.3 数据分析
|
||||
- **访问统计**:网站访问数据统计
|
||||
- **用户行为**:用户行为数据分析
|
||||
- **转化率**:页面转化率统计
|
||||
- **SEO数据**:搜索引擎优化数据
|
||||
|
||||
## 7. 安全需求
|
||||
|
||||
### 7.1 数据安全
|
||||
- **HTTPS加密**:全站HTTPS加密
|
||||
- **数据备份**:定期数据备份
|
||||
- **访问控制**:后台访问权限控制
|
||||
- **安全监控**:安全事件监控和报警
|
||||
|
||||
### 7.2 内容安全
|
||||
- **内容审核**:用户提交内容审核
|
||||
- **垃圾信息过滤**:防止垃圾信息和广告
|
||||
- **恶意攻击防护**:防止恶意攻击和爬虫
|
||||
- **版权保护**:保护原创内容版权
|
||||
|
||||
## 8. 维护需求
|
||||
|
||||
### 8.1 技术维护
|
||||
- **系统更新**:定期系统和安全更新
|
||||
- **性能监控**:网站性能监控和优化
|
||||
- **故障处理**:快速响应和处理故障
|
||||
- **备份恢复**:数据备份和恢复机制
|
||||
|
||||
### 8.2 内容维护
|
||||
- **内容更新**:定期更新网站内容
|
||||
- **链接检查**:检查和修复失效链接
|
||||
- **图片优化**:优化和更新图片资源
|
||||
- **SEO维护**:持续的SEO优化工作
|
||||
1050
docs/小程序app开发文档.md
Normal file
1050
docs/小程序app开发文档.md
Normal file
File diff suppressed because it is too large
Load Diff
1813
docs/小程序app接口设计文档.md
Normal file
1813
docs/小程序app接口设计文档.md
Normal file
File diff suppressed because it is too large
Load Diff
659
docs/小程序app需求文档.md
Normal file
659
docs/小程序app需求文档.md
Normal file
@@ -0,0 +1,659 @@
|
||||
# 解班客小程序需求文档
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
### 1.1 产品定位
|
||||
解班客微信小程序是面向C端用户的核心产品,专注于提供结伴旅行和动物认领服务。通过微信生态的便利性,为用户提供便捷的社交旅行体验和创新的动物认领服务。
|
||||
|
||||
### 1.2 目标用户
|
||||
- **主要用户群体**:18-35岁的年轻用户
|
||||
- **用户特征**:热爱旅行、喜欢社交、追求新鲜体验
|
||||
- **使用场景**:碎片化时间浏览、计划旅行、寻找旅伴、管理认领动物
|
||||
|
||||
### 1.3 核心价值
|
||||
- **便捷的结伴旅行**:快速找到志同道合的旅伴
|
||||
- **创新的动物认领**:体验农场生活,建立情感连接
|
||||
- **安全的社交环境**:实名认证,安全可靠的交友平台
|
||||
- **丰富的服务生态**:整合旅行、住宿、美食、购物等服务
|
||||
|
||||
## 2. 功能需求
|
||||
|
||||
### 2.1 用户系统
|
||||
#### 2.1.1 登录注册
|
||||
- **微信授权登录**:
|
||||
- 一键微信登录,获取基本信息
|
||||
- 支持静默登录和授权登录
|
||||
- 登录状态保持和自动续期
|
||||
- 登录异常处理和重试机制
|
||||
|
||||
- **手机号绑定**:
|
||||
- 微信手机号快速验证
|
||||
- 短信验证码验证
|
||||
- 手机号更换功能
|
||||
- 多设备登录管理
|
||||
|
||||
- **用户协议**:
|
||||
- 用户服务协议展示
|
||||
- 隐私政策说明
|
||||
- 必须同意才能使用
|
||||
- 协议更新通知
|
||||
|
||||
#### 2.1.2 个人资料
|
||||
- **基本信息设置**:
|
||||
- 头像上传和裁剪
|
||||
- 昵称设置(敏感词过滤)
|
||||
- 性别选择
|
||||
- 生日设置
|
||||
- 所在城市选择
|
||||
- 个人简介编辑
|
||||
|
||||
- **兴趣标签**:
|
||||
- 预设兴趣标签选择
|
||||
- 自定义标签添加
|
||||
- 标签权重设置
|
||||
- 标签推荐算法
|
||||
|
||||
- **认证信息**:
|
||||
- 实名认证(可选)
|
||||
- 身份证认证
|
||||
- 芝麻信用认证
|
||||
- 认证状态展示
|
||||
|
||||
#### 2.1.3 隐私设置
|
||||
- **个人信息可见性**:
|
||||
- 手机号可见范围
|
||||
- 位置信息共享设置
|
||||
- 个人资料可见性
|
||||
- 活动历史可见性
|
||||
|
||||
- **消息通知设置**:
|
||||
- 系统通知开关
|
||||
- 活动通知设置
|
||||
- 私信通知设置
|
||||
- 推送时间段设置
|
||||
|
||||
### 2.2 首页模块
|
||||
#### 2.2.1 首页布局
|
||||
- **顶部导航**:
|
||||
- 位置信息显示
|
||||
- 搜索入口
|
||||
- 消息通知图标
|
||||
- 个人头像入口
|
||||
|
||||
- **轮播图区域**:
|
||||
- 平台活动推广
|
||||
- 热门活动推荐
|
||||
- 新功能介绍
|
||||
- 商家广告展示
|
||||
|
||||
- **快捷功能区**:
|
||||
- 发布活动入口
|
||||
- 我的认领入口
|
||||
- 附近活动入口
|
||||
- 更多功能入口
|
||||
|
||||
#### 2.2.2 内容推荐
|
||||
- **推荐算法**:
|
||||
- 基于地理位置推荐
|
||||
- 基于兴趣标签推荐
|
||||
- 基于历史行为推荐
|
||||
- 基于社交关系推荐
|
||||
|
||||
- **内容类型**:
|
||||
- 热门活动推荐
|
||||
- 附近活动展示
|
||||
- 新用户活动推荐
|
||||
- 个性化内容推荐
|
||||
|
||||
#### 2.2.3 搜索功能
|
||||
- **搜索类型**:
|
||||
- 活动搜索
|
||||
- 用户搜索
|
||||
- 地点搜索
|
||||
- 综合搜索
|
||||
|
||||
- **搜索功能**:
|
||||
- 关键词搜索
|
||||
- 语音搜索
|
||||
- 图片搜索
|
||||
- 搜索历史记录
|
||||
|
||||
### 2.3 结伴旅行模块
|
||||
#### 2.3.1 活动发布
|
||||
- **活动信息填写**:
|
||||
- 活动标题(必填)
|
||||
- 活动类型选择(旅行/聚餐/看电影/户外运动等)
|
||||
- 活动描述(支持富文本)
|
||||
- 活动时间选择(开始时间、结束时间)
|
||||
- 活动地点选择(地图选点、地址搜索)
|
||||
- 参与人数限制
|
||||
- 费用说明(AA制/免费/付费)
|
||||
- 联系方式设置
|
||||
|
||||
- **活动图片**:
|
||||
- 多图片上传(最多9张)
|
||||
- 图片编辑和滤镜
|
||||
- 图片排序和删除
|
||||
- 封面图片设置
|
||||
|
||||
- **参与要求**:
|
||||
- 性别要求
|
||||
- 年龄范围
|
||||
- 兴趣标签要求
|
||||
- 其他自定义要求
|
||||
|
||||
- **发布设置**:
|
||||
- 立即发布/定时发布
|
||||
- 活动可见性设置
|
||||
- 报名审核开关
|
||||
- 活动分享设置
|
||||
|
||||
#### 2.3.2 活动浏览
|
||||
- **活动列表**:
|
||||
- 瀑布流/列表切换
|
||||
- 活动卡片信息展示
|
||||
- 无限滚动加载
|
||||
- 下拉刷新
|
||||
|
||||
- **筛选功能**:
|
||||
- 活动类型筛选
|
||||
- 时间范围筛选
|
||||
- 距离范围筛选
|
||||
- 价格范围筛选
|
||||
- 人数范围筛选
|
||||
|
||||
- **排序功能**:
|
||||
- 按时间排序
|
||||
- 按距离排序
|
||||
- 按热度排序
|
||||
- 按价格排序
|
||||
|
||||
#### 2.3.3 活动详情
|
||||
- **活动信息展示**:
|
||||
- 活动基本信息
|
||||
- 发起人信息
|
||||
- 参与者列表
|
||||
- 活动位置地图
|
||||
- 相关推荐活动
|
||||
|
||||
- **互动功能**:
|
||||
- 点赞/收藏
|
||||
- 评论/回复
|
||||
- 分享功能
|
||||
- 举报功能
|
||||
|
||||
- **报名功能**:
|
||||
- 报名按钮
|
||||
- 报名表单填写
|
||||
- 报名状态显示
|
||||
- 取消报名
|
||||
|
||||
#### 2.3.4 活动管理
|
||||
- **我发布的活动**:
|
||||
- 活动列表展示
|
||||
- 活动状态管理
|
||||
- 参与者管理
|
||||
- 活动编辑/删除
|
||||
|
||||
- **我参与的活动**:
|
||||
- 报名状态查看
|
||||
- 活动提醒设置
|
||||
- 活动评价
|
||||
- 活动分享
|
||||
|
||||
- **活动通知**:
|
||||
- 报名通知
|
||||
- 活动提醒
|
||||
- 状态变更通知
|
||||
- 消息推送
|
||||
|
||||
### 2.4 动物认领模块
|
||||
#### 2.4.1 动物展示
|
||||
- **动物列表**:
|
||||
- 动物卡片展示
|
||||
- 动物基本信息
|
||||
- 认领状态显示
|
||||
- 筛选和搜索
|
||||
|
||||
- **动物详情**:
|
||||
- 动物详细信息
|
||||
- 成长记录展示
|
||||
- 农场信息
|
||||
- 认领价格和周期
|
||||
|
||||
- **动物分类**:
|
||||
- 按动物类型分类
|
||||
- 按年龄分类
|
||||
- 按价格分类
|
||||
- 按农场分类
|
||||
|
||||
#### 2.4.2 认领流程
|
||||
- **认领申请**:
|
||||
- 认领申请表单
|
||||
- 认领原因填写
|
||||
- 探访计划制定
|
||||
- 认领协议确认
|
||||
|
||||
- **支付流程**:
|
||||
- 认领费用支付
|
||||
- 支付方式选择
|
||||
- 支付状态跟踪
|
||||
- 发票申请
|
||||
|
||||
- **认领确认**:
|
||||
- 认领审核状态
|
||||
- 认领证书生成
|
||||
- 动物信息绑定
|
||||
- 认领成功通知
|
||||
|
||||
#### 2.4.3 认领管理
|
||||
- **我的动物**:
|
||||
- 认领动物列表
|
||||
- 动物状态查看
|
||||
- 成长记录查看
|
||||
- 探访预约
|
||||
|
||||
- **互动功能**:
|
||||
- 给动物起名
|
||||
- 上传互动照片
|
||||
- 记录成长日记
|
||||
- 分享动物动态
|
||||
|
||||
- **农场服务**:
|
||||
- 农场探访预约
|
||||
- 探访路线导航
|
||||
- 农场活动参与
|
||||
- 农产品购买
|
||||
|
||||
### 2.5 社交功能模块
|
||||
#### 2.5.1 消息系统
|
||||
- **私信功能**:
|
||||
- 一对一聊天
|
||||
- 文字/图片/语音消息
|
||||
- 表情包发送
|
||||
- 消息撤回/删除
|
||||
|
||||
- **群聊功能**:
|
||||
- 活动群聊
|
||||
- 群成员管理
|
||||
- 群公告发布
|
||||
- 群文件共享
|
||||
|
||||
- **系统消息**:
|
||||
- 系统通知
|
||||
- 活动通知
|
||||
- 认领通知
|
||||
- 安全提醒
|
||||
|
||||
#### 2.5.2 动态功能
|
||||
- **动态发布**:
|
||||
- 图文动态发布
|
||||
- 视频动态发布
|
||||
- 位置标记
|
||||
- 话题标签
|
||||
|
||||
- **动态浏览**:
|
||||
- 关注动态流
|
||||
- 推荐动态
|
||||
- 附近动态
|
||||
- 话题动态
|
||||
|
||||
- **互动功能**:
|
||||
- 点赞/评论/转发
|
||||
- @好友功能
|
||||
- 动态收藏
|
||||
- 动态举报
|
||||
|
||||
#### 2.5.3 关注系统
|
||||
- **关注功能**:
|
||||
- 关注/取消关注
|
||||
- 关注列表管理
|
||||
- 粉丝列表查看
|
||||
- 互相关注标识
|
||||
|
||||
- **推荐关注**:
|
||||
- 基于兴趣推荐
|
||||
- 基于地理位置推荐
|
||||
- 基于共同好友推荐
|
||||
- 基于活动参与推荐
|
||||
|
||||
### 2.6 商家服务模块
|
||||
#### 2.6.1 商家展示
|
||||
- **商家列表**:
|
||||
- 商家卡片展示
|
||||
- 商家基本信息
|
||||
- 评分和评价
|
||||
- 距离和导航
|
||||
|
||||
- **商家详情**:
|
||||
- 商家详细信息
|
||||
- 服务项目展示
|
||||
- 用户评价
|
||||
- 联系方式
|
||||
|
||||
- **商家分类**:
|
||||
- 按服务类型分类
|
||||
- 按地理位置分类
|
||||
- 按评分排序
|
||||
- 按距离排序
|
||||
|
||||
#### 2.6.2 商品服务
|
||||
- **商品浏览**:
|
||||
- 商品列表展示
|
||||
- 商品详情查看
|
||||
- 商品图片展示
|
||||
- 价格和库存信息
|
||||
|
||||
- **购买流程**:
|
||||
- 商品选择和规格
|
||||
- 购物车管理
|
||||
- 订单确认
|
||||
- 支付和配送
|
||||
|
||||
- **订单管理**:
|
||||
- 订单状态跟踪
|
||||
- 物流信息查看
|
||||
- 订单评价
|
||||
- 售后服务
|
||||
|
||||
### 2.7 个人中心模块
|
||||
#### 2.7.1 个人信息
|
||||
- **基本信息展示**:
|
||||
- 头像和昵称
|
||||
- 认证状态
|
||||
- 个人统计数据
|
||||
- 快捷功能入口
|
||||
|
||||
- **个人资料编辑**:
|
||||
- 基本信息修改
|
||||
- 兴趣标签设置
|
||||
- 隐私设置
|
||||
- 账户安全设置
|
||||
|
||||
#### 2.7.2 我的活动
|
||||
- **活动记录**:
|
||||
- 发布的活动
|
||||
- 参与的活动
|
||||
- 收藏的活动
|
||||
- 活动历史
|
||||
|
||||
- **活动统计**:
|
||||
- 活动参与次数
|
||||
- 活动发布次数
|
||||
- 活动评分
|
||||
- 活动成就
|
||||
|
||||
#### 2.7.3 我的认领
|
||||
- **认领记录**:
|
||||
- 当前认领动物
|
||||
- 历史认领记录
|
||||
- 认领证书
|
||||
- 探访记录
|
||||
|
||||
- **认领统计**:
|
||||
- 认领总数
|
||||
- 认领时长
|
||||
- 探访次数
|
||||
- 认领成就
|
||||
|
||||
#### 2.7.4 钱包功能
|
||||
- **余额管理**:
|
||||
- 余额查看
|
||||
- 充值功能
|
||||
- 提现功能
|
||||
- 交易记录
|
||||
|
||||
- **支付管理**:
|
||||
- 支付方式设置
|
||||
- 支付密码设置
|
||||
- 自动支付设置
|
||||
- 支付安全
|
||||
|
||||
#### 2.7.5 设置中心
|
||||
- **账户设置**:
|
||||
- 个人信息设置
|
||||
- 隐私设置
|
||||
- 安全设置
|
||||
- 通知设置
|
||||
|
||||
- **应用设置**:
|
||||
- 语言设置
|
||||
- 字体大小设置
|
||||
- 夜间模式
|
||||
- 缓存清理
|
||||
|
||||
- **帮助支持**:
|
||||
- 使用帮助
|
||||
- 常见问题
|
||||
- 意见反馈
|
||||
- 联系客服
|
||||
|
||||
## 3. 用户体验需求
|
||||
|
||||
### 3.1 界面设计
|
||||
#### 3.1.1 设计风格
|
||||
- **现代简约**:简洁清爽的界面设计
|
||||
- **温馨友好**:体现社交和温暖的品牌调性
|
||||
- **年轻活力**:符合年轻用户的审美偏好
|
||||
- **一致性**:保持整体设计风格的统一
|
||||
|
||||
#### 3.1.2 色彩方案
|
||||
- **主色调**:温暖的橙色系,体现活力和友好
|
||||
- **辅助色**:清新的绿色系,体现自然和生机
|
||||
- **中性色**:灰色系作为背景和文字色
|
||||
- **强调色**:红色用于重要提示和警告
|
||||
|
||||
#### 3.1.3 字体规范
|
||||
- **标题字体**:醒目清晰的标题字体
|
||||
- **正文字体**:易读的正文字体
|
||||
- **字号层级**:合理的字号层级体系
|
||||
- **行间距**:舒适的行间距设置
|
||||
|
||||
### 3.2 交互设计
|
||||
#### 3.2.1 导航设计
|
||||
- **底部导航**:主要功能模块的快速切换
|
||||
- **顶部导航**:页面标题和功能按钮
|
||||
- **面包屑导航**:页面层级关系展示
|
||||
- **手势导航**:支持滑动返回等手势操作
|
||||
|
||||
#### 3.2.2 操作反馈
|
||||
- **点击反馈**:按钮点击的视觉和触觉反馈
|
||||
- **加载状态**:数据加载的进度提示
|
||||
- **操作结果**:操作成功或失败的明确提示
|
||||
- **错误处理**:友好的错误提示和解决建议
|
||||
|
||||
#### 3.2.3 动画效果
|
||||
- **页面转场**:流畅的页面切换动画
|
||||
- **元素动画**:适度的元素动画效果
|
||||
- **加载动画**:有趣的加载动画设计
|
||||
- **微交互**:细节的微交互动画
|
||||
|
||||
### 3.3 性能优化
|
||||
#### 3.3.1 加载性能
|
||||
- **首屏加载**:首屏加载时间 < 2秒
|
||||
- **图片优化**:图片懒加载和压缩
|
||||
- **代码分包**:合理的代码分包策略
|
||||
- **缓存策略**:有效的缓存机制
|
||||
|
||||
#### 3.3.2 运行性能
|
||||
- **流畅度**:保持60fps的流畅体验
|
||||
- **内存管理**:合理的内存使用和释放
|
||||
- **电量优化**:减少不必要的电量消耗
|
||||
- **网络优化**:减少网络请求和数据传输
|
||||
|
||||
### 3.4 适配要求
|
||||
#### 3.4.1 设备适配
|
||||
- **iPhone适配**:iPhone 6及以上设备
|
||||
- **Android适配**:主流Android设备
|
||||
- **屏幕适配**:不同屏幕尺寸的适配
|
||||
- **系统适配**:iOS 10+、Android 6.0+
|
||||
|
||||
#### 3.4.2 微信版本适配
|
||||
- **微信版本**:微信7.0及以上版本
|
||||
- **基础库版本**:2.10.0及以上版本
|
||||
- **API兼容**:新旧API的兼容处理
|
||||
- **功能降级**:低版本的功能降级方案
|
||||
|
||||
## 4. 技术需求
|
||||
|
||||
### 4.1 开发技术
|
||||
#### 4.1.1 开发框架
|
||||
- **原生小程序**:使用微信原生小程序开发
|
||||
- **UI组件库**:Vant Weapp组件库
|
||||
- **状态管理**:原生状态管理或MobX
|
||||
- **网络请求**:wx.request封装
|
||||
|
||||
#### 4.1.2 开发工具
|
||||
- **微信开发者工具**:官方开发调试工具
|
||||
- **代码编辑器**:VS Code等现代编辑器
|
||||
- **版本控制**:Git版本控制
|
||||
- **构建工具**:微信开发者工具内置构建
|
||||
|
||||
### 4.2 API集成
|
||||
#### 4.2.1 微信API
|
||||
- **登录API**:wx.login、wx.getUserProfile
|
||||
- **支付API**:wx.requestPayment
|
||||
- **分享API**:wx.shareAppMessage、wx.shareTimeline
|
||||
- **地图API**:wx.getLocation、wx.openLocation
|
||||
|
||||
#### 4.2.2 第三方API
|
||||
- **地图服务**:腾讯地图API
|
||||
- **支付服务**:微信支付API
|
||||
- **短信服务**:阿里云短信API
|
||||
- **云存储**:腾讯云COS或阿里云OSS
|
||||
|
||||
### 4.3 数据管理
|
||||
#### 4.3.1 本地存储
|
||||
- **用户数据**:用户信息和设置的本地缓存
|
||||
- **业务数据**:活动和动物信息的本地缓存
|
||||
- **图片缓存**:图片资源的本地缓存
|
||||
- **离线数据**:支持部分功能的离线使用
|
||||
|
||||
#### 4.3.2 数据同步
|
||||
- **实时同步**:关键数据的实时同步
|
||||
- **增量同步**:大量数据的增量同步
|
||||
- **冲突处理**:数据冲突的处理机制
|
||||
- **数据校验**:数据完整性和一致性校验
|
||||
|
||||
## 5. 安全需求
|
||||
|
||||
### 5.1 用户安全
|
||||
#### 5.1.1 身份验证
|
||||
- **微信授权**:安全的微信登录授权
|
||||
- **手机验证**:手机号验证码验证
|
||||
- **实名认证**:可选的实名认证功能
|
||||
- **设备绑定**:设备信息绑定和验证
|
||||
|
||||
#### 5.1.2 数据保护
|
||||
- **数据加密**:敏感数据的加密传输
|
||||
- **隐私保护**:用户隐私信息的保护
|
||||
- **权限控制**:细粒度的权限控制
|
||||
- **数据脱敏**:敏感信息的脱敏处理
|
||||
|
||||
### 5.2 交易安全
|
||||
#### 5.2.1 支付安全
|
||||
- **支付验证**:支付密码或指纹验证
|
||||
- **交易加密**:支付信息的加密传输
|
||||
- **风险控制**:异常交易的风险控制
|
||||
- **资金保护**:用户资金的安全保护
|
||||
|
||||
#### 5.2.2 信息安全
|
||||
- **内容审核**:用户发布内容的审核
|
||||
- **举报机制**:不当内容的举报处理
|
||||
- **黑名单**:恶意用户的黑名单机制
|
||||
- **安全提醒**:安全风险的及时提醒
|
||||
|
||||
### 5.3 系统安全
|
||||
#### 5.3.1 接口安全
|
||||
- **接口鉴权**:API接口的安全鉴权
|
||||
- **参数验证**:接口参数的严格验证
|
||||
- **频率限制**:接口调用频率的限制
|
||||
- **异常监控**:异常请求的监控和处理
|
||||
|
||||
#### 5.3.2 代码安全
|
||||
- **代码混淆**:小程序代码的混淆保护
|
||||
- **版本控制**:代码版本的安全管理
|
||||
- **漏洞扫描**:定期的安全漏洞扫描
|
||||
- **安全更新**:及时的安全补丁更新
|
||||
|
||||
## 6. 运营需求
|
||||
|
||||
### 6.1 数据统计
|
||||
#### 6.1.1 用户行为统计
|
||||
- **页面访问统计**:各页面的访问量和停留时间
|
||||
- **功能使用统计**:各功能模块的使用情况
|
||||
- **用户路径分析**:用户操作路径的分析
|
||||
- **转化率统计**:关键转化节点的转化率
|
||||
|
||||
#### 6.1.2 业务数据统计
|
||||
- **活动数据**:活动发布、参与、完成情况
|
||||
- **认领数据**:动物认领、探访、续费情况
|
||||
- **交易数据**:支付、退款、收入情况
|
||||
- **用户增长**:新用户注册、活跃用户统计
|
||||
|
||||
### 6.2 运营工具
|
||||
#### 6.2.1 内容管理
|
||||
- **活动推荐**:热门活动的推荐机制
|
||||
- **内容审核**:用户发布内容的审核工具
|
||||
- **标签管理**:兴趣标签的管理和维护
|
||||
- **推送管理**:消息推送的管理工具
|
||||
|
||||
#### 6.2.2 用户运营
|
||||
- **用户分群**:用户群体的细分和标记
|
||||
- **活动营销**:营销活动的策划和执行
|
||||
- **积分系统**:用户积分的获取和消费
|
||||
- **等级系统**:用户等级的升级和权益
|
||||
|
||||
### 6.3 客服支持
|
||||
#### 6.3.1 在线客服
|
||||
- **客服入口**:便捷的客服联系入口
|
||||
- **问题分类**:常见问题的分类和解答
|
||||
- **工单系统**:复杂问题的工单处理
|
||||
- **满意度评价**:客服服务的满意度评价
|
||||
|
||||
#### 6.3.2 帮助中心
|
||||
- **使用指南**:详细的功能使用指南
|
||||
- **常见问题**:FAQ的整理和更新
|
||||
- **视频教程**:功能操作的视频教程
|
||||
- **意见反馈**:用户意见和建议的收集
|
||||
|
||||
## 7. 测试需求
|
||||
|
||||
### 7.1 功能测试
|
||||
#### 7.1.1 基础功能测试
|
||||
- **登录注册**:各种登录注册场景的测试
|
||||
- **核心功能**:活动发布、认领等核心功能测试
|
||||
- **支付功能**:各种支付场景的测试
|
||||
- **消息功能**:消息发送接收的测试
|
||||
|
||||
#### 7.1.2 兼容性测试
|
||||
- **设备兼容**:不同设备的兼容性测试
|
||||
- **系统兼容**:不同操作系统的兼容性测试
|
||||
- **微信版本**:不同微信版本的兼容性测试
|
||||
- **网络环境**:不同网络环境的测试
|
||||
|
||||
### 7.2 性能测试
|
||||
#### 7.2.1 性能指标测试
|
||||
- **启动时间**:小程序启动时间测试
|
||||
- **页面加载**:各页面加载时间测试
|
||||
- **内存使用**:内存使用情况测试
|
||||
- **电量消耗**:电量消耗情况测试
|
||||
|
||||
#### 7.2.2 压力测试
|
||||
- **并发用户**:高并发用户的压力测试
|
||||
- **大数据量**:大数据量处理的测试
|
||||
- **网络异常**:网络异常情况的测试
|
||||
- **长时间使用**:长时间使用的稳定性测试
|
||||
|
||||
### 7.3 安全测试
|
||||
#### 7.3.1 数据安全测试
|
||||
- **数据传输**:数据传输安全性测试
|
||||
- **数据存储**:本地数据存储安全性测试
|
||||
- **权限验证**:用户权限验证测试
|
||||
- **隐私保护**:用户隐私保护测试
|
||||
|
||||
#### 7.3.2 业务安全测试
|
||||
- **支付安全**:支付流程安全性测试
|
||||
- **内容安全**:用户内容安全性测试
|
||||
- **账户安全**:用户账户安全性测试
|
||||
- **接口安全**:API接口安全性测试
|
||||
1655
docs/小程序架构文档.md
Normal file
1655
docs/小程序架构文档.md
Normal file
File diff suppressed because it is too large
Load Diff
469
docs/常见问题.md
469
docs/常见问题.md
@@ -1,469 +0,0 @@
|
||||
# 常见问题 (FAQ)
|
||||
|
||||
本文档收集了结伴客项目开发和使用过程中的常见问题及解决方案。
|
||||
|
||||
## 📋 目录
|
||||
|
||||
- [环境搭建问题](#环境搭建问题)
|
||||
- [开发相关问题](#开发相关问题)
|
||||
- [部署相关问题](#部署相关问题)
|
||||
- [数据库问题](#数据库问题)
|
||||
- [API接口问题](#api接口问题)
|
||||
- [前端问题](#前端问题)
|
||||
- [小程序问题](#小程序问题)
|
||||
- [性能优化问题](#性能优化问题)
|
||||
|
||||
## 🛠️ 环境搭建问题
|
||||
|
||||
### Q: Node.js版本要求是什么?
|
||||
**A:** 项目要求 Node.js 16.x 或更高版本。推荐使用 Node.js 18.x LTS 版本。
|
||||
|
||||
```bash
|
||||
# 检查Node.js版本
|
||||
node --version
|
||||
|
||||
# 使用nvm管理Node.js版本
|
||||
nvm install 18
|
||||
nvm use 18
|
||||
```
|
||||
|
||||
### Q: 安装依赖时出现权限错误怎么办?
|
||||
**A:** 避免使用 `sudo` 安装npm包,建议配置npm全局目录:
|
||||
|
||||
```bash
|
||||
# 创建全局目录
|
||||
mkdir ~/.npm-global
|
||||
|
||||
# 配置npm使用新目录
|
||||
npm config set prefix '~/.npm-global'
|
||||
|
||||
# 添加到环境变量
|
||||
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
### Q: MySQL连接失败怎么办?
|
||||
**A:** 检查以下几个方面:
|
||||
|
||||
1. **确认MySQL服务运行**
|
||||
```bash
|
||||
# macOS
|
||||
brew services start mysql
|
||||
|
||||
# Linux
|
||||
sudo systemctl start mysql
|
||||
|
||||
# Windows
|
||||
net start mysql
|
||||
```
|
||||
|
||||
2. **检查连接配置**
|
||||
```javascript
|
||||
// backend/.env
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_NAME=jiebanke
|
||||
DB_USER=root
|
||||
DB_PASSWORD=your_password
|
||||
```
|
||||
|
||||
3. **创建数据库**
|
||||
```sql
|
||||
CREATE DATABASE jiebanke CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
```
|
||||
|
||||
### Q: Redis连接问题如何解决?
|
||||
**A:** 确保Redis服务正常运行:
|
||||
|
||||
```bash
|
||||
# 启动Redis服务
|
||||
redis-server
|
||||
|
||||
# 测试连接
|
||||
redis-cli ping
|
||||
# 应该返回 PONG
|
||||
```
|
||||
|
||||
## 💻 开发相关问题
|
||||
|
||||
### Q: 如何重置数据库?
|
||||
**A:** 使用项目提供的重置脚本:
|
||||
|
||||
```bash
|
||||
# 方法1:使用npm脚本
|
||||
cd backend
|
||||
npm run db:reset
|
||||
|
||||
# 方法2:手动执行SQL
|
||||
mysql -u root -p jiebanke < scripts/init-database.sql
|
||||
```
|
||||
|
||||
### Q: 热重载不工作怎么办?
|
||||
**A:** 检查以下配置:
|
||||
|
||||
1. **后端热重载**
|
||||
```bash
|
||||
# 确保使用nodemon
|
||||
npm run dev
|
||||
|
||||
# 检查nodemon配置
|
||||
cat nodemon.json
|
||||
```
|
||||
|
||||
2. **前端热重载**
|
||||
```bash
|
||||
# 确保Vite配置正确
|
||||
npm run dev
|
||||
|
||||
# 检查vite.config.ts中的server配置
|
||||
```
|
||||
|
||||
### Q: ESLint报错如何解决?
|
||||
**A:** 常见解决方案:
|
||||
|
||||
```bash
|
||||
# 自动修复可修复的问题
|
||||
npm run lint:fix
|
||||
|
||||
# 检查ESLint配置
|
||||
cat .eslintrc.js
|
||||
|
||||
# 重新安装ESLint依赖
|
||||
npm install --save-dev eslint @typescript-eslint/parser
|
||||
```
|
||||
|
||||
### Q: 如何调试API接口?
|
||||
**A:** 推荐使用以下工具:
|
||||
|
||||
1. **使用内置测试脚本**
|
||||
```bash
|
||||
cd backend
|
||||
npm run test:api
|
||||
```
|
||||
|
||||
2. **使用Postman或Insomnia**
|
||||
- 导入API文档中的接口定义
|
||||
- 配置环境变量
|
||||
|
||||
3. **使用curl命令**
|
||||
```bash
|
||||
# 测试登录接口
|
||||
curl -X POST http://localhost:3000/api/v1/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"test@example.com","password":"123456"}'
|
||||
```
|
||||
|
||||
## 🚀 部署相关问题
|
||||
|
||||
### Q: Docker部署失败怎么办?
|
||||
**A:** 检查以下几个方面:
|
||||
|
||||
1. **确认Docker版本**
|
||||
```bash
|
||||
docker --version
|
||||
docker-compose --version
|
||||
```
|
||||
|
||||
2. **检查端口占用**
|
||||
```bash
|
||||
# 检查端口是否被占用
|
||||
lsof -i :3000
|
||||
lsof -i :8080
|
||||
```
|
||||
|
||||
3. **查看容器日志**
|
||||
```bash
|
||||
docker-compose logs backend
|
||||
docker-compose logs admin-system
|
||||
```
|
||||
|
||||
### Q: Nginx配置问题如何解决?
|
||||
**A:** 常见配置问题:
|
||||
|
||||
1. **检查配置文件语法**
|
||||
```bash
|
||||
nginx -t
|
||||
```
|
||||
|
||||
2. **重新加载配置**
|
||||
```bash
|
||||
nginx -s reload
|
||||
```
|
||||
|
||||
3. **查看错误日志**
|
||||
```bash
|
||||
tail -f /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
### Q: SSL证书配置问题?
|
||||
**A:** 使用Let's Encrypt免费证书:
|
||||
|
||||
```bash
|
||||
# 安装certbot
|
||||
sudo apt install certbot python3-certbot-nginx
|
||||
|
||||
# 获取证书
|
||||
sudo certbot --nginx -d yourdomain.com
|
||||
|
||||
# 自动续期
|
||||
sudo crontab -e
|
||||
# 添加:0 12 * * * /usr/bin/certbot renew --quiet
|
||||
```
|
||||
|
||||
## 🗄️ 数据库问题
|
||||
|
||||
### Q: 数据库迁移失败怎么办?
|
||||
**A:** 按以下步骤排查:
|
||||
|
||||
1. **检查迁移文件**
|
||||
```bash
|
||||
# 查看迁移状态
|
||||
npx sequelize-cli db:migrate:status
|
||||
|
||||
# 回滚迁移
|
||||
npx sequelize-cli db:migrate:undo
|
||||
```
|
||||
|
||||
2. **手动执行SQL**
|
||||
```sql
|
||||
-- 查看表结构
|
||||
DESCRIBE users;
|
||||
|
||||
-- 检查约束
|
||||
SHOW CREATE TABLE users;
|
||||
```
|
||||
|
||||
### Q: 数据库性能问题如何优化?
|
||||
**A:** 常见优化方案:
|
||||
|
||||
1. **添加索引**
|
||||
```sql
|
||||
-- 为常用查询字段添加索引
|
||||
CREATE INDEX idx_user_email ON users(email);
|
||||
CREATE INDEX idx_created_at ON travel_plans(created_at);
|
||||
```
|
||||
|
||||
2. **查询优化**
|
||||
```sql
|
||||
-- 使用EXPLAIN分析查询
|
||||
EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';
|
||||
```
|
||||
|
||||
3. **配置优化**
|
||||
```ini
|
||||
# my.cnf
|
||||
[mysqld]
|
||||
innodb_buffer_pool_size = 1G
|
||||
query_cache_size = 256M
|
||||
```
|
||||
|
||||
## 🔌 API接口问题
|
||||
|
||||
### Q: 接口返回401未授权错误?
|
||||
**A:** 检查JWT token配置:
|
||||
|
||||
1. **确认token格式**
|
||||
```javascript
|
||||
// 请求头格式
|
||||
Authorization: Bearer <your-jwt-token>
|
||||
```
|
||||
|
||||
2. **检查token有效期**
|
||||
```javascript
|
||||
// 解码token查看过期时间
|
||||
const jwt = require('jsonwebtoken');
|
||||
const decoded = jwt.decode(token);
|
||||
console.log(decoded.exp);
|
||||
```
|
||||
|
||||
### Q: 跨域问题如何解决?
|
||||
**A:** 配置CORS中间件:
|
||||
|
||||
```javascript
|
||||
// backend/src/app.js
|
||||
const cors = require('cors');
|
||||
|
||||
app.use(cors({
|
||||
origin: ['http://localhost:8080', 'https://admin.jiebanke.com'],
|
||||
credentials: true
|
||||
}));
|
||||
```
|
||||
|
||||
### Q: 文件上传失败怎么办?
|
||||
**A:** 检查以下配置:
|
||||
|
||||
1. **文件大小限制**
|
||||
```javascript
|
||||
// 增加文件大小限制
|
||||
app.use(express.json({ limit: '50mb' }));
|
||||
app.use(express.urlencoded({ limit: '50mb', extended: true }));
|
||||
```
|
||||
|
||||
2. **存储路径权限**
|
||||
```bash
|
||||
# 确保上传目录有写权限
|
||||
chmod 755 uploads/
|
||||
```
|
||||
|
||||
## 🎨 前端问题
|
||||
|
||||
### Q: 组件样式不生效怎么办?
|
||||
**A:** 检查以下几个方面:
|
||||
|
||||
1. **CSS作用域**
|
||||
```vue
|
||||
<style scoped>
|
||||
/* 组件内样式 */
|
||||
</style>
|
||||
|
||||
<style>
|
||||
/* 全局样式 */
|
||||
</style>
|
||||
```
|
||||
|
||||
2. **样式优先级**
|
||||
```css
|
||||
/* 使用!important提高优先级 */
|
||||
.my-class {
|
||||
color: red !important;
|
||||
}
|
||||
```
|
||||
|
||||
### Q: 路由跳转问题?
|
||||
**A:** 常见解决方案:
|
||||
|
||||
```javascript
|
||||
// 编程式导航
|
||||
this.$router.push('/path');
|
||||
|
||||
// 声明式导航
|
||||
<router-link to="/path">链接</router-link>
|
||||
|
||||
// 带参数跳转
|
||||
this.$router.push({
|
||||
name: 'user',
|
||||
params: { id: 123 }
|
||||
});
|
||||
```
|
||||
|
||||
### Q: 状态管理问题?
|
||||
**A:** 使用Pinia进行状态管理:
|
||||
|
||||
```javascript
|
||||
// stores/user.js
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
export const useUserStore = defineStore('user', {
|
||||
state: () => ({
|
||||
userInfo: null
|
||||
}),
|
||||
actions: {
|
||||
setUserInfo(info) {
|
||||
this.userInfo = info;
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 📱 小程序问题
|
||||
|
||||
### Q: 小程序真机调试问题?
|
||||
**A:** 常见解决方案:
|
||||
|
||||
1. **网络请求问题**
|
||||
```javascript
|
||||
// 确保域名在小程序后台配置
|
||||
wx.request({
|
||||
url: 'https://api.jiebanke.com/api/v1/users',
|
||||
method: 'GET',
|
||||
success: (res) => {
|
||||
console.log(res.data);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
2. **权限问题**
|
||||
```json
|
||||
// app.json
|
||||
{
|
||||
"permission": {
|
||||
"scope.userLocation": {
|
||||
"desc": "你的位置信息将用于小程序位置接口的效果展示"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Q: 小程序分包加载问题?
|
||||
**A:** 配置分包策略:
|
||||
|
||||
```json
|
||||
// app.json
|
||||
{
|
||||
"pages": ["pages/index/index"],
|
||||
"subPackages": [
|
||||
{
|
||||
"root": "pages/travel",
|
||||
"pages": ["list/list", "detail/detail"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## ⚡ 性能优化问题
|
||||
|
||||
### Q: 页面加载慢怎么优化?
|
||||
**A:** 常见优化策略:
|
||||
|
||||
1. **代码分割**
|
||||
```javascript
|
||||
// 路由懒加载
|
||||
const UserProfile = () => import('./components/UserProfile.vue');
|
||||
```
|
||||
|
||||
2. **图片优化**
|
||||
```html
|
||||
<!-- 使用WebP格式 -->
|
||||
<img src="image.webp" alt="description" loading="lazy">
|
||||
```
|
||||
|
||||
3. **缓存策略**
|
||||
```javascript
|
||||
// 设置HTTP缓存
|
||||
app.use(express.static('public', {
|
||||
maxAge: '1d'
|
||||
}));
|
||||
```
|
||||
|
||||
### Q: 数据库查询慢如何优化?
|
||||
**A:** 优化建议:
|
||||
|
||||
1. **使用索引**
|
||||
2. **避免N+1查询**
|
||||
3. **使用连接查询替代子查询**
|
||||
4. **分页查询大数据集**
|
||||
|
||||
## 📞 获取帮助
|
||||
|
||||
如果以上FAQ没有解决您的问题,可以通过以下方式获取帮助:
|
||||
|
||||
### 技术支持
|
||||
- **GitHub Issues**: [提交问题](https://github.com/jiebanke/jiebanke/issues)
|
||||
- **开发者邮箱**: dev@jiebanke.com
|
||||
- **技术QQ群**: 123456789
|
||||
|
||||
### 文档资源
|
||||
- **开发指南**: [docs/开发指南.md](开发指南.md)
|
||||
- **API文档**: [docs/API接口文档.md](API接口文档.md)
|
||||
- **部署指南**: [docs/部署指南.md](部署指南.md)
|
||||
|
||||
### 社区资源
|
||||
- **官方论坛**: https://forum.jiebanke.com
|
||||
- **技术博客**: https://blog.jiebanke.com
|
||||
- **视频教程**: https://video.jiebanke.com
|
||||
|
||||
---
|
||||
|
||||
*本文档持续更新中,如有新问题请及时反馈。*
|
||||
|
||||
*最后更新:2024年1月*
|
||||
1022
docs/开发指南.md
1022
docs/开发指南.md
File diff suppressed because it is too large
Load Diff
@@ -1,862 +0,0 @@
|
||||
# 解班客项目开发规范和最佳实践
|
||||
|
||||
## 📋 文档概述
|
||||
|
||||
本文档制定了解班客项目的开发规范、编码标准和最佳实践,旨在提高代码质量、团队协作效率和项目可维护性。
|
||||
|
||||
### 文档目标
|
||||
- 建立统一的代码规范和编码标准
|
||||
- 规范开发流程和团队协作方式
|
||||
- 提高代码质量和可维护性
|
||||
- 确保项目的长期稳定发展
|
||||
|
||||
## 🎯 开发原则
|
||||
|
||||
### 核心原则
|
||||
1. **可读性优先**:代码应该易于理解和维护
|
||||
2. **一致性**:遵循统一的编码风格和命名规范
|
||||
3. **简洁性**:避免过度设计,保持代码简洁
|
||||
4. **可测试性**:编写易于测试的代码
|
||||
5. **安全性**:始终考虑安全因素
|
||||
6. **性能意识**:在保证功能的前提下优化性能
|
||||
|
||||
### SOLID原则
|
||||
- **S** - 单一职责原则(Single Responsibility Principle)
|
||||
- **O** - 开闭原则(Open/Closed Principle)
|
||||
- **L** - 里氏替换原则(Liskov Substitution Principle)
|
||||
- **I** - 接口隔离原则(Interface Segregation Principle)
|
||||
- **D** - 依赖倒置原则(Dependency Inversion Principle)
|
||||
|
||||
## 📁 项目结构规范
|
||||
|
||||
### 后端项目结构
|
||||
```
|
||||
backend/
|
||||
├── src/
|
||||
│ ├── controllers/ # 控制器层
|
||||
│ │ ├── admin/ # 管理员控制器
|
||||
│ │ └── user/ # 用户控制器
|
||||
│ ├── models/ # 数据模型层
|
||||
│ ├── routes/ # 路由层
|
||||
│ │ ├── admin/ # 管理员路由
|
||||
│ │ └── user/ # 用户路由
|
||||
│ ├── middleware/ # 中间件
|
||||
│ ├── services/ # 业务逻辑层
|
||||
│ ├── utils/ # 工具函数
|
||||
│ ├── config/ # 配置文件
|
||||
│ └── validators/ # 数据验证
|
||||
├── tests/ # 测试文件
|
||||
│ ├── unit/ # 单元测试
|
||||
│ ├── integration/ # 集成测试
|
||||
│ └── fixtures/ # 测试数据
|
||||
├── docs/ # API文档
|
||||
├── scripts/ # 脚本文件
|
||||
└── package.json
|
||||
```
|
||||
|
||||
### 前端项目结构
|
||||
```
|
||||
frontend/
|
||||
├── src/
|
||||
│ ├── components/ # 公共组件
|
||||
│ │ ├── common/ # 通用组件
|
||||
│ │ └── business/ # 业务组件
|
||||
│ ├── views/ # 页面组件
|
||||
│ │ ├── admin/ # 管理员页面
|
||||
│ │ └── user/ # 用户页面
|
||||
│ ├── stores/ # Pinia状态管理
|
||||
│ ├── composables/ # 组合式函数
|
||||
│ ├── utils/ # 工具函数
|
||||
│ ├── api/ # API接口
|
||||
│ ├── router/ # 路由配置
|
||||
│ ├── assets/ # 静态资源
|
||||
│ └── styles/ # 样式文件
|
||||
├── public/ # 公共资源
|
||||
├── tests/ # 测试文件
|
||||
└── package.json
|
||||
```
|
||||
frontend/
|
||||
├── src/
|
||||
│ ├── components/ # 公共组件
|
||||
│ │ ├── common/ # 通用组件
|
||||
│ │ └── business/ # 业务组件
|
||||
│ ├── views/ # 页面视图
|
||||
│ │ ├── user/ # 用户相关页面
|
||||
│ │ ├── animal/ # 动物相关页面
|
||||
│ │ └── admin/ # 管理页面
|
||||
│ ├── stores/ # 状态管理
|
||||
│ ├── router/ # 路由配置
|
||||
│ ├── utils/ # 工具函数
|
||||
│ ├── api/ # API接口
|
||||
│ ├── assets/ # 静态资源
|
||||
│ │ ├── images/ # 图片资源
|
||||
│ │ ├── styles/ # 样式文件
|
||||
│ │ └── icons/ # 图标资源
|
||||
│ └── composables/ # 组合式函数
|
||||
├── public/ # 公共文件
|
||||
├── tests/ # 测试文件
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## 🔤 命名规范
|
||||
|
||||
### 文件和目录命名
|
||||
- **文件名**: 使用小写字母和连字符 (`kebab-case`)
|
||||
```
|
||||
✅ user-management.js
|
||||
✅ animal-list.vue
|
||||
❌ UserManagement.js
|
||||
❌ animalList.vue
|
||||
```
|
||||
|
||||
- **目录名**: 使用小写字母和连字符
|
||||
```
|
||||
✅ user-management/
|
||||
✅ api-docs/
|
||||
❌ UserManagement/
|
||||
❌ apiDocs/
|
||||
```
|
||||
|
||||
### 变量和函数命名
|
||||
|
||||
#### JavaScript/Node.js
|
||||
- **变量**: 使用驼峰命名法 (`camelCase`)
|
||||
- **常量**: 使用大写字母和下划线 (`UPPER_SNAKE_CASE`)
|
||||
- **函数**: 使用驼峰命名法,动词开头
|
||||
- **类**: 使用帕斯卡命名法 (`PascalCase`)
|
||||
|
||||
```javascript
|
||||
// ✅ 正确示例
|
||||
const userName = 'john';
|
||||
const MAX_RETRY_COUNT = 3;
|
||||
const API_BASE_URL = 'https://api.example.com';
|
||||
|
||||
function getUserById(id) { }
|
||||
function createAnimalRecord(data) { }
|
||||
|
||||
class UserService { }
|
||||
class AnimalController { }
|
||||
|
||||
// ❌ 错误示例
|
||||
const user_name = 'john';
|
||||
const maxretrycount = 3;
|
||||
function GetUserById(id) { }
|
||||
class userService { }
|
||||
```
|
||||
|
||||
#### Vue.js组件
|
||||
- **组件名**: 使用帕斯卡命名法
|
||||
- **Props**: 使用驼峰命名法
|
||||
- **事件**: 使用kebab-case
|
||||
|
||||
```vue
|
||||
<!-- ✅ 正确示例 -->
|
||||
<template>
|
||||
<UserProfile
|
||||
:user-data="userData"
|
||||
@user-updated="handleUserUpdate"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UserProfile',
|
||||
props: {
|
||||
userData: Object,
|
||||
isEditable: Boolean
|
||||
},
|
||||
emits: ['user-updated', 'profile-changed']
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### 数据库命名
|
||||
- **表名**: 使用复数形式,下划线分隔
|
||||
- **字段名**: 使用下划线分隔
|
||||
- **索引名**: 使用 `idx_` 前缀
|
||||
- **外键名**: 使用 `fk_` 前缀
|
||||
|
||||
```sql
|
||||
-- ✅ 正确示例
|
||||
CREATE TABLE users (
|
||||
id INT PRIMARY KEY,
|
||||
user_name VARCHAR(50),
|
||||
email_address VARCHAR(100),
|
||||
created_at TIMESTAMP,
|
||||
updated_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_users_email ON users(email_address);
|
||||
ALTER TABLE adoptions ADD CONSTRAINT fk_adoptions_user_id
|
||||
FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
```
|
||||
|
||||
## 💻 代码风格规范
|
||||
|
||||
### JavaScript/Node.js代码规范
|
||||
|
||||
#### 基本格式
|
||||
```javascript
|
||||
// ✅ 使用2个空格缩进
|
||||
if (condition) {
|
||||
doSomething();
|
||||
}
|
||||
|
||||
// ✅ 使用单引号
|
||||
const message = 'Hello World';
|
||||
|
||||
// ✅ 对象和数组的格式
|
||||
const user = {
|
||||
name: 'John',
|
||||
age: 30,
|
||||
email: 'john@example.com'
|
||||
};
|
||||
|
||||
const animals = [
|
||||
'dog',
|
||||
'cat',
|
||||
'bird'
|
||||
];
|
||||
|
||||
// ✅ 函数声明
|
||||
function calculateAge(birthDate) {
|
||||
const today = new Date();
|
||||
const birth = new Date(birthDate);
|
||||
return today.getFullYear() - birth.getFullYear();
|
||||
}
|
||||
|
||||
// ✅ 箭头函数
|
||||
const getFullName = (firstName, lastName) => `${firstName} ${lastName}`;
|
||||
```
|
||||
|
||||
#### 注释规范
|
||||
```javascript
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param {number} userId - 用户ID
|
||||
* @param {Object} options - 查询选项
|
||||
* @param {boolean} options.includeProfile - 是否包含个人资料
|
||||
* @returns {Promise<Object>} 用户信息对象
|
||||
* @throws {Error} 当用户不存在时抛出错误
|
||||
*/
|
||||
async function getUserInfo(userId, options = {}) {
|
||||
// 验证用户ID
|
||||
if (!userId || typeof userId !== 'number') {
|
||||
throw new Error('Invalid user ID');
|
||||
}
|
||||
|
||||
// 查询用户基本信息
|
||||
const user = await User.findById(userId);
|
||||
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
|
||||
// 如果需要包含个人资料
|
||||
if (options.includeProfile) {
|
||||
user.profile = await UserProfile.findByUserId(userId);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误处理
|
||||
```javascript
|
||||
// ✅ 使用try-catch处理异步错误
|
||||
async function createUser(userData) {
|
||||
try {
|
||||
// 验证输入数据
|
||||
const validatedData = validateUserData(userData);
|
||||
|
||||
// 创建用户
|
||||
const user = await User.create(validatedData);
|
||||
|
||||
// 记录日志
|
||||
logger.info('User created successfully', { userId: user.id });
|
||||
|
||||
return user;
|
||||
} catch (error) {
|
||||
// 记录错误日志
|
||||
logger.error('Failed to create user', { error: error.message, userData });
|
||||
|
||||
// 重新抛出错误
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 使用自定义错误类
|
||||
class ValidationError extends Error {
|
||||
constructor(message, field) {
|
||||
super(message);
|
||||
this.name = 'ValidationError';
|
||||
this.field = field;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Vue.js代码规范
|
||||
|
||||
#### 组件结构
|
||||
```vue
|
||||
<template>
|
||||
<!-- 模板内容 -->
|
||||
<div class="user-profile">
|
||||
<div class="user-profile__header">
|
||||
<h2 class="user-profile__title">{{ user.name }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="user-profile__content">
|
||||
<UserAvatar
|
||||
:src="user.avatar"
|
||||
:alt="user.name"
|
||||
@click="handleAvatarClick"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { useUserStore } from '@/stores/user';
|
||||
import UserAvatar from '@/components/common/UserAvatar.vue';
|
||||
|
||||
export default {
|
||||
name: 'UserProfile',
|
||||
|
||||
components: {
|
||||
UserAvatar
|
||||
},
|
||||
|
||||
props: {
|
||||
userId: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
editable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['profile-updated', 'avatar-changed'],
|
||||
|
||||
setup(props, { emit }) {
|
||||
// 响应式数据
|
||||
const user = ref(null);
|
||||
const loading = ref(false);
|
||||
|
||||
// 计算属性
|
||||
const displayName = computed(() => {
|
||||
return user.value ? user.value.name : 'Unknown User';
|
||||
});
|
||||
|
||||
// 方法
|
||||
const loadUser = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
user.value = await userStore.fetchUser(props.userId);
|
||||
} catch (error) {
|
||||
console.error('Failed to load user:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleAvatarClick = () => {
|
||||
if (props.editable) {
|
||||
emit('avatar-changed');
|
||||
}
|
||||
};
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
loadUser();
|
||||
});
|
||||
|
||||
// 返回模板需要的数据和方法
|
||||
return {
|
||||
user,
|
||||
loading,
|
||||
displayName,
|
||||
handleAvatarClick
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.user-profile {
|
||||
padding: 20px;
|
||||
|
||||
&__header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
#### CSS/SCSS规范
|
||||
```scss
|
||||
// ✅ 使用BEM命名规范
|
||||
.animal-card {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
&__status {
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
|
||||
&--available {
|
||||
background-color: #e8f5e8;
|
||||
color: #2d8f2d;
|
||||
}
|
||||
|
||||
&--adopted {
|
||||
background-color: #fff3cd;
|
||||
color: #856404;
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 使用CSS变量
|
||||
:root {
|
||||
--primary-color: #007bff;
|
||||
--success-color: #28a745;
|
||||
--warning-color: #ffc107;
|
||||
--danger-color: #dc3545;
|
||||
--font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 测试规范
|
||||
|
||||
### 测试文件命名
|
||||
- 单元测试: `*.test.js` 或 `*.spec.js`
|
||||
- 集成测试: `*.integration.test.js`
|
||||
- E2E测试: `*.e2e.test.js`
|
||||
|
||||
### 测试结构
|
||||
```javascript
|
||||
// ✅ 测试文件示例
|
||||
describe('UserService', () => {
|
||||
let userService;
|
||||
let mockDatabase;
|
||||
|
||||
beforeEach(() => {
|
||||
mockDatabase = createMockDatabase();
|
||||
userService = new UserService(mockDatabase);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockDatabase.reset();
|
||||
});
|
||||
|
||||
describe('createUser', () => {
|
||||
it('should create user with valid data', async () => {
|
||||
// Arrange
|
||||
const userData = {
|
||||
name: 'John Doe',
|
||||
email: 'john@example.com'
|
||||
};
|
||||
|
||||
// Act
|
||||
const result = await userService.createUser(userData);
|
||||
|
||||
// Assert
|
||||
expect(result).toBeDefined();
|
||||
expect(result.id).toBeTruthy();
|
||||
expect(result.name).toBe(userData.name);
|
||||
expect(result.email).toBe(userData.email);
|
||||
});
|
||||
|
||||
it('should throw error with invalid email', async () => {
|
||||
// Arrange
|
||||
const userData = {
|
||||
name: 'John Doe',
|
||||
email: 'invalid-email'
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
await expect(userService.createUser(userData))
|
||||
.rejects
|
||||
.toThrow('Invalid email format');
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 测试覆盖率要求
|
||||
- **单元测试覆盖率**: ≥ 80%
|
||||
- **集成测试覆盖率**: ≥ 60%
|
||||
- **关键业务逻辑**: 100%
|
||||
|
||||
## 📝 文档规范
|
||||
|
||||
### API文档
|
||||
使用OpenAPI 3.0规范编写API文档:
|
||||
|
||||
```yaml
|
||||
# ✅ API文档示例
|
||||
paths:
|
||||
/api/v1/users/{id}:
|
||||
get:
|
||||
summary: 获取用户信息
|
||||
description: 根据用户ID获取用户详细信息
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
description: 用户ID
|
||||
responses:
|
||||
'200':
|
||||
description: 成功获取用户信息
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
'404':
|
||||
description: 用户不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
```
|
||||
|
||||
### 代码注释
|
||||
```javascript
|
||||
/**
|
||||
* 动物认领服务类
|
||||
* 处理动物认领相关的业务逻辑
|
||||
*/
|
||||
class AdoptionService {
|
||||
/**
|
||||
* 创建认领申请
|
||||
* @param {Object} adoptionData - 认领申请数据
|
||||
* @param {number} adoptionData.userId - 申请人ID
|
||||
* @param {number} adoptionData.animalId - 动物ID
|
||||
* @param {string} adoptionData.reason - 认领原因
|
||||
* @param {Object} adoptionData.contact - 联系方式
|
||||
* @returns {Promise<Object>} 认领申请对象
|
||||
* @throws {ValidationError} 当数据验证失败时
|
||||
* @throws {BusinessError} 当业务规则验证失败时
|
||||
*
|
||||
* @example
|
||||
* const adoption = await adoptionService.createAdoption({
|
||||
* userId: 123,
|
||||
* animalId: 456,
|
||||
* reason: '我想给这只小狗一个温暖的家',
|
||||
* contact: { phone: '13800138000', address: '北京市朝阳区' }
|
||||
* });
|
||||
*/
|
||||
async createAdoption(adoptionData) {
|
||||
// 实现代码...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔒 安全规范
|
||||
|
||||
### 输入验证
|
||||
```javascript
|
||||
// ✅ 使用joi进行数据验证
|
||||
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)/).required(),
|
||||
phone: Joi.string().pattern(/^1[3-9]\d{9}$/).optional()
|
||||
});
|
||||
|
||||
// 验证用户输入
|
||||
const { error, value } = userSchema.validate(userData);
|
||||
if (error) {
|
||||
throw new ValidationError(error.details[0].message);
|
||||
}
|
||||
```
|
||||
|
||||
### SQL注入防护
|
||||
```javascript
|
||||
// ✅ 使用参数化查询
|
||||
const getUserById = async (id) => {
|
||||
const query = 'SELECT * FROM users WHERE id = ?';
|
||||
const result = await db.query(query, [id]);
|
||||
return result[0];
|
||||
};
|
||||
|
||||
// ❌ 避免字符串拼接
|
||||
const getUserById = async (id) => {
|
||||
const query = `SELECT * FROM users WHERE id = ${id}`; // 危险!
|
||||
const result = await db.query(query);
|
||||
return result[0];
|
||||
};
|
||||
```
|
||||
|
||||
### 敏感信息处理
|
||||
```javascript
|
||||
// ✅ 密码加密
|
||||
const bcrypt = require('bcrypt');
|
||||
|
||||
const hashPassword = async (password) => {
|
||||
const saltRounds = 12;
|
||||
return await bcrypt.hash(password, saltRounds);
|
||||
};
|
||||
|
||||
// ✅ 敏感信息过滤
|
||||
const sanitizeUser = (user) => {
|
||||
const { password, salt, ...safeUser } = user;
|
||||
return safeUser;
|
||||
};
|
||||
```
|
||||
|
||||
## 🚀 性能优化规范
|
||||
|
||||
### 数据库查询优化
|
||||
```javascript
|
||||
// ✅ 使用索引和限制查询
|
||||
const getAnimals = async (filters, pagination) => {
|
||||
const { page = 1, limit = 20 } = pagination;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
const query = `
|
||||
SELECT a.*, u.name as owner_name
|
||||
FROM animals a
|
||||
LEFT JOIN users u ON a.owner_id = u.id
|
||||
WHERE a.status = ?
|
||||
ORDER BY a.created_at DESC
|
||||
LIMIT ? OFFSET ?
|
||||
`;
|
||||
|
||||
return await db.query(query, [filters.status, limit, offset]);
|
||||
};
|
||||
|
||||
// ✅ 使用缓存
|
||||
const Redis = require('redis');
|
||||
const redis = Redis.createClient();
|
||||
|
||||
const getCachedUser = async (userId) => {
|
||||
const cacheKey = `user:${userId}`;
|
||||
|
||||
// 尝试从缓存获取
|
||||
let user = await redis.get(cacheKey);
|
||||
if (user) {
|
||||
return JSON.parse(user);
|
||||
}
|
||||
|
||||
// 从数据库获取
|
||||
user = await User.findById(userId);
|
||||
|
||||
// 存入缓存,过期时间1小时
|
||||
await redis.setex(cacheKey, 3600, JSON.stringify(user));
|
||||
|
||||
return user;
|
||||
};
|
||||
```
|
||||
|
||||
### 前端性能优化
|
||||
```vue
|
||||
<template>
|
||||
<!-- ✅ 使用v-show代替v-if进行频繁切换 -->
|
||||
<div v-show="isVisible" class="content">
|
||||
<!-- ✅ 使用key优化列表渲染 -->
|
||||
<div
|
||||
v-for="animal in animals"
|
||||
:key="animal.id"
|
||||
class="animal-item"
|
||||
>
|
||||
{{ animal.name }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, computed, watchEffect } from 'vue';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
// ✅ 使用computed缓存计算结果
|
||||
const expensiveValue = computed(() => {
|
||||
return animals.value.filter(animal => animal.status === 'available')
|
||||
.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
|
||||
});
|
||||
|
||||
// ✅ 使用防抖处理搜索
|
||||
const searchTerm = ref('');
|
||||
const debouncedSearch = debounce((term) => {
|
||||
performSearch(term);
|
||||
}, 300);
|
||||
|
||||
watchEffect(() => {
|
||||
debouncedSearch(searchTerm.value);
|
||||
});
|
||||
|
||||
return {
|
||||
expensiveValue,
|
||||
searchTerm
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
## 📋 Git工作流规范
|
||||
|
||||
### 分支命名
|
||||
- **主分支**: `main`
|
||||
- **开发分支**: `develop`
|
||||
- **功能分支**: `feature/功能名称`
|
||||
- **修复分支**: `fix/问题描述`
|
||||
- **发布分支**: `release/版本号`
|
||||
|
||||
### 提交信息规范
|
||||
使用Conventional Commits规范:
|
||||
|
||||
```bash
|
||||
# ✅ 正确的提交信息
|
||||
feat: 添加用户认证功能
|
||||
fix: 修复动物列表分页问题
|
||||
docs: 更新API文档
|
||||
style: 统一代码格式
|
||||
refactor: 重构用户服务层
|
||||
test: 添加用户注册测试用例
|
||||
chore: 更新依赖包版本
|
||||
|
||||
# 详细提交信息示例
|
||||
feat: 添加动物认领申请功能
|
||||
|
||||
- 实现认领申请表单
|
||||
- 添加申请状态跟踪
|
||||
- 集成邮件通知功能
|
||||
- 添加相关测试用例
|
||||
|
||||
Closes #123
|
||||
```
|
||||
|
||||
### 代码审查清单
|
||||
- [ ] 代码符合项目规范
|
||||
- [ ] 功能实现正确
|
||||
- [ ] 测试用例充分
|
||||
- [ ] 文档更新完整
|
||||
- [ ] 性能影响评估
|
||||
- [ ] 安全风险评估
|
||||
- [ ] 向后兼容性检查
|
||||
|
||||
## 🛠️ 开发工具配置
|
||||
|
||||
### ESLint配置
|
||||
```json
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"@vue/eslint-config-prettier"
|
||||
],
|
||||
"rules": {
|
||||
"indent": ["error", 2],
|
||||
"quotes": ["error", "single"],
|
||||
"semi": ["error", "always"],
|
||||
"no-console": "warn",
|
||||
"no-debugger": "error",
|
||||
"no-unused-vars": "error"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Prettier配置
|
||||
```json
|
||||
{
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5",
|
||||
"printWidth": 80,
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
```
|
||||
|
||||
### VS Code配置
|
||||
```json
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"emmet.includeLanguages": {
|
||||
"vue": "html"
|
||||
},
|
||||
"files.associations": {
|
||||
"*.vue": "vue"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📚 学习资源
|
||||
|
||||
### 官方文档
|
||||
- [Vue.js 官方文档](https://vuejs.org/)
|
||||
- [Node.js 官方文档](https://nodejs.org/)
|
||||
- [Express.js 官方文档](https://expressjs.com/)
|
||||
- [MySQL 官方文档](https://dev.mysql.com/doc/)
|
||||
|
||||
### 最佳实践
|
||||
- [JavaScript 最佳实践](https://github.com/airbnb/javascript)
|
||||
- [Vue.js 风格指南](https://vuejs.org/style-guide/)
|
||||
- [Node.js 最佳实践](https://github.com/goldbergyoni/nodebestpractices)
|
||||
|
||||
### 工具和库
|
||||
- [ESLint](https://eslint.org/) - 代码检查
|
||||
- [Prettier](https://prettier.io/) - 代码格式化
|
||||
- [Jest](https://jestjs.io/) - 测试框架
|
||||
- [Joi](https://joi.dev/) - 数据验证
|
||||
|
||||
## 🔄 规范更新
|
||||
|
||||
本规范会根据项目发展和团队反馈持续更新。如有建议或问题,请通过以下方式反馈:
|
||||
|
||||
1. 创建GitHub Issue
|
||||
2. 提交Pull Request
|
||||
3. 团队会议讨论
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.0.0
|
||||
**最后更新**: 2024年1月15日
|
||||
**下次审查**: 2024年4月15日
|
||||
2526
docs/性能优化文档.md
2526
docs/性能优化文档.md
File diff suppressed because it is too large
Load Diff
@@ -1,423 +0,0 @@
|
||||
# 支付系统API文档
|
||||
|
||||
## 概述
|
||||
|
||||
支付系统提供完整的支付流程管理,包括支付订单创建、状态查询、退款处理等功能。支持微信支付、支付宝支付和余额支付三种支付方式。
|
||||
|
||||
## 基础信息
|
||||
|
||||
- **基础URL**: `/api/v1/payments`
|
||||
- **认证方式**: Bearer Token
|
||||
- **数据格式**: JSON
|
||||
|
||||
## 数据模型
|
||||
|
||||
### 支付订单 (Payment)
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"payment_no": "PAY202401010001",
|
||||
"order_id": 1,
|
||||
"user_id": 1,
|
||||
"amount": 299.00,
|
||||
"paid_amount": 299.00,
|
||||
"payment_method": "wechat",
|
||||
"status": "paid",
|
||||
"transaction_id": "wx_transaction_123",
|
||||
"paid_at": "2024-01-01T10:00:00Z",
|
||||
"created_at": "2024-01-01T09:00:00Z",
|
||||
"updated_at": "2024-01-01T10:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 退款记录 (Refund)
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"refund_no": "REF202401010001",
|
||||
"payment_id": 1,
|
||||
"user_id": 1,
|
||||
"refund_amount": 100.00,
|
||||
"refund_reason": "用户申请退款",
|
||||
"status": "completed",
|
||||
"processed_by": 2,
|
||||
"process_remark": "同意退款",
|
||||
"processed_at": "2024-01-01T11:00:00Z",
|
||||
"refunded_at": "2024-01-01T11:30:00Z",
|
||||
"created_at": "2024-01-01T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## API接口
|
||||
|
||||
### 1. 创建支付订单
|
||||
|
||||
**接口**: `POST /api/v1/payments`
|
||||
|
||||
**描述**: 为订单创建支付订单
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"order_id": 1,
|
||||
"amount": 299.00,
|
||||
"payment_method": "wechat",
|
||||
"return_url": "https://example.com/success"
|
||||
}
|
||||
```
|
||||
|
||||
**参数说明**:
|
||||
- `order_id` (必填): 订单ID
|
||||
- `amount` (必填): 支付金额
|
||||
- `payment_method` (必填): 支付方式 (wechat/alipay/balance)
|
||||
- `return_url` (可选): 支付成功回调地址
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "支付订单创建成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"payment_no": "PAY202401010001",
|
||||
"order_id": 1,
|
||||
"amount": 299.00,
|
||||
"payment_method": "wechat",
|
||||
"status": "pending",
|
||||
"payment_params": {
|
||||
"prepay_id": "wx_prepay_123",
|
||||
"code_url": "weixin://wxpay/bizpayurl?pr=abc123"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 获取支付订单详情
|
||||
|
||||
**接口**: `GET /api/v1/payments/{paymentId}`
|
||||
|
||||
**描述**: 获取指定支付订单的详细信息
|
||||
|
||||
**路径参数**:
|
||||
- `paymentId`: 支付订单ID
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"id": 1,
|
||||
"payment_no": "PAY202401010001",
|
||||
"order_id": 1,
|
||||
"user_id": 1,
|
||||
"amount": 299.00,
|
||||
"paid_amount": 299.00,
|
||||
"payment_method": "wechat",
|
||||
"status": "paid",
|
||||
"transaction_id": "wx_transaction_123",
|
||||
"paid_at": "2024-01-01T10:00:00Z",
|
||||
"order_no": "ORD202401010001",
|
||||
"username": "张三",
|
||||
"phone": "13800138000"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 查询支付状态
|
||||
|
||||
**接口**: `GET /api/v1/payments/query/{paymentNo}`
|
||||
|
||||
**描述**: 根据支付订单号查询支付状态
|
||||
|
||||
**路径参数**:
|
||||
- `paymentNo`: 支付订单号
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"payment_no": "PAY202401010001",
|
||||
"status": "paid",
|
||||
"amount": 299.00,
|
||||
"paid_at": "2024-01-01T10:00:00Z",
|
||||
"transaction_id": "wx_transaction_123"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 支付回调接口
|
||||
|
||||
#### 微信支付回调
|
||||
|
||||
**接口**: `POST /api/v1/payments/callback/wechat`
|
||||
|
||||
**描述**: 微信支付异步通知接口
|
||||
|
||||
**请求格式**: XML
|
||||
|
||||
**响应格式**: XML
|
||||
|
||||
#### 支付宝回调
|
||||
|
||||
**接口**: `POST /api/v1/payments/callback/alipay`
|
||||
|
||||
**描述**: 支付宝异步通知接口
|
||||
|
||||
**请求格式**: Form Data
|
||||
|
||||
**响应格式**: 文本 (success/fail)
|
||||
|
||||
### 5. 申请退款
|
||||
|
||||
**接口**: `POST /api/v1/payments/{paymentId}/refund`
|
||||
|
||||
**描述**: 为已支付的订单申请退款
|
||||
|
||||
**路径参数**:
|
||||
- `paymentId`: 支付订单ID
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"refund_amount": 100.00,
|
||||
"refund_reason": "商品质量问题"
|
||||
}
|
||||
```
|
||||
|
||||
**参数说明**:
|
||||
- `refund_amount` (必填): 退款金额
|
||||
- `refund_reason` (必填): 退款原因
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "退款申请提交成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"refund_no": "REF202401010001",
|
||||
"payment_id": 1,
|
||||
"refund_amount": 100.00,
|
||||
"refund_reason": "商品质量问题",
|
||||
"status": "pending",
|
||||
"created_at": "2024-01-01T10:30:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 获取退款详情
|
||||
|
||||
**接口**: `GET /api/v1/payments/refunds/{refundId}`
|
||||
|
||||
**描述**: 获取退款记录详情
|
||||
|
||||
**路径参数**:
|
||||
- `refundId`: 退款ID
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"id": 1,
|
||||
"refund_no": "REF202401010001",
|
||||
"payment_id": 1,
|
||||
"refund_amount": 100.00,
|
||||
"refund_reason": "商品质量问题",
|
||||
"status": "completed",
|
||||
"processed_by": 2,
|
||||
"process_remark": "同意退款",
|
||||
"processed_at": "2024-01-01T11:00:00Z",
|
||||
"refunded_at": "2024-01-01T11:30:00Z",
|
||||
"payment_no": "PAY202401010001",
|
||||
"username": "张三",
|
||||
"processed_by_name": "管理员"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7. 处理退款(管理员)
|
||||
|
||||
**接口**: `PUT /api/v1/payments/refunds/{refundId}/process`
|
||||
|
||||
**描述**: 管理员处理退款申请
|
||||
|
||||
**权限**: 管理员
|
||||
|
||||
**路径参数**:
|
||||
- `refundId`: 退款ID
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"status": "approved",
|
||||
"process_remark": "同意退款申请"
|
||||
}
|
||||
```
|
||||
|
||||
**参数说明**:
|
||||
- `status` (必填): 退款状态 (approved/rejected/completed)
|
||||
- `process_remark` (可选): 处理备注
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "退款处理成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"refund_no": "REF202401010001",
|
||||
"status": "approved",
|
||||
"processed_by": 2,
|
||||
"process_remark": "同意退款申请",
|
||||
"processed_at": "2024-01-01T11:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8. 获取支付统计信息(管理员)
|
||||
|
||||
**接口**: `GET /api/v1/payments/statistics`
|
||||
|
||||
**描述**: 获取支付相关的统计信息
|
||||
|
||||
**权限**: 管理员
|
||||
|
||||
**查询参数**:
|
||||
- `start_date` (可选): 开始日期 (YYYY-MM-DD)
|
||||
- `end_date` (可选): 结束日期 (YYYY-MM-DD)
|
||||
- `payment_method` (可选): 支付方式
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"total_count": 100,
|
||||
"total_amount": 29900.00,
|
||||
"success_count": 85,
|
||||
"success_amount": 25415.00,
|
||||
"refund_count": 5,
|
||||
"refund_amount": 1500.00,
|
||||
"method_stats": [
|
||||
{
|
||||
"payment_method": "wechat",
|
||||
"count": 50,
|
||||
"amount": 15000.00
|
||||
},
|
||||
{
|
||||
"payment_method": "alipay",
|
||||
"count": 35,
|
||||
"amount": 10415.00
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 状态说明
|
||||
|
||||
### 支付状态 (Payment Status)
|
||||
|
||||
- `pending`: 待支付
|
||||
- `paid`: 已支付
|
||||
- `failed`: 支付失败
|
||||
- `refunded`: 已退款
|
||||
- `cancelled`: 已取消
|
||||
|
||||
### 退款状态 (Refund Status)
|
||||
|
||||
- `pending`: 待处理
|
||||
- `approved`: 已同意
|
||||
- `rejected`: 已拒绝
|
||||
- `completed`: 已完成
|
||||
|
||||
## 支付方式
|
||||
|
||||
- `wechat`: 微信支付
|
||||
- `alipay`: 支付宝支付
|
||||
- `balance`: 余额支付
|
||||
|
||||
## 错误码说明
|
||||
|
||||
| 错误码 | 说明 |
|
||||
|--------|------|
|
||||
| 400 | 参数错误 |
|
||||
| 401 | 未授权 |
|
||||
| 403 | 权限不足 |
|
||||
| 404 | 资源不存在 |
|
||||
| 500 | 服务器内部错误 |
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **安全性**: 所有支付相关接口都需要用户认证
|
||||
2. **权限控制**: 用户只能操作自己的支付订单和退款记录
|
||||
3. **金额精度**: 所有金额字段保留两位小数
|
||||
4. **回调验证**: 支付回调需要验证签名确保安全性
|
||||
5. **幂等性**: 支付订单创建支持幂等性,避免重复创建
|
||||
6. **超时处理**: 待支付订单会在24小时后自动取消
|
||||
|
||||
## 集成示例
|
||||
|
||||
### 创建支付订单示例
|
||||
|
||||
```javascript
|
||||
// 创建支付订单
|
||||
const createPayment = async (orderData) => {
|
||||
try {
|
||||
const response = await fetch('/api/v1/payments', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
order_id: orderData.orderId,
|
||||
amount: orderData.amount,
|
||||
payment_method: 'wechat',
|
||||
return_url: 'https://example.com/success'
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
// 跳转到支付页面或调用支付SDK
|
||||
handlePayment(result.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('创建支付订单失败:', error);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 查询支付状态示例
|
||||
|
||||
```javascript
|
||||
// 轮询查询支付状态
|
||||
const checkPaymentStatus = async (paymentNo) => {
|
||||
try {
|
||||
const response = await fetch(`/api/v1/payments/query/${paymentNo}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
const status = result.data.status;
|
||||
if (status === 'paid') {
|
||||
// 支付成功处理
|
||||
handlePaymentSuccess();
|
||||
} else if (status === 'failed') {
|
||||
// 支付失败处理
|
||||
handlePaymentFailed();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查询支付状态失败:', error);
|
||||
}
|
||||
};
|
||||
```
|
||||
219
docs/数据库设计文档.md
219
docs/数据库设计文档.md
@@ -1,52 +1,138 @@
|
||||
# 🗄️ 结伴客数据库设计文档
|
||||
# 解班客数据库设计文档
|
||||
|
||||
## 📋 数据库概述
|
||||
## 1. 概述
|
||||
|
||||
结伴客系统采用MySQL 8.0作为主要数据存储,设计了完整的数据库架构来支持结伴旅行、动物认领、商家服务等核心业务功能。数据库设计遵循第三范式,确保数据一致性和完整性。
|
||||
### 1.1 项目简介
|
||||
解班客是一个综合性的社交旅行平台,融合了结伴旅行、动物认领、商家服务等多种功能。本文档详细描述了支撑整个平台运行的数据库设计方案。
|
||||
|
||||
## 🔧 数据库配置
|
||||
### 1.2 设计原则
|
||||
- **数据一致性**:确保数据的完整性和一致性
|
||||
- **性能优化**:合理设计索引,优化查询性能
|
||||
- **扩展性**:支持业务快速发展和功能扩展
|
||||
- **安全性**:敏感数据加密存储,权限控制
|
||||
- **可维护性**:清晰的表结构和命名规范
|
||||
|
||||
### 环境配置
|
||||
### 1.3 技术选型
|
||||
- **主数据库**:MySQL 8.0
|
||||
- **缓存数据库**:Redis 6.0
|
||||
- **文件存储**:腾讯云COS
|
||||
|
||||
#### 开发环境
|
||||
- **主机**:localhost
|
||||
- **端口**:3306
|
||||
- **数据库名**:jiebandata_dev
|
||||
### 1.4 数据库配置
|
||||
|
||||
本项目使用统一的数据库实例,所有环境共享同一个数据库配置:
|
||||
|
||||
#### 数据库连接信息
|
||||
- **主机地址**:nj-cdb-3pwh2kz1.sql.tencentcdb.com
|
||||
- **端口**:20784
|
||||
- **用户名**:jiebanke
|
||||
- **密码**:aiot741$12346
|
||||
- **数据库名**:jbkdata
|
||||
- **连接池大小**:10
|
||||
- **字符集**:utf8mb4
|
||||
- **排序规则**:utf8mb4_unicode_ci
|
||||
- **时区**:+08:00
|
||||
|
||||
#### 测试环境
|
||||
- **主机**:192.168.0.240
|
||||
- **端口**:3306
|
||||
- **用户名**:root
|
||||
- **密码**:aiot$Aiot123
|
||||
- **数据库名**:jiebandata_test
|
||||
|
||||
#### 生产环境
|
||||
- **主机**:129.211.213.226
|
||||
- **端口**:9527
|
||||
- **用户名**:root
|
||||
- **密码**:aiotAiot123!
|
||||
- **数据库名**:jiebandata
|
||||
|
||||
### 数据库架构
|
||||
|
||||
#### 主从复制架构
|
||||
```mermaid
|
||||
graph LR
|
||||
A[应用服务器] --> B[MySQL主库<br/>写操作]
|
||||
B --> C[MySQL从库1<br/>读操作]
|
||||
B --> D[MySQL从库2<br/>读操作]
|
||||
A --> C
|
||||
A --> D
|
||||
|
||||
E[备份服务器] --> B
|
||||
F[监控系统] --> B
|
||||
F --> C
|
||||
F --> D
|
||||
#### 环境变量配置
|
||||
```bash
|
||||
# 数据库配置
|
||||
DB_HOST=nj-cdb-3pwh2kz1.sql.tencentcdb.com
|
||||
DB_PORT=20784
|
||||
DB_USER=jiebanke
|
||||
DB_PASSWORD=aiot741$12346
|
||||
DB_NAME=jbkdata
|
||||
```
|
||||
|
||||
## 📊 数据库ER图
|
||||
#### 连接配置示例
|
||||
```javascript
|
||||
// Node.js 连接配置
|
||||
const dbConfig = {
|
||||
host: process.env.DB_HOST || 'nj-cdb-3pwh2kz1.sql.tencentcdb.com',
|
||||
port: process.env.DB_PORT || 20784,
|
||||
user: process.env.DB_USER || 'jiebanke',
|
||||
password: process.env.DB_PASSWORD || 'aiot741$12346',
|
||||
database: process.env.DB_NAME || 'jbkdata',
|
||||
connectionLimit: 10,
|
||||
charset: 'utf8mb4',
|
||||
timezone: '+08:00'
|
||||
};
|
||||
```
|
||||
|
||||
## 2. 数据库架构
|
||||
|
||||
### 2.1 整体架构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "应用层"
|
||||
A[小程序App]
|
||||
B[管理后台]
|
||||
C[官方网站]
|
||||
D[后端API]
|
||||
end
|
||||
|
||||
subgraph "数据访问层"
|
||||
E[ORM层 - Sequelize]
|
||||
F[缓存层 - Redis]
|
||||
end
|
||||
|
||||
subgraph "数据存储层"
|
||||
G[MySQL数据库<br/>jbkdata]
|
||||
H[文件存储 - 腾讯云COS]
|
||||
end
|
||||
|
||||
A --> D
|
||||
B --> D
|
||||
C --> D
|
||||
D --> E
|
||||
D --> F
|
||||
E --> G
|
||||
F --> G
|
||||
D --> H
|
||||
```
|
||||
|
||||
### 2.2 数据库连接架构
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "应用服务"
|
||||
A[小程序API]
|
||||
B[管理后台API]
|
||||
C[官网API]
|
||||
end
|
||||
|
||||
subgraph "连接池管理"
|
||||
D[连接池<br/>最大连接数: 10]
|
||||
end
|
||||
|
||||
subgraph "腾讯云数据库"
|
||||
E[MySQL 8.0<br/>nj-cdb-3pwh2kz1.sql.tencentcdb.com:20784<br/>数据库: jbkdata]
|
||||
end
|
||||
|
||||
A --> D
|
||||
B --> D
|
||||
C --> D
|
||||
D --> E
|
||||
## 3. 数据库设计原则
|
||||
|
||||
### 3.1 表设计规范
|
||||
- **命名规范**:使用小写字母和下划线,表名使用复数形式
|
||||
- **主键设计**:统一使用自增整型主键 `id`
|
||||
- **时间字段**:统一使用 `created_at` 和 `updated_at`
|
||||
- **软删除**:使用 `deleted_at` 字段实现软删除
|
||||
- **状态字段**:使用 `status` 字段管理记录状态
|
||||
|
||||
### 3.2 索引设计原则
|
||||
- **主键索引**:每个表必须有主键
|
||||
- **唯一索引**:对唯一性约束字段创建唯一索引
|
||||
- **复合索引**:根据查询场景创建合适的复合索引
|
||||
- **外键索引**:对外键字段创建索引
|
||||
|
||||
### 3.3 数据类型规范
|
||||
- **整型**:使用 `INT` 或 `BIGINT`
|
||||
- **字符串**:使用 `VARCHAR` 或 `TEXT`
|
||||
- **时间**:使用 `TIMESTAMP` 或 `DATETIME`
|
||||
- **枚举**:使用 `ENUM` 或 `TINYINT`
|
||||
- **布尔**:使用 `TINYINT(1)`
|
||||
|
||||
## 4. 数据库ER图
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
@@ -720,12 +806,59 @@ SELECT
|
||||
s.cardinality
|
||||
FROM information_schema.tables t
|
||||
LEFT JOIN information_schema.statistics s ON t.table_name = s.table_name
|
||||
WHERE t.table_schema = 'jiebandata'
|
||||
WHERE t.table_schema = 'jbkdata'
|
||||
AND s.index_name IS NOT NULL
|
||||
AND s.index_name != 'PRIMARY';
|
||||
```
|
||||
|
||||
## 12. 数据库连接和维护
|
||||
|
||||
### 12.1 连接管理
|
||||
```javascript
|
||||
// 数据库连接池配置
|
||||
const mysql = require('mysql2/promise');
|
||||
|
||||
const pool = mysql.createPool({
|
||||
host: 'nj-cdb-3pwh2kz1.sql.tencentcdb.com',
|
||||
port: 20784,
|
||||
user: 'jiebanke',
|
||||
password: 'aiot741$12346',
|
||||
database: 'jbkdata',
|
||||
connectionLimit: 10,
|
||||
charset: 'utf8mb4',
|
||||
timezone: '+08:00',
|
||||
acquireTimeout: 60000,
|
||||
timeout: 60000,
|
||||
reconnect: true
|
||||
});
|
||||
|
||||
module.exports = pool;
|
||||
```
|
||||
|
||||
### 12.2 数据库维护脚本
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 数据库备份脚本
|
||||
DB_HOST="nj-cdb-3pwh2kz1.sql.tencentcdb.com"
|
||||
DB_PORT="20784"
|
||||
DB_USER="jiebanke"
|
||||
DB_PASSWORD="aiot741$12346"
|
||||
DB_NAME="jbkdata"
|
||||
|
||||
# 创建备份
|
||||
mysqldump -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASSWORD $DB_NAME > backup_$(date +%Y%m%d_%H%M%S).sql
|
||||
|
||||
echo "数据库备份完成"
|
||||
```
|
||||
|
||||
### 12.3 监控和告警
|
||||
- **连接数监控**:监控当前连接数,避免超过连接池限制
|
||||
- **慢查询监控**:监控执行时间超过2秒的查询
|
||||
- **磁盘空间监控**:监控数据库磁盘使用情况
|
||||
- **性能指标监控**:QPS、TPS、响应时间等关键指标
|
||||
|
||||
---
|
||||
|
||||
*文档版本:v1.0*
|
||||
*最后更新:2025年1月*
|
||||
*文档版本:v2.0*
|
||||
*最后更新:2025年1月*
|
||||
*数据库实例:腾讯云MySQL - jbkdata*
|
||||
611
docs/整个项目的架构文档.md
Normal file
611
docs/整个项目的架构文档.md
Normal file
@@ -0,0 +1,611 @@
|
||||
# 解班客项目系统架构文档
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
### 1.1 项目简介
|
||||
解班客是一个综合性的社交旅行平台,融合了结伴旅行和动物认领两大核心功能。项目采用现代化的微服务架构,包含微信小程序、管理后台、官方网站和后端服务四个主要模块。
|
||||
|
||||
### 1.2 业务架构
|
||||
```mermaid
|
||||
graph TB
|
||||
A[用户端] --> B[微信小程序]
|
||||
A --> C[官方网站]
|
||||
D[管理端] --> E[管理后台]
|
||||
|
||||
B --> F[后端服务]
|
||||
C --> F
|
||||
E --> F
|
||||
|
||||
F --> G[用户服务]
|
||||
F --> H[活动服务]
|
||||
F --> I[动物认领服务]
|
||||
F --> J[支付服务]
|
||||
F --> K[消息服务]
|
||||
F --> L[文件服务]
|
||||
|
||||
G --> M[数据库集群]
|
||||
H --> M
|
||||
I --> M
|
||||
J --> M
|
||||
K --> M
|
||||
L --> M
|
||||
|
||||
F --> N[缓存集群]
|
||||
F --> O[消息队列]
|
||||
F --> P[对象存储]
|
||||
```
|
||||
|
||||
### 1.3 技术选型原则
|
||||
- **稳定性优先**:选择成熟稳定的技术栈
|
||||
- **性能考虑**:支持高并发和快速响应
|
||||
- **可扩展性**:支持业务快速发展和功能扩展
|
||||
- **开发效率**:提高开发效率和维护便利性
|
||||
- **成本控制**:在满足需求的前提下控制技术成本
|
||||
|
||||
## 2. 整体架构设计
|
||||
|
||||
### 2.1 系统架构图
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "客户端层"
|
||||
A1[微信小程序]
|
||||
A2[管理后台Web]
|
||||
A3[官方网站]
|
||||
end
|
||||
|
||||
subgraph "网关层"
|
||||
B1[API网关]
|
||||
B2[负载均衡器]
|
||||
end
|
||||
|
||||
subgraph "应用服务层"
|
||||
C1[用户服务]
|
||||
C2[活动服务]
|
||||
C3[认领服务]
|
||||
C4[支付服务]
|
||||
C5[消息服务]
|
||||
C6[文件服务]
|
||||
C7[管理服务]
|
||||
end
|
||||
|
||||
subgraph "数据服务层"
|
||||
D1[MySQL主从集群]
|
||||
D2[Redis集群]
|
||||
D3[MongoDB集群]
|
||||
D4[Elasticsearch]
|
||||
end
|
||||
|
||||
subgraph "基础设施层"
|
||||
E1[Docker容器]
|
||||
E2[Kubernetes]
|
||||
E3[监控系统]
|
||||
E4[日志系统]
|
||||
E5[CI/CD]
|
||||
end
|
||||
|
||||
subgraph "第三方服务"
|
||||
F1[微信API]
|
||||
F2[支付接口]
|
||||
F3[短信服务]
|
||||
F4[地图服务]
|
||||
F5[云存储]
|
||||
end
|
||||
|
||||
A1 --> B1
|
||||
A2 --> B1
|
||||
A3 --> B1
|
||||
|
||||
B1 --> B2
|
||||
B2 --> C1
|
||||
B2 --> C2
|
||||
B2 --> C3
|
||||
B2 --> C4
|
||||
B2 --> C5
|
||||
B2 --> C6
|
||||
B2 --> C7
|
||||
|
||||
C1 --> D1
|
||||
C2 --> D1
|
||||
C3 --> D1
|
||||
C4 --> D1
|
||||
C5 --> D2
|
||||
C6 --> D3
|
||||
C7 --> D1
|
||||
|
||||
C1 --> D2
|
||||
C2 --> D2
|
||||
C3 --> D2
|
||||
C4 --> D2
|
||||
|
||||
C2 --> D4
|
||||
C3 --> D4
|
||||
|
||||
C1 --> F1
|
||||
C4 --> F2
|
||||
C5 --> F3
|
||||
C2 --> F4
|
||||
C6 --> F5
|
||||
```
|
||||
|
||||
### 2.2 架构分层说明
|
||||
|
||||
#### 2.2.1 客户端层
|
||||
- **微信小程序**:面向C端用户的主要应用
|
||||
- **管理后台Web**:面向运营人员的管理界面
|
||||
- **官方网站**:品牌展示和用户获取的官方门户
|
||||
|
||||
#### 2.2.2 网关层
|
||||
- **API网关**:统一的API入口,负责路由、鉴权、限流等
|
||||
- **负载均衡器**:请求分发和服务负载均衡
|
||||
|
||||
#### 2.2.3 应用服务层
|
||||
- **用户服务**:用户注册、登录、资料管理
|
||||
- **活动服务**:活动发布、报名、管理
|
||||
- **认领服务**:动物认领、管理、互动
|
||||
- **支付服务**:支付处理、订单管理
|
||||
- **消息服务**:消息推送、通知管理
|
||||
- **文件服务**:文件上传、存储、处理
|
||||
- **管理服务**:后台管理功能
|
||||
|
||||
#### 2.2.4 数据服务层
|
||||
- **MySQL主从集群**:关系型数据存储
|
||||
- **Redis集群**:缓存和会话存储
|
||||
- **MongoDB集群**:文档型数据存储
|
||||
- **Elasticsearch**:搜索和日志分析
|
||||
|
||||
#### 2.2.5 基础设施层
|
||||
- **Docker容器**:应用容器化部署
|
||||
- **Kubernetes**:容器编排和管理
|
||||
- **监控系统**:系统监控和告警
|
||||
- **日志系统**:日志收集和分析
|
||||
- **CI/CD**:持续集成和部署
|
||||
|
||||
## 3. 技术栈选型
|
||||
|
||||
### 3.1 前端技术栈
|
||||
|
||||
#### 3.1.1 微信小程序
|
||||
| 技术 | 版本 | 选型理由 |
|
||||
|------|------|----------|
|
||||
| 微信小程序原生 | 最新版本 | 官方支持,性能最优,功能最全 |
|
||||
| Vant Weapp | 1.x | 成熟的小程序UI组件库 |
|
||||
| MobX | 6.x | 轻量级状态管理 |
|
||||
|
||||
#### 3.1.2 管理后台
|
||||
| 技术 | 版本 | 选型理由 |
|
||||
|------|------|----------|
|
||||
| Vue.js | 3.x | 现代化前端框架,生态丰富 |
|
||||
| Element Plus | 2.x | 成熟的Vue3 UI组件库 |
|
||||
| Vue Router | 4.x | Vue官方路由管理 |
|
||||
| Pinia | 2.x | Vue3推荐的状态管理 |
|
||||
| Vite | 4.x | 快速的构建工具 |
|
||||
| TypeScript | 5.x | 类型安全,提高代码质量 |
|
||||
|
||||
#### 3.1.3 官方网站
|
||||
| 技术 | 版本 | 选型理由 |
|
||||
|------|------|----------|
|
||||
| Vue.js | 3.x | 与管理后台技术栈统一 |
|
||||
| Nuxt.js | 3.x | SSR支持,SEO友好 |
|
||||
| Tailwind CSS | 3.x | 原子化CSS,开发效率高 |
|
||||
| TypeScript | 5.x | 类型安全 |
|
||||
|
||||
### 3.2 后端技术栈
|
||||
|
||||
#### 3.2.1 核心框架
|
||||
| 技术 | 版本 | 选型理由 |
|
||||
|------|------|----------|
|
||||
| Node.js | 18+ LTS | 高性能,生态丰富,开发效率高 |
|
||||
| Express.js | 4.x | 成熟的Web框架,中间件丰富 |
|
||||
| TypeScript | 5.x | 类型安全,提高代码质量 |
|
||||
| PM2 | 5.x | 进程管理和监控 |
|
||||
|
||||
#### 3.2.2 数据库
|
||||
| 技术 | 版本 | 选型理由 |
|
||||
|------|------|----------|
|
||||
| MySQL | 8.0+ | 成熟稳定的关系型数据库 |
|
||||
| Redis | 7.x | 高性能缓存和会话存储 |
|
||||
| MongoDB | 6.x | 灵活的文档型数据库 |
|
||||
|
||||
#### 3.2.3 中间件和工具
|
||||
| 技术 | 版本 | 选型理由 |
|
||||
|------|------|----------|
|
||||
| Nginx | 1.20+ | 高性能Web服务器和反向代理 |
|
||||
| RabbitMQ | 3.11+ | 可靠的消息队列 |
|
||||
| Elasticsearch | 8.x | 强大的搜索和分析引擎 |
|
||||
| Docker | 20.x+ | 容器化部署 |
|
||||
| Kubernetes | 1.25+ | 容器编排 |
|
||||
|
||||
### 3.3 第三方服务
|
||||
| 服务 | 提供商 | 用途 |
|
||||
|------|--------|------|
|
||||
| 微信开放平台 | 腾讯 | 小程序登录、支付、分享 |
|
||||
| 腾讯云COS | 腾讯云 | 对象存储 |
|
||||
| 腾讯云SMS | 腾讯云 | 短信服务 |
|
||||
| 腾讯地图API | 腾讯 | 地图和定位服务 |
|
||||
| 微信支付 | 腾讯 | 支付服务 |
|
||||
|
||||
## 4. 系统设计
|
||||
|
||||
### 4.1 微服务架构设计
|
||||
|
||||
#### 4.1.1 服务拆分原则
|
||||
- **业务边界清晰**:按业务领域拆分服务
|
||||
- **数据独立**:每个服务拥有独立的数据存储
|
||||
- **接口标准化**:统一的API设计规范
|
||||
- **服务自治**:服务可独立开发、部署、扩展
|
||||
|
||||
#### 4.1.2 服务间通信
|
||||
```mermaid
|
||||
graph LR
|
||||
A[API网关] --> B[用户服务]
|
||||
A --> C[活动服务]
|
||||
A --> D[认领服务]
|
||||
A --> E[支付服务]
|
||||
|
||||
C --> F[消息队列]
|
||||
D --> F
|
||||
E --> F
|
||||
|
||||
F --> G[消息服务]
|
||||
F --> H[通知服务]
|
||||
|
||||
B --> I[Redis缓存]
|
||||
C --> I
|
||||
D --> I
|
||||
E --> I
|
||||
```
|
||||
|
||||
#### 4.1.3 数据一致性
|
||||
- **最终一致性**:通过消息队列实现最终一致性
|
||||
- **分布式事务**:使用Saga模式处理跨服务事务
|
||||
- **数据同步**:定时任务同步关键数据
|
||||
- **补偿机制**:失败场景的数据补偿
|
||||
|
||||
### 4.2 数据架构设计
|
||||
|
||||
#### 4.2.1 数据分层
|
||||
```mermaid
|
||||
graph TB
|
||||
A[应用层] --> B[服务层]
|
||||
B --> C[数据访问层]
|
||||
C --> D[数据存储层]
|
||||
|
||||
subgraph "数据存储层"
|
||||
D1[MySQL - 业务数据]
|
||||
D2[Redis - 缓存数据]
|
||||
D3[MongoDB - 文档数据]
|
||||
D4[ES - 搜索数据]
|
||||
end
|
||||
|
||||
C --> D1
|
||||
C --> D2
|
||||
C --> D3
|
||||
C --> D4
|
||||
```
|
||||
|
||||
#### 4.2.2 数据库设计原则
|
||||
- **读写分离**:主库写入,从库读取
|
||||
- **分库分表**:按业务和数据量进行分库分表
|
||||
- **索引优化**:合理设计索引提高查询性能
|
||||
- **数据备份**:定期备份和恢复策略
|
||||
|
||||
#### 4.2.3 缓存策略
|
||||
- **多级缓存**:浏览器缓存 + CDN缓存 + Redis缓存
|
||||
- **缓存更新**:Cache-Aside模式
|
||||
- **缓存穿透**:布隆过滤器防止缓存穿透
|
||||
- **缓存雪崩**:缓存过期时间随机化
|
||||
|
||||
### 4.3 安全架构设计
|
||||
|
||||
#### 4.3.1 安全防护体系
|
||||
```mermaid
|
||||
graph TB
|
||||
A[用户请求] --> B[WAF防火墙]
|
||||
B --> C[API网关]
|
||||
C --> D[身份认证]
|
||||
D --> E[权限验证]
|
||||
E --> F[业务服务]
|
||||
|
||||
F --> G[数据加密]
|
||||
G --> H[数据库]
|
||||
|
||||
I[安全监控] --> J[日志分析]
|
||||
J --> K[告警系统]
|
||||
```
|
||||
|
||||
#### 4.3.2 安全措施
|
||||
- **身份认证**:JWT Token + 刷新Token机制
|
||||
- **权限控制**:RBAC角色权限模型
|
||||
- **数据加密**:敏感数据加密存储和传输
|
||||
- **接口安全**:接口签名、频率限制、参数验证
|
||||
- **安全监控**:实时监控异常行为和攻击
|
||||
|
||||
## 5. 部署架构
|
||||
|
||||
### 5.1 部署环境规划
|
||||
|
||||
#### 5.1.1 环境分类
|
||||
| 环境 | 用途 | 配置 |
|
||||
|------|------|------|
|
||||
| 开发环境 | 日常开发测试 | 单机部署,资源共享 |
|
||||
| 测试环境 | 功能测试验证 | 模拟生产环境 |
|
||||
| 预发布环境 | 上线前验证 | 生产环境配置 |
|
||||
| 生产环境 | 正式服务 | 高可用集群部署 |
|
||||
|
||||
#### 5.1.2 生产环境架构
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "负载均衡层"
|
||||
A1[Nginx LB 1]
|
||||
A2[Nginx LB 2]
|
||||
end
|
||||
|
||||
subgraph "应用服务层"
|
||||
B1[App Server 1]
|
||||
B2[App Server 2]
|
||||
B3[App Server 3]
|
||||
end
|
||||
|
||||
subgraph "数据库层"
|
||||
C1[MySQL Master]
|
||||
C2[MySQL Slave 1]
|
||||
C3[MySQL Slave 2]
|
||||
C4[Redis Cluster]
|
||||
end
|
||||
|
||||
subgraph "存储层"
|
||||
D1[文件存储]
|
||||
D2[日志存储]
|
||||
D3[备份存储]
|
||||
end
|
||||
|
||||
A1 --> B1
|
||||
A1 --> B2
|
||||
A2 --> B2
|
||||
A2 --> B3
|
||||
|
||||
B1 --> C1
|
||||
B2 --> C1
|
||||
B3 --> C1
|
||||
|
||||
B1 --> C2
|
||||
B2 --> C3
|
||||
B3 --> C2
|
||||
|
||||
B1 --> C4
|
||||
B2 --> C4
|
||||
B3 --> C4
|
||||
|
||||
B1 --> D1
|
||||
B2 --> D1
|
||||
B3 --> D1
|
||||
```
|
||||
|
||||
### 5.2 容器化部署
|
||||
|
||||
#### 5.2.1 Docker容器化
|
||||
- **应用容器化**:所有服务打包为Docker镜像
|
||||
- **镜像管理**:私有镜像仓库管理
|
||||
- **容器编排**:使用Docker Compose或Kubernetes
|
||||
- **资源限制**:合理设置容器资源限制
|
||||
|
||||
#### 5.2.2 Kubernetes部署
|
||||
```yaml
|
||||
# 示例:用户服务部署配置
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: user-service
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: user-service
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: user-service
|
||||
spec:
|
||||
containers:
|
||||
- name: user-service
|
||||
image: jiebanke/user-service:latest
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
env:
|
||||
- name: NODE_ENV
|
||||
value: "production"
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "250m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
```
|
||||
|
||||
### 5.3 监控和运维
|
||||
|
||||
#### 5.3.1 监控体系
|
||||
```mermaid
|
||||
graph TB
|
||||
A[应用监控] --> D[监控中心]
|
||||
B[系统监控] --> D
|
||||
C[业务监控] --> D
|
||||
|
||||
D --> E[告警系统]
|
||||
D --> F[可视化面板]
|
||||
|
||||
E --> G[短信告警]
|
||||
E --> H[邮件告警]
|
||||
E --> I[微信告警]
|
||||
```
|
||||
|
||||
#### 5.3.2 监控指标
|
||||
- **系统指标**:CPU、内存、磁盘、网络使用率
|
||||
- **应用指标**:响应时间、吞吐量、错误率
|
||||
- **业务指标**:用户活跃度、交易量、转化率
|
||||
- **自定义指标**:关键业务流程的监控指标
|
||||
|
||||
## 6. 性能优化
|
||||
|
||||
### 6.1 前端性能优化
|
||||
|
||||
#### 6.1.1 小程序优化
|
||||
- **代码分包**:按功能模块分包加载
|
||||
- **图片优化**:WebP格式、懒加载、压缩
|
||||
- **缓存策略**:合理使用本地缓存
|
||||
- **网络优化**:请求合并、预加载
|
||||
|
||||
#### 6.1.2 Web端优化
|
||||
- **构建优化**:代码分割、Tree Shaking
|
||||
- **资源优化**:压缩、合并、CDN加速
|
||||
- **渲染优化**:虚拟滚动、懒加载
|
||||
- **缓存优化**:浏览器缓存、Service Worker
|
||||
|
||||
### 6.2 后端性能优化
|
||||
|
||||
#### 6.2.1 应用层优化
|
||||
- **代码优化**:算法优化、异步处理
|
||||
- **连接池**:数据库连接池管理
|
||||
- **缓存策略**:多级缓存、缓存预热
|
||||
- **异步处理**:消息队列异步处理
|
||||
|
||||
#### 6.2.2 数据库优化
|
||||
- **索引优化**:合理创建和使用索引
|
||||
- **查询优化**:SQL语句优化
|
||||
- **读写分离**:主从分离,读写分离
|
||||
- **分库分表**:水平分割,垂直分割
|
||||
|
||||
### 6.3 系统性能目标
|
||||
|
||||
| 指标 | 目标值 | 说明 |
|
||||
|------|--------|------|
|
||||
| 响应时间 | < 200ms | API接口平均响应时间 |
|
||||
| 并发用户 | 10,000+ | 同时在线用户数 |
|
||||
| 可用性 | 99.9% | 系统可用性 |
|
||||
| 错误率 | < 0.1% | 系统错误率 |
|
||||
| 数据库QPS | 5,000+ | 数据库查询性能 |
|
||||
|
||||
## 7. 扩展性设计
|
||||
|
||||
### 7.1 水平扩展
|
||||
|
||||
#### 7.1.1 应用层扩展
|
||||
- **无状态设计**:应用服务无状态,支持水平扩展
|
||||
- **负载均衡**:多实例负载均衡
|
||||
- **自动扩缩容**:基于负载自动扩缩容
|
||||
- **服务发现**:动态服务发现和注册
|
||||
|
||||
#### 7.1.2 数据层扩展
|
||||
- **读写分离**:读库水平扩展
|
||||
- **分库分表**:数据水平分割
|
||||
- **缓存集群**:Redis集群扩展
|
||||
- **搜索集群**:Elasticsearch集群扩展
|
||||
|
||||
### 7.2 垂直扩展
|
||||
|
||||
#### 7.2.1 功能扩展
|
||||
- **插件化架构**:支持功能插件化扩展
|
||||
- **模块化设计**:新功能模块化开发
|
||||
- **API版本管理**:支持API版本演进
|
||||
- **配置化**:业务规则配置化
|
||||
|
||||
#### 7.2.2 技术栈扩展
|
||||
- **多语言支持**:支持多种编程语言
|
||||
- **多数据库支持**:支持多种数据库
|
||||
- **云原生**:支持云原生技术栈
|
||||
- **微服务演进**:支持微服务架构演进
|
||||
|
||||
## 8. 风险评估与应对
|
||||
|
||||
### 8.1 技术风险
|
||||
|
||||
#### 8.1.1 性能风险
|
||||
- **风险描述**:高并发场景下系统性能瓶颈
|
||||
- **影响程度**:高
|
||||
- **应对策略**:
|
||||
- 性能测试和优化
|
||||
- 缓存策略优化
|
||||
- 数据库优化
|
||||
- 水平扩展
|
||||
|
||||
#### 8.1.2 可用性风险
|
||||
- **风险描述**:系统故障导致服务不可用
|
||||
- **影响程度**:高
|
||||
- **应对策略**:
|
||||
- 高可用架构设计
|
||||
- 故障自动恢复
|
||||
- 监控告警系统
|
||||
- 灾备方案
|
||||
|
||||
#### 8.1.3 数据安全风险
|
||||
- **风险描述**:数据泄露或丢失
|
||||
- **影响程度**:高
|
||||
- **应对策略**:
|
||||
- 数据加密
|
||||
- 访问控制
|
||||
- 数据备份
|
||||
- 安全审计
|
||||
|
||||
### 8.2 业务风险
|
||||
|
||||
#### 8.2.1 用户增长风险
|
||||
- **风险描述**:用户快速增长超出系统承载能力
|
||||
- **影响程度**:中
|
||||
- **应对策略**:
|
||||
- 弹性扩展架构
|
||||
- 性能监控
|
||||
- 容量规划
|
||||
- 分阶段发布
|
||||
|
||||
#### 8.2.2 第三方依赖风险
|
||||
- **风险描述**:第三方服务故障影响系统功能
|
||||
- **影响程度**:中
|
||||
- **应对策略**:
|
||||
- 多供应商策略
|
||||
- 服务降级
|
||||
- 本地缓存
|
||||
- 监控告警
|
||||
|
||||
### 8.3 运维风险
|
||||
|
||||
#### 8.3.1 部署风险
|
||||
- **风险描述**:部署过程中出现故障
|
||||
- **影响程度**:中
|
||||
- **应对策略**:
|
||||
- 蓝绿部署
|
||||
- 灰度发布
|
||||
- 自动化部署
|
||||
- 回滚机制
|
||||
|
||||
#### 8.3.2 人员风险
|
||||
- **风险描述**:关键人员离职影响项目进度
|
||||
- **影响程度**:中
|
||||
- **应对策略**:
|
||||
- 文档完善
|
||||
- 知识分享
|
||||
- 团队培训
|
||||
- 备份人员
|
||||
|
||||
## 9. 总结
|
||||
|
||||
### 9.1 架构优势
|
||||
- **高可用性**:多层次的高可用保障
|
||||
- **高性能**:多级缓存和性能优化
|
||||
- **可扩展性**:支持业务快速发展
|
||||
- **安全性**:全方位的安全防护
|
||||
- **可维护性**:清晰的架构分层和模块化设计
|
||||
|
||||
### 9.2 技术创新点
|
||||
- **微服务架构**:现代化的微服务架构设计
|
||||
- **容器化部署**:Docker + Kubernetes容器化部署
|
||||
- **多端统一**:统一的后端服务支持多端应用
|
||||
- **智能推荐**:基于用户行为的智能推荐算法
|
||||
- **实时通信**:WebSocket实时消息推送
|
||||
|
||||
### 9.3 后续演进
|
||||
- **云原生**:向云原生架构演进
|
||||
- **服务网格**:引入Service Mesh技术
|
||||
- **AI集成**:集成人工智能技术
|
||||
- **边缘计算**:支持边缘计算场景
|
||||
- **国际化**:支持多语言和多地区部署
|
||||
292
docs/整个项目需求文档.md
Normal file
292
docs/整个项目需求文档.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# 解班客项目需求文档
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
### 1.1 项目背景
|
||||
解班客是一个创新的社交旅行平台,专注于为用户提供结伴旅行服务,并融入了独特的动物认领功能。该项目旨在通过结合传统的结伴旅行功能与现代的动物认领体验,为用户创造独特的旅行记忆。
|
||||
|
||||
### 1.2 项目目标
|
||||
- 构建一个完整的社交旅行生态系统
|
||||
- 提供便捷的结伴旅行服务
|
||||
- 创新性地融入动物认领功能
|
||||
- 为商家提供多元化的服务平台
|
||||
- 建立可持续发展的商业模式
|
||||
|
||||
### 1.3 项目范围
|
||||
本项目包含以下四个核心模块:
|
||||
- **微信小程序**:面向C端用户的移动应用
|
||||
- **管理后台系统**:面向管理员的Web管理平台
|
||||
- **后端管理系统**:提供API服务和业务逻辑
|
||||
- **官方网站**:品牌展示和商家入驻平台
|
||||
|
||||
## 2. 用户角色定义
|
||||
|
||||
### 2.1 普通用户(C端用户)
|
||||
- **主要特征**:热爱旅行的年轻人群,希望通过旅行结识新朋友
|
||||
- **核心需求**:寻找旅伴、参与活动、动物认领、社交互动
|
||||
- **使用场景**:通过微信小程序进行日常操作
|
||||
|
||||
### 2.2 商家用户
|
||||
- **花店商家**:提供鲜花产品和相关服务
|
||||
- **活动组织者**:组织各类结伴活动和旅行项目
|
||||
- **农场主**:提供动物认领和农场体验服务
|
||||
- **旅行服务商**:提供专业的旅行规划和服务
|
||||
|
||||
### 2.3 管理员
|
||||
- **系统管理员**:负责系统维护和用户管理
|
||||
- **内容管理员**:负责内容审核和活动管理
|
||||
- **客服人员**:处理用户咨询和投诉
|
||||
|
||||
## 3. 功能需求
|
||||
|
||||
### 3.1 用户系统
|
||||
#### 3.1.1 用户注册与登录
|
||||
- 微信授权登录
|
||||
- 手机号验证
|
||||
- 用户信息完善
|
||||
- 实名认证(可选)
|
||||
|
||||
#### 3.1.2 用户信息管理
|
||||
- 个人资料编辑
|
||||
- 头像上传
|
||||
- 兴趣标签设置
|
||||
- 隐私设置
|
||||
|
||||
#### 3.1.3 用户认证
|
||||
- 身份证认证
|
||||
- 芝麻信用认证
|
||||
- 手机号认证
|
||||
- 邮箱认证
|
||||
|
||||
### 3.2 结伴旅行功能
|
||||
#### 3.2.1 活动发布
|
||||
- 创建结伴活动
|
||||
- 设置活动详情(时间、地点、人数、费用)
|
||||
- 上传活动图片
|
||||
- 设置报名条件
|
||||
|
||||
#### 3.2.2 活动搜索与筛选
|
||||
- 按地理位置搜索
|
||||
- 按活动类型筛选
|
||||
- 按时间范围筛选
|
||||
- 按价格区间筛选
|
||||
- 关键词搜索
|
||||
|
||||
#### 3.2.3 报名与管理
|
||||
- 在线报名
|
||||
- 报名审核
|
||||
- 参与者管理
|
||||
- 活动取消与退款
|
||||
|
||||
#### 3.2.4 智能匹配
|
||||
- 基于兴趣爱好匹配
|
||||
- 基于地理位置匹配
|
||||
- 基于时间安排匹配
|
||||
- 推荐算法优化
|
||||
|
||||
### 3.3 动物认领功能
|
||||
#### 3.3.1 动物信息管理
|
||||
- 动物基本信息录入
|
||||
- 动物照片上传
|
||||
- 健康状态记录
|
||||
- 成长记录更新
|
||||
|
||||
#### 3.3.2 认领流程
|
||||
- 浏览可认领动物
|
||||
- 提交认领申请
|
||||
- 认领审核流程
|
||||
- 认领合同签署
|
||||
|
||||
#### 3.3.3 认领后管理
|
||||
- 动物状态跟踪
|
||||
- 农场探访预约
|
||||
- 成长记录查看
|
||||
- 互动功能(喂食、拍照等)
|
||||
|
||||
### 3.4 商家服务功能
|
||||
#### 3.4.1 商家入驻
|
||||
- 商家注册申请
|
||||
- 资质审核
|
||||
- 店铺信息设置
|
||||
- 服务类目选择
|
||||
|
||||
#### 3.4.2 商品/服务管理
|
||||
- 商品发布与编辑
|
||||
- 库存管理
|
||||
- 价格设置
|
||||
- 促销活动
|
||||
|
||||
#### 3.4.3 订单管理
|
||||
- 订单接收与处理
|
||||
- 订单状态更新
|
||||
- 发货管理
|
||||
- 售后服务
|
||||
|
||||
### 3.5 社交功能
|
||||
#### 3.5.1 消息系统
|
||||
- 私信功能
|
||||
- 群聊功能
|
||||
- 系统通知
|
||||
- 活动通知
|
||||
|
||||
#### 3.5.2 社区功能
|
||||
- 动态发布
|
||||
- 图片分享
|
||||
- 点赞评论
|
||||
- 关注功能
|
||||
|
||||
### 3.6 支付功能
|
||||
#### 3.6.1 支付方式
|
||||
- 微信支付
|
||||
- 支付宝支付
|
||||
- 银行卡支付
|
||||
- 余额支付
|
||||
|
||||
#### 3.6.2 财务管理
|
||||
- 充值功能
|
||||
- 提现功能
|
||||
- 交易记录
|
||||
- 发票管理
|
||||
|
||||
## 4. 非功能需求
|
||||
|
||||
### 4.1 性能需求
|
||||
- 系统响应时间 < 2秒
|
||||
- 并发用户数支持 > 10000
|
||||
- 系统可用性 > 99.5%
|
||||
- 数据库查询优化
|
||||
|
||||
### 4.2 安全需求
|
||||
- 用户数据加密存储
|
||||
- API接口安全认证
|
||||
- 防SQL注入
|
||||
- 防XSS攻击
|
||||
- 数据备份与恢复
|
||||
|
||||
### 4.3 兼容性需求
|
||||
- 支持主流浏览器
|
||||
- 微信小程序兼容性
|
||||
- 移动端适配
|
||||
- 不同屏幕尺寸适配
|
||||
|
||||
### 4.4 可扩展性需求
|
||||
- 微服务架构设计
|
||||
- 水平扩展能力
|
||||
- 模块化设计
|
||||
- 插件化支持
|
||||
|
||||
## 5. 技术需求
|
||||
|
||||
### 5.1 前端技术栈
|
||||
- **微信小程序**:原生小程序开发 + Vant Weapp UI组件
|
||||
- **管理后台**:Vue 3 + TypeScript + Element Plus
|
||||
- **官方网站**:Vue 3 + Vue Router + 响应式设计
|
||||
|
||||
### 5.2 后端技术栈
|
||||
- **运行环境**:Node.js 18+
|
||||
- **Web框架**:Express.js
|
||||
- **数据库**:MySQL 8.0
|
||||
- **缓存**:Redis 6.0
|
||||
- **认证**:JWT + Passport
|
||||
|
||||
### 5.3 基础设施
|
||||
- **容器化**:Docker + Docker Compose
|
||||
- **反向代理**:Nginx
|
||||
- **进程管理**:PM2
|
||||
- **监控**:Prometheus + Grafana
|
||||
|
||||
## 6. 项目约束
|
||||
|
||||
### 6.1 时间约束
|
||||
- 项目总周期:6个月
|
||||
- MVP版本:3个月
|
||||
- 完整版本:6个月
|
||||
|
||||
### 6.2 预算约束
|
||||
- 开发成本控制
|
||||
- 服务器成本优化
|
||||
- 第三方服务费用
|
||||
|
||||
### 6.3 技术约束
|
||||
- 必须支持微信小程序
|
||||
- 必须支持移动端
|
||||
- 必须符合相关法规要求
|
||||
|
||||
## 7. 验收标准
|
||||
|
||||
### 7.1 功能验收
|
||||
- 所有核心功能正常运行
|
||||
- 用户流程完整可用
|
||||
- 数据准确性验证
|
||||
- 异常情况处理
|
||||
|
||||
### 7.2 性能验收
|
||||
- 响应时间达标
|
||||
- 并发性能达标
|
||||
- 稳定性测试通过
|
||||
- 压力测试通过
|
||||
|
||||
### 7.3 安全验收
|
||||
- 安全测试通过
|
||||
- 漏洞扫描通过
|
||||
- 数据安全验证
|
||||
- 权限控制验证
|
||||
|
||||
## 8. 风险评估
|
||||
|
||||
### 8.1 技术风险
|
||||
- 第三方API稳定性
|
||||
- 数据迁移风险
|
||||
- 性能瓶颈风险
|
||||
- 安全漏洞风险
|
||||
|
||||
### 8.2 业务风险
|
||||
- 用户接受度风险
|
||||
- 竞争对手风险
|
||||
- 政策法规风险
|
||||
- 市场变化风险
|
||||
|
||||
### 8.3 项目风险
|
||||
- 进度延期风险
|
||||
- 人员流失风险
|
||||
- 需求变更风险
|
||||
- 质量风险
|
||||
|
||||
## 9. 项目里程碑
|
||||
|
||||
### 9.1 第一阶段(1-2个月)
|
||||
- 需求分析完成
|
||||
- 系统架构设计
|
||||
- 数据库设计
|
||||
- 开发环境搭建
|
||||
|
||||
### 9.2 第二阶段(3-4个月)
|
||||
- 核心功能开发
|
||||
- 用户系统完成
|
||||
- 基础功能测试
|
||||
- MVP版本发布
|
||||
|
||||
### 9.3 第三阶段(5-6个月)
|
||||
- 完整功能开发
|
||||
- 系统集成测试
|
||||
- 性能优化
|
||||
- 正式版本发布
|
||||
|
||||
## 10. 后续规划
|
||||
|
||||
### 10.1 功能扩展
|
||||
- AI智能推荐
|
||||
- 直播功能
|
||||
- 短视频功能
|
||||
- 积分商城
|
||||
|
||||
### 10.2 平台扩展
|
||||
- APP版本开发
|
||||
- H5版本开发
|
||||
- 其他平台小程序
|
||||
|
||||
### 10.3 业务扩展
|
||||
- 更多动物类型
|
||||
- 国际化支持
|
||||
- 企业服务
|
||||
- 品牌合作
|
||||
694
docs/文件上传系统文档.md
694
docs/文件上传系统文档.md
@@ -1,694 +0,0 @@
|
||||
# 文件上传系统文档
|
||||
|
||||
## 概述
|
||||
|
||||
文件上传系统为解班客平台提供了完整的文件管理功能,支持多种文件类型的上传、处理、存储和管理。系统采用模块化设计,支持图片处理、文件验证、安全控制等功能。
|
||||
|
||||
## 系统架构
|
||||
|
||||
### 核心组件
|
||||
|
||||
1. **上传中间件** (`middleware/upload.js`)
|
||||
- 文件上传处理
|
||||
- 文件类型验证
|
||||
- 大小限制控制
|
||||
- 存储路径管理
|
||||
|
||||
2. **图片处理器**
|
||||
- 图片压缩和格式转换
|
||||
- 缩略图生成
|
||||
- 尺寸调整
|
||||
- 质量优化
|
||||
|
||||
3. **文件管理控制器** (`controllers/admin/fileManagement.js`)
|
||||
- 文件列表管理
|
||||
- 文件统计分析
|
||||
- 批量操作
|
||||
- 清理功能
|
||||
|
||||
4. **错误处理机制**
|
||||
- 统一错误响应
|
||||
- 详细错误日志
|
||||
- 安全错误信息
|
||||
|
||||
## 支持的文件类型
|
||||
|
||||
### 图片文件
|
||||
- **格式**: JPG, JPEG, PNG, GIF, WebP
|
||||
- **用途**: 头像、动物图片、旅行照片
|
||||
- **处理**: 自动压缩、生成缩略图、格式转换
|
||||
|
||||
### 文档文件
|
||||
- **格式**: PDF, DOC, DOCX, XLS, XLSX, TXT
|
||||
- **用途**: 证书、合同、报告等
|
||||
- **处理**: 文件验证、病毒扫描(计划中)
|
||||
|
||||
## 文件分类存储
|
||||
|
||||
### 存储目录结构
|
||||
```
|
||||
uploads/
|
||||
├── avatars/ # 用户头像
|
||||
├── animals/ # 动物图片
|
||||
├── travels/ # 旅行图片
|
||||
├── documents/ # 文档文件
|
||||
└── temp/ # 临时文件
|
||||
```
|
||||
|
||||
### 文件命名规则
|
||||
- **格式**: `{timestamp}_{randomString}.{extension}`
|
||||
- **示例**: `1701234567890_a1b2c3d4.jpg`
|
||||
- **优势**: 避免重名、便于排序、安全性高
|
||||
|
||||
## 上传限制配置
|
||||
|
||||
### 头像上传
|
||||
- **文件类型**: JPG, PNG
|
||||
- **文件大小**: 最大 2MB
|
||||
- **文件数量**: 1个
|
||||
- **处理**: 300x300像素,生成100x100缩略图
|
||||
|
||||
### 动物图片上传
|
||||
- **文件类型**: JPG, PNG, GIF, WebP
|
||||
- **文件大小**: 最大 5MB
|
||||
- **文件数量**: 最多 5张
|
||||
- **处理**: 800x600像素,生成200x200缩略图
|
||||
|
||||
### 旅行图片上传
|
||||
- **文件类型**: JPG, PNG, GIF, WebP
|
||||
- **文件大小**: 最大 5MB
|
||||
- **文件数量**: 最多 10张
|
||||
- **处理**: 1200x800像素,生成300x300缩略图
|
||||
|
||||
### 文档上传
|
||||
- **文件类型**: PDF, DOC, DOCX, XLS, XLSX, TXT
|
||||
- **文件大小**: 最大 10MB
|
||||
- **文件数量**: 最多 3个
|
||||
- **处理**: 仅验证,不做格式转换
|
||||
|
||||
## API接口说明
|
||||
|
||||
### 文件上传接口
|
||||
|
||||
#### 1. 头像上传
|
||||
```http
|
||||
POST /api/v1/admin/files/upload/avatar
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
avatar: [文件]
|
||||
```
|
||||
|
||||
#### 2. 动物图片上传
|
||||
```http
|
||||
POST /api/v1/admin/files/upload/animal
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
images: [文件1, 文件2, ...]
|
||||
```
|
||||
|
||||
#### 3. 旅行图片上传
|
||||
```http
|
||||
POST /api/v1/admin/files/upload/travel
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
images: [文件1, 文件2, ...]
|
||||
```
|
||||
|
||||
#### 4. 文档上传
|
||||
```http
|
||||
POST /api/v1/admin/files/upload/document
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
documents: [文件1, 文件2, ...]
|
||||
```
|
||||
|
||||
### 文件管理接口
|
||||
|
||||
#### 1. 获取文件列表
|
||||
```http
|
||||
GET /api/v1/admin/files?page=1&limit=20&type=all&keyword=搜索词
|
||||
```
|
||||
|
||||
#### 2. 获取文件详情
|
||||
```http
|
||||
GET /api/v1/admin/files/{file_id}
|
||||
```
|
||||
|
||||
#### 3. 删除文件
|
||||
```http
|
||||
DELETE /api/v1/admin/files/{file_id}
|
||||
```
|
||||
|
||||
#### 4. 批量删除文件
|
||||
```http
|
||||
POST /api/v1/admin/files/batch/delete
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"file_ids": ["id1", "id2", "id3"]
|
||||
}
|
||||
```
|
||||
|
||||
#### 5. 获取文件统计
|
||||
```http
|
||||
GET /api/v1/admin/files/statistics
|
||||
```
|
||||
|
||||
#### 6. 清理无用文件
|
||||
```http
|
||||
POST /api/v1/admin/files/cleanup?dry_run=true
|
||||
```
|
||||
|
||||
## 图片处理功能
|
||||
|
||||
### 自动处理流程
|
||||
1. **上传验证**: 检查文件类型、大小、数量
|
||||
2. **格式转换**: 统一转换为JPEG格式(可配置)
|
||||
3. **尺寸调整**: 按预设尺寸调整图片大小
|
||||
4. **质量压缩**: 优化文件大小,保持视觉质量
|
||||
5. **缩略图生成**: 生成小尺寸预览图
|
||||
6. **文件保存**: 保存到指定目录
|
||||
|
||||
### 处理参数配置
|
||||
```javascript
|
||||
// 头像处理配置
|
||||
{
|
||||
width: 300,
|
||||
height: 300,
|
||||
quality: 85,
|
||||
format: 'jpeg',
|
||||
thumbnail: true,
|
||||
thumbnailSize: 100
|
||||
}
|
||||
|
||||
// 动物图片处理配置
|
||||
{
|
||||
width: 800,
|
||||
height: 600,
|
||||
quality: 80,
|
||||
format: 'jpeg',
|
||||
thumbnail: true,
|
||||
thumbnailSize: 200
|
||||
}
|
||||
```
|
||||
|
||||
## 安全机制
|
||||
|
||||
### 文件验证
|
||||
1. **MIME类型检查**: 验证文件真实类型
|
||||
2. **文件扩展名检查**: 防止恶意文件上传
|
||||
3. **文件大小限制**: 防止大文件攻击
|
||||
4. **文件数量限制**: 防止批量上传攻击
|
||||
|
||||
### 存储安全
|
||||
1. **随机文件名**: 防止文件名猜测
|
||||
2. **目录隔离**: 不同类型文件分目录存储
|
||||
3. **访问控制**: 通过Web服务器配置访问权限
|
||||
4. **定期清理**: 自动清理临时和无用文件
|
||||
|
||||
### 错误处理
|
||||
1. **统一错误格式**: 标准化错误响应
|
||||
2. **详细日志记录**: 记录所有操作和错误
|
||||
3. **安全错误信息**: 不暴露系统内部信息
|
||||
4. **异常恢复**: 上传失败时自动清理临时文件
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 图片优化
|
||||
1. **智能压缩**: 根据图片内容调整压缩参数
|
||||
2. **格式选择**: 自动选择最优图片格式
|
||||
3. **渐进式JPEG**: 支持渐进式加载
|
||||
4. **WebP支持**: 现代浏览器使用WebP格式
|
||||
|
||||
### 存储优化
|
||||
1. **分目录存储**: 避免单目录文件过多
|
||||
2. **CDN集成**: 支持CDN加速(计划中)
|
||||
3. **缓存策略**: 合理设置HTTP缓存头
|
||||
4. **压缩传输**: 启用gzip压缩
|
||||
|
||||
### 并发处理
|
||||
1. **异步处理**: 图片处理使用异步操作
|
||||
2. **队列机制**: 大批量操作使用队列(计划中)
|
||||
3. **限流控制**: 防止并发上传过多
|
||||
4. **资源监控**: 监控CPU和内存使用
|
||||
|
||||
## 监控和统计
|
||||
|
||||
### 文件统计
|
||||
- **总文件数量**: 系统中所有文件的数量
|
||||
- **存储空间使用**: 各类型文件占用的存储空间
|
||||
- **文件格式分布**: 不同格式文件的数量和占比
|
||||
- **上传趋势**: 文件上传的时间趋势
|
||||
|
||||
### 性能监控
|
||||
- **上传成功率**: 文件上传的成功率统计
|
||||
- **处理时间**: 文件处理的平均时间
|
||||
- **错误率**: 各类错误的发生频率
|
||||
- **存储使用率**: 存储空间的使用情况
|
||||
|
||||
### 日志记录
|
||||
- **操作日志**: 记录所有文件操作
|
||||
- **错误日志**: 记录所有错误和异常
|
||||
- **性能日志**: 记录性能相关数据
|
||||
- **安全日志**: 记录安全相关事件
|
||||
|
||||
## 维护和管理
|
||||
|
||||
### 定期维护任务
|
||||
1. **清理临时文件**: 每小时清理超过24小时的临时文件
|
||||
2. **清理无用文件**: 定期扫描和清理不再使用的文件
|
||||
3. **日志轮转**: 定期归档和清理日志文件
|
||||
4. **存储空间监控**: 监控存储空间使用情况
|
||||
|
||||
### 备份策略
|
||||
1. **增量备份**: 每日增量备份新上传的文件
|
||||
2. **全量备份**: 每周全量备份所有文件
|
||||
3. **异地备份**: 重要文件异地备份(计划中)
|
||||
4. **恢复测试**: 定期测试备份恢复功能
|
||||
|
||||
### 故障处理
|
||||
1. **自动恢复**: 临时故障自动重试
|
||||
2. **降级服务**: 服务异常时提供基础功能
|
||||
3. **故障通知**: 严重故障及时通知管理员
|
||||
4. **快速恢复**: 提供快速故障恢复方案
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 前端上传示例
|
||||
|
||||
#### HTML表单上传
|
||||
```html
|
||||
<form id="uploadForm" enctype="multipart/form-data">
|
||||
<input type="file" name="images" multiple accept="image/*">
|
||||
<button type="submit">上传</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
#### JavaScript上传
|
||||
```javascript
|
||||
async function uploadFiles(files, type = 'animal') {
|
||||
const formData = new FormData();
|
||||
|
||||
// 添加文件到表单数据
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
formData.append('images', files[i]);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/v1/admin/files/upload/${type}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: formData
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
console.log('上传成功:', result.data.files);
|
||||
return result.data.files;
|
||||
} else {
|
||||
throw new Error(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('上传失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
const fileInput = document.getElementById('fileInput');
|
||||
fileInput.addEventListener('change', async (e) => {
|
||||
const files = e.target.files;
|
||||
if (files.length > 0) {
|
||||
try {
|
||||
const uploadedFiles = await uploadFiles(files, 'animal');
|
||||
// 处理上传成功的文件
|
||||
displayUploadedFiles(uploadedFiles);
|
||||
} catch (error) {
|
||||
// 处理上传错误
|
||||
showError(error.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### Vue.js组件示例
|
||||
```vue
|
||||
<template>
|
||||
<div class="file-upload">
|
||||
<div class="upload-area" @drop="handleDrop" @dragover.prevent>
|
||||
<input
|
||||
ref="fileInput"
|
||||
type="file"
|
||||
multiple
|
||||
:accept="acceptTypes"
|
||||
@change="handleFileSelect"
|
||||
style="display: none"
|
||||
>
|
||||
<button @click="$refs.fileInput.click()">选择文件</button>
|
||||
<p>或拖拽文件到此处</p>
|
||||
</div>
|
||||
|
||||
<div v-if="uploading" class="upload-progress">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" :style="{width: progress + '%'}"></div>
|
||||
</div>
|
||||
<p>上传中... {{ progress }}%</p>
|
||||
</div>
|
||||
|
||||
<div v-if="uploadedFiles.length > 0" class="uploaded-files">
|
||||
<h3>已上传文件</h3>
|
||||
<div class="file-list">
|
||||
<div v-for="file in uploadedFiles" :key="file.id" class="file-item">
|
||||
<img v-if="file.thumbnailUrl" :src="file.thumbnailUrl" :alt="file.filename">
|
||||
<div class="file-info">
|
||||
<p class="filename">{{ file.originalName }}</p>
|
||||
<p class="filesize">{{ formatFileSize(file.size) }}</p>
|
||||
</div>
|
||||
<button @click="deleteFile(file.id)" class="delete-btn">删除</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FileUpload',
|
||||
props: {
|
||||
uploadType: {
|
||||
type: String,
|
||||
default: 'animal'
|
||||
},
|
||||
maxFiles: {
|
||||
type: Number,
|
||||
default: 5
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
uploading: false,
|
||||
progress: 0,
|
||||
uploadedFiles: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
acceptTypes() {
|
||||
const types = {
|
||||
avatar: 'image/jpeg,image/png',
|
||||
animal: 'image/jpeg,image/png,image/gif,image/webp',
|
||||
travel: 'image/jpeg,image/png,image/gif,image/webp',
|
||||
document: '.pdf,.doc,.docx,.xls,.xlsx,.txt'
|
||||
};
|
||||
return types[this.uploadType] || 'image/*';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleFileSelect(event) {
|
||||
const files = Array.from(event.target.files);
|
||||
this.uploadFiles(files);
|
||||
},
|
||||
|
||||
handleDrop(event) {
|
||||
event.preventDefault();
|
||||
const files = Array.from(event.dataTransfer.files);
|
||||
this.uploadFiles(files);
|
||||
},
|
||||
|
||||
async uploadFiles(files) {
|
||||
if (files.length === 0) return;
|
||||
|
||||
if (files.length > this.maxFiles) {
|
||||
this.$message.error(`最多只能上传${this.maxFiles}个文件`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.uploading = true;
|
||||
this.progress = 0;
|
||||
|
||||
const formData = new FormData();
|
||||
const fieldName = this.uploadType === 'avatar' ? 'avatar' :
|
||||
this.uploadType === 'document' ? 'documents' : 'images';
|
||||
|
||||
files.forEach(file => {
|
||||
formData.append(fieldName, file);
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await this.$http.post(
|
||||
`/admin/files/upload/${this.uploadType}`,
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
},
|
||||
onUploadProgress: (progressEvent) => {
|
||||
this.progress = Math.round(
|
||||
(progressEvent.loaded * 100) / progressEvent.total
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (response.data.success) {
|
||||
this.uploadedFiles.push(...response.data.data.files);
|
||||
this.$message.success('文件上传成功');
|
||||
this.$emit('uploaded', response.data.data.files);
|
||||
} else {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('上传失败:', error);
|
||||
this.$message.error(error.message || '文件上传失败');
|
||||
} finally {
|
||||
this.uploading = false;
|
||||
this.progress = 0;
|
||||
}
|
||||
},
|
||||
|
||||
async deleteFile(fileId) {
|
||||
try {
|
||||
const response = await this.$http.delete(`/admin/files/${fileId}`);
|
||||
|
||||
if (response.data.success) {
|
||||
this.uploadedFiles = this.uploadedFiles.filter(f => f.id !== fileId);
|
||||
this.$message.success('文件删除成功');
|
||||
this.$emit('deleted', fileId);
|
||||
} else {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error);
|
||||
this.$message.error(error.message || '文件删除失败');
|
||||
}
|
||||
},
|
||||
|
||||
formatFileSize(bytes) {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
const k = 1024;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.file-upload {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
border: 2px dashed #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
|
||||
.upload-area:hover {
|
||||
border-color: #007bff;
|
||||
}
|
||||
|
||||
.upload-progress {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background-color: #007bff;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
|
||||
.uploaded-files {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.file-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.file-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.file-item img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.file-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.filename {
|
||||
font-weight: bold;
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
.filesize {
|
||||
color: #666;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
background-color: #dc3545;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.delete-btn:hover {
|
||||
background-color: #c82333;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 1. 上传失败
|
||||
**问题**: 文件上传时返回错误
|
||||
**可能原因**:
|
||||
- 文件大小超出限制
|
||||
- 文件类型不支持
|
||||
- 服务器存储空间不足
|
||||
- 网络连接问题
|
||||
|
||||
**解决方案**:
|
||||
- 检查文件大小和类型
|
||||
- 确认服务器存储空间
|
||||
- 检查网络连接
|
||||
- 查看错误日志
|
||||
|
||||
#### 2. 图片处理失败
|
||||
**问题**: 图片上传成功但处理失败
|
||||
**可能原因**:
|
||||
- Sharp库未正确安装
|
||||
- 图片文件损坏
|
||||
- 服务器内存不足
|
||||
- 权限问题
|
||||
|
||||
**解决方案**:
|
||||
- 重新安装Sharp库
|
||||
- 检查图片文件完整性
|
||||
- 增加服务器内存
|
||||
- 检查文件权限
|
||||
|
||||
#### 3. 文件访问404
|
||||
**问题**: 上传的文件无法访问
|
||||
**可能原因**:
|
||||
- 静态文件服务未配置
|
||||
- 文件路径错误
|
||||
- 文件被误删
|
||||
- 权限设置问题
|
||||
|
||||
**解决方案**:
|
||||
- 配置静态文件服务
|
||||
- 检查文件路径
|
||||
- 恢复备份文件
|
||||
- 调整文件权限
|
||||
|
||||
### 调试方法
|
||||
|
||||
#### 1. 启用详细日志
|
||||
```javascript
|
||||
// 在环境变量中设置
|
||||
NODE_ENV=development
|
||||
LOG_LEVEL=debug
|
||||
```
|
||||
|
||||
#### 2. 检查上传目录权限
|
||||
```bash
|
||||
# 检查目录权限
|
||||
ls -la uploads/
|
||||
|
||||
# 设置正确权限
|
||||
chmod 755 uploads/
|
||||
chmod 644 uploads/*
|
||||
```
|
||||
|
||||
#### 3. 监控系统资源
|
||||
```bash
|
||||
# 监控磁盘空间
|
||||
df -h
|
||||
|
||||
# 监控内存使用
|
||||
free -m
|
||||
|
||||
# 监控进程
|
||||
ps aux | grep node
|
||||
```
|
||||
|
||||
## 扩展功能
|
||||
|
||||
### 计划中的功能
|
||||
1. **CDN集成**: 支持阿里云OSS、腾讯云COS等
|
||||
2. **病毒扫描**: 集成病毒扫描引擎
|
||||
3. **水印添加**: 自动为图片添加水印
|
||||
4. **智能裁剪**: AI驱动的智能图片裁剪
|
||||
5. **格式转换**: 支持更多图片格式转换
|
||||
6. **批量处理**: 支持批量图片处理
|
||||
7. **版本控制**: 文件版本管理
|
||||
8. **权限控制**: 细粒度的文件访问权限
|
||||
|
||||
### 集成建议
|
||||
1. **前端组件**: 开发可复用的上传组件
|
||||
2. **移动端适配**: 支持移动端文件上传
|
||||
3. **拖拽上传**: 实现拖拽上传功能
|
||||
4. **进度显示**: 显示上传进度和状态
|
||||
5. **预览功能**: 上传前预览文件
|
||||
6. **批量操作**: 支持批量选择和操作
|
||||
|
||||
## 总结
|
||||
|
||||
文件上传系统为解班客平台提供了完整、安全、高效的文件管理解决方案。通过模块化设计、完善的错误处理、详细的日志记录和性能优化,确保系统的稳定性和可维护性。
|
||||
|
||||
系统支持多种文件类型,提供了灵活的配置选项,能够满足不同场景的需求。同时,通过监控和统计功能,管理员可以实时了解系统状态,及时发现和解决问题。
|
||||
|
||||
未来将继续完善系统功能,增加更多高级特性,为用户提供更好的文件管理体验。
|
||||
413
docs/测试文档.md
413
docs/测试文档.md
@@ -1,55 +1,390 @@
|
||||
# 解班客测试文档
|
||||
# 解班客项目测试文档
|
||||
|
||||
## 📋 概述
|
||||
## 1. 测试概述
|
||||
|
||||
本文档详细描述解班客项目的测试策略、测试流程、测试用例设计和质量保证体系。通过全面的测试覆盖,确保系统的稳定性、可靠性和用户体验。
|
||||
### 1.1 测试目标
|
||||
确保解班客项目各个模块的功能正确性、性能稳定性、安全可靠性,为产品上线提供质量保障。
|
||||
|
||||
## 🎯 测试目标
|
||||
### 1.2 测试范围
|
||||
- **后端API服务**:接口功能、性能、安全测试
|
||||
- **小程序应用**:功能、兼容性、用户体验测试
|
||||
- **管理后台**:功能、权限、数据一致性测试
|
||||
- **数据库**:数据完整性、性能、备份恢复测试
|
||||
- **系统集成**:各模块间集成测试
|
||||
|
||||
### 主要目标
|
||||
- **功能完整性**: 确保所有功能按需求正确实现
|
||||
- **系统稳定性**: 保证系统在各种条件下稳定运行
|
||||
- **性能达标**: 满足性能指标和用户体验要求
|
||||
- **安全可靠**: 确保数据安全和系统安全
|
||||
- **兼容性**: 支持多平台和多浏览器
|
||||
|
||||
### 质量标准
|
||||
- **代码覆盖率**: ≥ 80%
|
||||
- **接口测试覆盖率**: 100%
|
||||
- **核心功能测试覆盖率**: 100%
|
||||
- **性能指标**: 响应时间 < 2秒
|
||||
- **可用性**: 99.9%
|
||||
|
||||
## 🏗️ 测试架构
|
||||
|
||||
### 测试金字塔
|
||||
### 1.3 测试策略
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[UI测试 - 10%] --> B[集成测试 - 20%]
|
||||
B --> C[单元测试 - 70%]
|
||||
A[测试策略] --> B[单元测试]
|
||||
A --> C[集成测试]
|
||||
A --> D[系统测试]
|
||||
A --> E[验收测试]
|
||||
|
||||
style A fill:#ff9999
|
||||
style B fill:#99ccff
|
||||
style C fill:#99ff99
|
||||
B --> B1[代码覆盖率>80%]
|
||||
B --> B2[自动化执行]
|
||||
|
||||
C --> C1[API集成测试]
|
||||
C --> C2[数据库集成测试]
|
||||
|
||||
D --> D1[功能测试]
|
||||
D --> D2[性能测试]
|
||||
D --> D3[安全测试]
|
||||
|
||||
E --> E1[用户验收测试]
|
||||
E --> E2[业务流程验证]
|
||||
## 2. 测试环境
|
||||
|
||||
### 2.1 环境配置
|
||||
|
||||
| 环境类型 | 用途 | 配置 | 数据库 |
|
||||
|---------|------|------|--------|
|
||||
| 开发环境 | 开发调试 | 本地Docker | MySQL 8.0 |
|
||||
| 测试环境 | 功能测试 | 测试服务器 | MySQL 8.0 |
|
||||
| 预发布环境 | 集成测试 | 生产同配置 | MySQL 8.0 |
|
||||
| 生产环境 | 线上服务 | 高可用集群 | MySQL 8.0主从 |
|
||||
|
||||
### 2.2 测试数据管理
|
||||
|
||||
```yaml
|
||||
# 测试数据配置
|
||||
test_data:
|
||||
users:
|
||||
- username: "test_user_001"
|
||||
email: "test001@example.com"
|
||||
role: "user"
|
||||
- username: "test_admin_001"
|
||||
email: "admin001@example.com"
|
||||
role: "admin"
|
||||
|
||||
trips:
|
||||
- title: "测试旅行001"
|
||||
destination: "北京"
|
||||
start_date: "2024-06-01"
|
||||
end_date: "2024-06-07"
|
||||
|
||||
animals:
|
||||
- name: "测试动物001"
|
||||
type: "cat"
|
||||
location: "北京动物园"
|
||||
```
|
||||
|
||||
### 测试分层
|
||||
## 3. 测试计划
|
||||
|
||||
#### 1. 单元测试 (Unit Testing)
|
||||
- **目标**: 测试最小可测试单元
|
||||
- **工具**: Jest, Vitest, JUnit
|
||||
- **覆盖**: 函数、方法、组件
|
||||
### 3.1 测试阶段
|
||||
|
||||
#### 2. 集成测试 (Integration Testing)
|
||||
- **目标**: 测试模块间交互
|
||||
- **工具**: Supertest, TestContainers
|
||||
- **覆盖**: API接口、数据库交互
|
||||
```mermaid
|
||||
gantt
|
||||
title 测试计划时间线
|
||||
dateFormat YYYY-MM-DD
|
||||
section 单元测试
|
||||
后端单元测试 :ut1, 2024-03-01, 7d
|
||||
前端单元测试 :ut2, 2024-03-01, 7d
|
||||
|
||||
section 集成测试
|
||||
API集成测试 :it1, after ut1, 5d
|
||||
数据库集成测试 :it2, after ut1, 3d
|
||||
|
||||
section 系统测试
|
||||
功能测试 :st1, after it1, 10d
|
||||
性能测试 :st2, after it1, 7d
|
||||
安全测试 :st3, after it1, 5d
|
||||
|
||||
section 验收测试
|
||||
用户验收测试 :at1, after st1, 7d
|
||||
```
|
||||
|
||||
#### 3. 端到端测试 (E2E Testing)
|
||||
- **目标**: 测试完整用户流程
|
||||
- **工具**: Playwright, Cypress
|
||||
- **覆盖**: 关键业务流程
|
||||
### 3.2 测试用例设计
|
||||
|
||||
#### 3.2.1 后端API测试用例
|
||||
|
||||
```javascript
|
||||
// 用户注册接口测试用例
|
||||
describe('用户注册API', () => {
|
||||
test('正常注册流程', async () => {
|
||||
const userData = {
|
||||
username: 'testuser001',
|
||||
email: 'test@example.com',
|
||||
password: 'Test123456',
|
||||
phone: '13800138000'
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/auth/register')
|
||||
.send(userData)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.code).toBe(0);
|
||||
expect(response.body.data.user.username).toBe(userData.username);
|
||||
});
|
||||
|
||||
test('重复邮箱注册', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/auth/register')
|
||||
.send({
|
||||
username: 'testuser002',
|
||||
email: 'test@example.com', // 重复邮箱
|
||||
password: 'Test123456'
|
||||
})
|
||||
.expect(400);
|
||||
|
||||
expect(response.body.code).toBe(40001);
|
||||
expect(response.body.message).toContain('邮箱已存在');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
#### 3.2.2 小程序功能测试用例
|
||||
|
||||
```javascript
|
||||
// 小程序页面测试
|
||||
describe('旅行结伴页面', () => {
|
||||
test('页面正常加载', async () => {
|
||||
const page = await miniProgram.reLaunch('/pages/trip/list');
|
||||
await page.waitFor(2000);
|
||||
|
||||
const title = await page.$('.page-title');
|
||||
expect(await title.text()).toBe('旅行结伴');
|
||||
});
|
||||
|
||||
test('创建旅行结伴', async () => {
|
||||
const page = await miniProgram.navigateTo('/pages/trip/create');
|
||||
|
||||
await page.setData({
|
||||
'form.title': '测试旅行',
|
||||
'form.destination': '北京',
|
||||
'form.startDate': '2024-06-01',
|
||||
'form.endDate': '2024-06-07'
|
||||
});
|
||||
|
||||
await page.tap('.submit-btn');
|
||||
await page.waitFor(1000);
|
||||
|
||||
expect(page.path).toBe('/pages/trip/detail');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 4. 性能测试
|
||||
|
||||
### 4.1 性能指标
|
||||
|
||||
| 指标类型 | 目标值 | 测试方法 |
|
||||
|---------|--------|----------|
|
||||
| 接口响应时间 | < 500ms | JMeter压测 |
|
||||
| 页面加载时间 | < 2s | Lighthouse |
|
||||
| 并发用户数 | 1000+ | 压力测试 |
|
||||
| 数据库查询 | < 100ms | SQL性能分析 |
|
||||
| 内存使用率 | < 80% | 系统监控 |
|
||||
|
||||
### 4.2 JMeter压测脚本
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jmeterTestPlan version="1.2">
|
||||
<hashTree>
|
||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="解班客API压测">
|
||||
<elementProp name="TestPlan.arguments" elementType="Arguments" guiclass="ArgumentsPanel">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||
</TestPlan>
|
||||
|
||||
<hashTree>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="用户登录压测">
|
||||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
<stringProp name="LoopController.loops">100</stringProp>
|
||||
</elementProp>
|
||||
<stringProp name="ThreadGroup.num_threads">50</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">10</stringProp>
|
||||
</ThreadGroup>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</jmeterTestPlan>
|
||||
```
|
||||
|
||||
### 4.3 Artillery性能测试
|
||||
|
||||
```yaml
|
||||
# artillery-config.yml
|
||||
config:
|
||||
target: 'http://localhost:3000'
|
||||
phases:
|
||||
- duration: 60
|
||||
arrivalRate: 10
|
||||
- duration: 120
|
||||
arrivalRate: 50
|
||||
- duration: 60
|
||||
arrivalRate: 100
|
||||
|
||||
scenarios:
|
||||
- name: "用户注册登录流程"
|
||||
flow:
|
||||
- post:
|
||||
url: "/api/auth/register"
|
||||
json:
|
||||
username: "test_{{ $randomString() }}"
|
||||
email: "{{ $randomString() }}@test.com"
|
||||
password: "Test123456"
|
||||
- post:
|
||||
url: "/api/auth/login"
|
||||
json:
|
||||
email: "{{ email }}"
|
||||
password: "Test123456"
|
||||
```
|
||||
|
||||
## 5. 安全测试
|
||||
|
||||
### 5.1 安全测试范围
|
||||
|
||||
- **身份认证安全**:JWT令牌、密码加密
|
||||
- **授权控制**:角色权限、接口鉴权
|
||||
- **数据安全**:SQL注入、XSS攻击
|
||||
- **传输安全**:HTTPS、数据加密
|
||||
- **系统安全**:文件上传、敏感信息泄露
|
||||
|
||||
### 5.2 OWASP ZAP安全扫描
|
||||
|
||||
```yaml
|
||||
# zap-baseline-scan.yml
|
||||
version: '3'
|
||||
services:
|
||||
zap:
|
||||
image: owasp/zap2docker-stable
|
||||
command: zap-baseline.py -t http://host.docker.internal:3000 -r zap-report.html
|
||||
volumes:
|
||||
- ./reports:/zap/wrk/:rw
|
||||
```
|
||||
|
||||
### 5.3 安全测试用例
|
||||
|
||||
```javascript
|
||||
// SQL注入测试
|
||||
describe('SQL注入防护测试', () => {
|
||||
test('用户名SQL注入', async () => {
|
||||
const maliciousInput = "admin'; DROP TABLE users; --";
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send({
|
||||
username: maliciousInput,
|
||||
password: 'password'
|
||||
});
|
||||
|
||||
// 应该返回错误,而不是执行SQL
|
||||
expect(response.status).toBe(400);
|
||||
expect(response.body.message).toContain('参数格式错误');
|
||||
});
|
||||
});
|
||||
|
||||
// XSS攻击测试
|
||||
describe('XSS防护测试', () => {
|
||||
test('评论内容XSS过滤', async () => {
|
||||
const xssPayload = '<script>alert("XSS")</script>';
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/comments')
|
||||
.set('Authorization', `Bearer ${token}`)
|
||||
.send({
|
||||
content: xssPayload,
|
||||
tripId: 1
|
||||
});
|
||||
|
||||
expect(response.body.data.content).not.toContain('<script>');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 6. 测试报告
|
||||
|
||||
### 6.1 测试报告模板
|
||||
|
||||
```markdown
|
||||
# 解班客项目测试报告
|
||||
|
||||
## 测试概要
|
||||
- **测试版本**: v1.0.0
|
||||
- **测试时间**: 2024-03-01 ~ 2024-03-15
|
||||
- **测试环境**: 测试环境
|
||||
- **测试人员**: 测试团队
|
||||
|
||||
## 测试结果统计
|
||||
- **总用例数**: 500
|
||||
- **通过用例**: 485
|
||||
- **失败用例**: 15
|
||||
- **通过率**: 97%
|
||||
|
||||
## 缺陷统计
|
||||
- **严重缺陷**: 0
|
||||
- **一般缺陷**: 8
|
||||
- **轻微缺陷**: 7
|
||||
- **建议优化**: 12
|
||||
|
||||
## 性能测试结果
|
||||
- **平均响应时间**: 245ms
|
||||
- **最大并发用户**: 1200
|
||||
- **系统稳定性**: 99.8%
|
||||
|
||||
## 安全测试结果
|
||||
- **高危漏洞**: 0
|
||||
- **中危漏洞**: 2
|
||||
- **低危漏洞**: 5
|
||||
|
||||
## 测试结论
|
||||
系统整体质量良好,满足上线要求。
|
||||
```
|
||||
|
||||
### 6.2 自动化测试报告
|
||||
|
||||
```javascript
|
||||
// jest.config.js
|
||||
module.exports = {
|
||||
collectCoverage: true,
|
||||
coverageDirectory: 'coverage',
|
||||
coverageReporters: ['text', 'lcov', 'html'],
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
branches: 80,
|
||||
functions: 80,
|
||||
lines: 80,
|
||||
statements: 80
|
||||
}
|
||||
},
|
||||
reporters: [
|
||||
'default',
|
||||
['jest-html-reporters', {
|
||||
publicPath: './test-reports',
|
||||
filename: 'test-report.html'
|
||||
}]
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
## 7. 总结
|
||||
|
||||
### 7.1 测试策略总结
|
||||
- **全面覆盖**:从单元测试到端到端测试的完整覆盖
|
||||
- **自动化优先**:80%以上测试用例实现自动化
|
||||
- **持续集成**:集成到CI/CD流程中
|
||||
- **质量保证**:建立完善的质量门禁机制
|
||||
|
||||
### 7.2 测试工具链
|
||||
- **单元测试**:Jest, Vitest
|
||||
- **集成测试**:Supertest, TestContainers
|
||||
- **E2E测试**:Playwright, Cypress
|
||||
- **性能测试**:JMeter, Artillery
|
||||
- **安全测试**:OWASP ZAP, SonarQube
|
||||
- **测试管理**:TestRail, Jira
|
||||
|
||||
### 7.3 持续改进
|
||||
- 定期回顾测试策略和流程
|
||||
- 持续优化测试用例和自动化脚本
|
||||
- 加强团队测试技能培训
|
||||
- 建立测试最佳实践知识库
|
||||
|
||||
#### 4. 性能测试 (Performance Testing)
|
||||
- **目标**: 验证系统性能指标
|
||||
|
||||
426
docs/用户手册文档.md
Normal file
426
docs/用户手册文档.md
Normal file
@@ -0,0 +1,426 @@
|
||||
# 解班客用户手册文档
|
||||
|
||||
## 1. 文档概述
|
||||
|
||||
### 1.1 文档目的
|
||||
本文档为解班客平台的用户使用手册,包含小程序端用户指南和管理后台操作手册,帮助用户快速上手并充分利用平台功能。
|
||||
|
||||
### 1.2 适用对象
|
||||
- **普通用户**:使用小程序进行旅行结伴和动物认领的用户
|
||||
- **管理员**:使用管理后台进行平台管理的工作人员
|
||||
- **版主**:负责内容审核和用户管理的版主
|
||||
|
||||
### 1.3 文档结构
|
||||
```mermaid
|
||||
graph TB
|
||||
A[用户手册] --> B[小程序用户指南]
|
||||
A --> C[管理后台操作手册]
|
||||
|
||||
B --> B1[注册登录]
|
||||
B --> B2[旅行结伴]
|
||||
B --> B3[动物认领]
|
||||
B --> B4[个人中心]
|
||||
|
||||
C --> C1[系统管理]
|
||||
C --> C2[用户管理]
|
||||
C --> C3[内容管理]
|
||||
C --> C4[数据统计]
|
||||
```
|
||||
|
||||
## 2. 小程序用户指南
|
||||
|
||||
### 2.1 注册与登录
|
||||
|
||||
#### 2.1.1 首次使用
|
||||
1. **下载安装**
|
||||
- 微信搜索"解班客"小程序
|
||||
- 或扫描二维码进入小程序
|
||||
|
||||
2. **授权登录**
|
||||
- 点击"微信登录"按钮
|
||||
- 授权获取微信基本信息
|
||||
- 系统自动创建账户
|
||||
|
||||
3. **完善资料**
|
||||
- 设置昵称和头像
|
||||
- 填写个人简介
|
||||
- 设置隐私偏好
|
||||
|
||||
#### 2.1.2 登录流程
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 用户
|
||||
participant M as 小程序
|
||||
participant W as 微信
|
||||
participant S as 服务器
|
||||
|
||||
U->>M: 点击登录
|
||||
M->>W: 调用wx.login()
|
||||
W-->>M: 返回code
|
||||
M->>S: 发送code到后端
|
||||
S->>W: 验证code获取openid
|
||||
W-->>S: 返回用户信息
|
||||
S-->>M: 返回JWT令牌
|
||||
M-->>U: 登录成功
|
||||
```
|
||||
|
||||
### 2.2 旅行结伴功能
|
||||
|
||||
#### 2.2.1 发布结伴信息
|
||||
1. **进入发布页面**
|
||||
- 点击首页"+"按钮
|
||||
- 选择"发布结伴"
|
||||
|
||||
2. **填写基本信息**
|
||||
- **目的地**:选择或输入目的地
|
||||
- **出行时间**:选择出发和返回日期
|
||||
- **人数限制**:设置最大参与人数
|
||||
- **预算范围**:设置人均预算区间
|
||||
|
||||
3. **详细描述**
|
||||
- **行程安排**:详细描述行程计划
|
||||
- **住宿安排**:说明住宿方式和标准
|
||||
- **交通方式**:选择主要交通工具
|
||||
- **特殊要求**:其他注意事项
|
||||
|
||||
4. **上传图片**
|
||||
- 最多上传9张图片
|
||||
- 支持拍照或从相册选择
|
||||
- 系统自动压缩优化
|
||||
|
||||
#### 2.2.2 搜索结伴信息
|
||||
1. **搜索方式**
|
||||
- **关键词搜索**:输入目的地或关键词
|
||||
- **筛选搜索**:按时间、预算、人数筛选
|
||||
- **地图搜索**:在地图上查看附近结伴
|
||||
|
||||
2. **搜索结果**
|
||||
- 列表显示匹配的结伴信息
|
||||
- 支持按时间、热度、距离排序
|
||||
- 点击查看详细信息
|
||||
|
||||
#### 2.2.3 参与结伴
|
||||
1. **查看详情**
|
||||
- 浏览结伴详细信息
|
||||
- 查看发起人资料和评价
|
||||
- 了解已参与成员情况
|
||||
|
||||
2. **申请参与**
|
||||
- 点击"我要参与"按钮
|
||||
- 填写申请理由
|
||||
- 等待发起人审核
|
||||
|
||||
3. **沟通交流**
|
||||
- 加入结伴群聊
|
||||
- 与其他成员交流
|
||||
- 讨论行程细节
|
||||
|
||||
### 2.3 动物认领功能
|
||||
|
||||
#### 2.3.1 浏览动物信息
|
||||
1. **动物列表**
|
||||
- 首页显示推荐动物
|
||||
- 支持按类型、年龄、性别筛选
|
||||
- 查看动物基本信息和照片
|
||||
|
||||
2. **动物详情**
|
||||
- 查看动物详细资料
|
||||
- 了解健康状况和性格特点
|
||||
- 查看救助机构信息
|
||||
|
||||
#### 2.3.2 申请认领
|
||||
1. **认领申请**
|
||||
- 点击"申请认领"按钮
|
||||
- 填写个人信息和认领理由
|
||||
- 上传相关证明材料
|
||||
|
||||
2. **审核流程**
|
||||
```mermaid
|
||||
graph LR
|
||||
A[提交申请] --> B[初步审核]
|
||||
B --> C[实地考察]
|
||||
C --> D[最终审核]
|
||||
D --> E[认领成功]
|
||||
|
||||
B --> F[审核不通过]
|
||||
C --> F
|
||||
D --> F
|
||||
```
|
||||
|
||||
3. **认领后续**
|
||||
- 签署认领协议
|
||||
- 接受定期回访
|
||||
- 分享动物生活状态
|
||||
|
||||
### 2.4 个人中心
|
||||
|
||||
#### 2.4.1 个人资料管理
|
||||
1. **基本信息**
|
||||
- 修改昵称和头像
|
||||
- 更新个人简介
|
||||
- 设置联系方式
|
||||
|
||||
2. **认证信息**
|
||||
- 实名认证
|
||||
- 手机号验证
|
||||
- 身份证验证
|
||||
|
||||
#### 2.4.2 我的活动
|
||||
1. **我发布的**
|
||||
- 查看发布的结伴信息
|
||||
- 管理参与申请
|
||||
- 编辑或删除发布内容
|
||||
|
||||
2. **我参与的**
|
||||
- 查看参与的结伴活动
|
||||
- 查看申请状态
|
||||
- 退出结伴活动
|
||||
|
||||
3. **我认领的**
|
||||
- 查看认领的动物
|
||||
- 上传动物近况
|
||||
- 查看回访记录
|
||||
|
||||
#### 2.4.3 设置中心
|
||||
1. **隐私设置**
|
||||
- 个人信息可见性
|
||||
- 消息接收设置
|
||||
- 位置信息授权
|
||||
|
||||
2. **通知设置**
|
||||
- 系统通知开关
|
||||
- 消息推送设置
|
||||
- 免打扰时间设置
|
||||
|
||||
## 3. 管理后台操作手册
|
||||
|
||||
### 3.1 系统登录
|
||||
|
||||
#### 3.1.1 登录流程
|
||||
1. **访问后台**
|
||||
- 打开管理后台网址
|
||||
- 输入管理员账号密码
|
||||
- 完成验证码验证
|
||||
|
||||
2. **多因子认证**(如已启用)
|
||||
- 输入TOTP验证码
|
||||
- 或使用备用验证码
|
||||
- 验证通过后进入系统
|
||||
|
||||
#### 3.1.2 权限说明
|
||||
| 角色 | 权限范围 | 主要功能 |
|
||||
|------|----------|----------|
|
||||
| 超级管理员 | 全部权限 | 系统配置、用户管理、数据统计 |
|
||||
| 管理员 | 业务管理 | 内容审核、用户管理 |
|
||||
| 版主 | 内容管理 | 内容审核、举报处理 |
|
||||
| 客服 | 用户服务 | 用户咨询、问题处理 |
|
||||
|
||||
### 3.2 用户管理
|
||||
|
||||
#### 3.2.1 用户列表
|
||||
1. **查看用户**
|
||||
- 用户列表显示基本信息
|
||||
- 支持按注册时间、状态筛选
|
||||
- 搜索特定用户
|
||||
|
||||
2. **用户详情**
|
||||
- 查看用户完整资料
|
||||
- 查看用户活动记录
|
||||
- 查看举报和投诉记录
|
||||
|
||||
#### 3.2.2 用户操作
|
||||
1. **账户管理**
|
||||
- 冻结/解冻用户账户
|
||||
- 重置用户密码
|
||||
- 修改用户权限
|
||||
|
||||
2. **内容管理**
|
||||
- 查看用户发布内容
|
||||
- 删除违规内容
|
||||
- 设置内容可见性
|
||||
|
||||
### 3.3 内容管理
|
||||
|
||||
#### 3.3.1 结伴信息管理
|
||||
1. **内容审核**
|
||||
- 审核待发布的结伴信息
|
||||
- 检查内容合规性
|
||||
- 批准或拒绝发布
|
||||
|
||||
2. **内容监控**
|
||||
- 监控已发布内容
|
||||
- 处理用户举报
|
||||
- 删除违规内容
|
||||
|
||||
#### 3.3.2 动物信息管理
|
||||
1. **动物档案**
|
||||
- 添加新的待认领动物
|
||||
- 更新动物信息和状态
|
||||
- 管理动物照片和视频
|
||||
|
||||
2. **认领管理**
|
||||
- 审核认领申请
|
||||
- 跟踪认领进度
|
||||
- 管理认领记录
|
||||
|
||||
### 3.4 数据统计
|
||||
|
||||
#### 3.4.1 用户统计
|
||||
```mermaid
|
||||
graph TB
|
||||
A[用户统计] --> B[注册用户数]
|
||||
A --> C[活跃用户数]
|
||||
A --> D[用户增长趋势]
|
||||
A --> E[用户地域分布]
|
||||
|
||||
B --> B1[总注册数]
|
||||
B --> B2[今日新增]
|
||||
B --> B3[本月新增]
|
||||
|
||||
C --> C1[日活跃用户]
|
||||
C --> C2[月活跃用户]
|
||||
C --> C3[用户留存率]
|
||||
```
|
||||
|
||||
#### 3.4.2 业务统计
|
||||
1. **结伴统计**
|
||||
- 发布结伴数量
|
||||
- 成功结伴率
|
||||
- 热门目的地统计
|
||||
|
||||
2. **认领统计**
|
||||
- 待认领动物数量
|
||||
- 成功认领数量
|
||||
- 认领成功率
|
||||
|
||||
### 3.5 系统配置
|
||||
|
||||
#### 3.5.1 基础配置
|
||||
1. **系统参数**
|
||||
- 系统名称和Logo
|
||||
- 联系方式设置
|
||||
- 服务条款更新
|
||||
|
||||
2. **功能开关**
|
||||
- 新用户注册开关
|
||||
- 内容发布审核开关
|
||||
- 维护模式开关
|
||||
|
||||
#### 3.5.2 安全配置
|
||||
1. **登录安全**
|
||||
- 密码复杂度要求
|
||||
- 登录失败锁定策略
|
||||
- 会话超时设置
|
||||
|
||||
2. **内容安全**
|
||||
- 敏感词过滤
|
||||
- 图片审核设置
|
||||
- 举报处理流程
|
||||
|
||||
## 4. 常见问题解答
|
||||
|
||||
### 4.1 小程序使用问题
|
||||
|
||||
#### Q1: 为什么无法登录小程序?
|
||||
**A:** 可能的原因和解决方案:
|
||||
- 网络连接问题:检查网络连接
|
||||
- 微信版本过低:更新微信到最新版本
|
||||
- 小程序版本问题:删除小程序重新搜索进入
|
||||
- 账户被冻结:联系客服处理
|
||||
|
||||
#### Q2: 如何修改已发布的结伴信息?
|
||||
**A:** 操作步骤:
|
||||
1. 进入个人中心
|
||||
2. 点击"我发布的"
|
||||
3. 找到要修改的结伴信息
|
||||
4. 点击"编辑"按钮
|
||||
5. 修改后提交审核
|
||||
|
||||
#### Q3: 认领申请被拒绝怎么办?
|
||||
**A:** 处理方式:
|
||||
- 查看拒绝原因
|
||||
- 完善申请材料
|
||||
- 提升认领条件
|
||||
- 重新提交申请
|
||||
|
||||
### 4.2 管理后台问题
|
||||
|
||||
#### Q1: 忘记管理员密码怎么办?
|
||||
**A:** 解决方案:
|
||||
1. 点击登录页面"忘记密码"
|
||||
2. 输入管理员邮箱
|
||||
3. 查收重置密码邮件
|
||||
4. 按邮件指引重置密码
|
||||
|
||||
#### Q2: 如何批量处理用户举报?
|
||||
**A:** 操作步骤:
|
||||
1. 进入举报管理页面
|
||||
2. 使用筛选条件过滤举报
|
||||
3. 勾选要处理的举报
|
||||
4. 选择批量操作类型
|
||||
5. 确认执行批量操作
|
||||
|
||||
## 5. 联系支持
|
||||
|
||||
### 5.1 技术支持
|
||||
- **客服热线**:400-xxx-xxxx
|
||||
- **工作时间**:周一至周日 9:00-21:00
|
||||
- **邮箱支持**:support@jiebanke.com
|
||||
- **在线客服**:小程序内客服功能
|
||||
|
||||
### 5.2 意见反馈
|
||||
- **功能建议**:feedback@jiebanke.com
|
||||
- **问题报告**:bug@jiebanke.com
|
||||
- **合作咨询**:business@jiebanke.com
|
||||
|
||||
### 5.3 紧急联系
|
||||
- **安全问题**:security@jiebanke.com
|
||||
- **紧急故障**:emergency@jiebanke.com
|
||||
- **24小时热线**:400-xxx-9999
|
||||
|
||||
## 6. 更新记录
|
||||
|
||||
### 6.1 版本历史
|
||||
| 版本 | 发布日期 | 主要更新 |
|
||||
|------|----------|----------|
|
||||
| v1.0.0 | 2024-01-15 | 初始版本发布 |
|
||||
| v1.1.0 | 2024-02-01 | 新增动物认领功能 |
|
||||
| v1.2.0 | 2024-02-15 | 优化用户体验 |
|
||||
| v1.3.0 | 2024-03-01 | 新增管理后台功能 |
|
||||
|
||||
### 6.2 即将发布
|
||||
- **v1.4.0**:新增社区功能
|
||||
- **v1.5.0**:优化搜索算法
|
||||
- **v2.0.0**:全新UI设计
|
||||
|
||||
## 7. 附录
|
||||
|
||||
### 7.1 快捷键说明(管理后台)
|
||||
| 功能 | 快捷键 | 说明 |
|
||||
|------|--------|------|
|
||||
| 搜索 | Ctrl + F | 快速搜索 |
|
||||
| 保存 | Ctrl + S | 保存当前操作 |
|
||||
| 刷新 | F5 | 刷新页面 |
|
||||
| 返回 | Alt + ← | 返回上一页 |
|
||||
|
||||
### 7.2 状态码说明
|
||||
| 状态 | 说明 | 颜色标识 |
|
||||
|------|------|----------|
|
||||
| 待审核 | 内容等待审核 | 橙色 |
|
||||
| 已通过 | 审核通过 | 绿色 |
|
||||
| 已拒绝 | 审核拒绝 | 红色 |
|
||||
| 已下线 | 内容已下线 | 灰色 |
|
||||
|
||||
### 7.3 错误代码对照表
|
||||
| 错误代码 | 错误描述 | 解决方案 |
|
||||
|----------|----------|----------|
|
||||
| 10001 | 参数错误 | 检查输入参数 |
|
||||
| 10002 | 权限不足 | 联系管理员 |
|
||||
| 10003 | 资源不存在 | 刷新页面重试 |
|
||||
| 10004 | 操作频繁 | 稍后再试 |
|
||||
|
||||
---
|
||||
|
||||
**文档版本**:v1.0.0
|
||||
**最后更新**:2024-01-15
|
||||
**维护团队**:解班客技术团队
|
||||
1184
docs/管理后台开发文档.md
Normal file
1184
docs/管理后台开发文档.md
Normal file
File diff suppressed because it is too large
Load Diff
1946
docs/管理后台接口设计文档.md
Normal file
1946
docs/管理后台接口设计文档.md
Normal file
File diff suppressed because it is too large
Load Diff
2564
docs/管理后台架构文档.md
Normal file
2564
docs/管理后台架构文档.md
Normal file
File diff suppressed because it is too large
Load Diff
493
docs/管理后台需求文档.md
Normal file
493
docs/管理后台需求文档.md
Normal file
@@ -0,0 +1,493 @@
|
||||
# 解班客管理后台需求文档
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
### 1.1 系统定位
|
||||
管理后台系统是解班客平台的运营管理中心,为管理员、运营人员和客服人员提供全面的平台管理功能。系统采用现代化的Web界面设计,支持多角色权限管理,确保平台的高效运营。
|
||||
|
||||
### 1.2 核心目标
|
||||
- 提供直观易用的管理界面
|
||||
- 支持多角色权限管理
|
||||
- 实现高效的数据管理和分析
|
||||
- 保障平台安全稳定运行
|
||||
- 提升运营管理效率
|
||||
|
||||
### 1.3 技术架构
|
||||
- **开发框架**:Vue 3 + TypeScript
|
||||
- **UI组件库**:Element Plus
|
||||
- **状态管理**:Pinia
|
||||
- **路由管理**:Vue Router 4
|
||||
- **HTTP客户端**:Axios
|
||||
- **构建工具**:Vite
|
||||
|
||||
## 2. 用户角色与权限
|
||||
|
||||
### 2.1 角色定义
|
||||
#### 2.1.1 超级管理员
|
||||
- **权限范围**:系统所有功能的完全访问权限
|
||||
- **主要职责**:系统配置、用户管理、权限分配、安全监控
|
||||
- **操作权限**:创建、读取、更新、删除所有数据
|
||||
|
||||
#### 2.1.2 运营管理员
|
||||
- **权限范围**:业务运营相关功能的管理权限
|
||||
- **主要职责**:内容审核、活动管理、商家管理、数据分析
|
||||
- **操作权限**:业务数据的增删改查,内容审核权限
|
||||
|
||||
#### 2.1.3 客服人员
|
||||
- **权限范围**:用户服务相关功能的操作权限
|
||||
- **主要职责**:用户咨询处理、投诉处理、订单协调
|
||||
- **操作权限**:用户信息查看,订单状态修改,消息发送
|
||||
|
||||
#### 2.1.4 数据分析师
|
||||
- **权限范围**:数据查看和分析功能的访问权限
|
||||
- **主要职责**:数据统计、报表生成、趋势分析
|
||||
- **操作权限**:只读权限,数据导出权限
|
||||
|
||||
### 2.2 权限管理
|
||||
#### 2.2.1 菜单权限
|
||||
- 根据角色显示不同的菜单项
|
||||
- 支持动态菜单加载
|
||||
- 菜单权限的细粒度控制
|
||||
- 权限变更的实时生效
|
||||
|
||||
#### 2.2.2 操作权限
|
||||
- 页面级权限控制
|
||||
- 按钮级权限控制
|
||||
- 数据级权限控制
|
||||
- API接口权限验证
|
||||
|
||||
## 3. 功能模块需求
|
||||
|
||||
### 3.1 登录与认证模块
|
||||
#### 3.1.1 登录界面
|
||||
- **用户名密码登录**:支持管理员账号密码登录
|
||||
- **验证码验证**:图形验证码防止暴力破解
|
||||
- **记住登录状态**:可选择记住登录状态
|
||||
- **登录日志记录**:记录所有登录尝试和结果
|
||||
|
||||
#### 3.1.2 安全设置
|
||||
- **密码强度要求**:强制使用复杂密码
|
||||
- **登录失败锁定**:多次失败后临时锁定账户
|
||||
- **会话超时管理**:自动登出机制
|
||||
- **IP白名单**:限制登录IP地址范围
|
||||
|
||||
#### 3.1.3 双因素认证
|
||||
- **短信验证码**:支持短信二次验证
|
||||
- **邮箱验证码**:支持邮箱二次验证
|
||||
- **Google Authenticator**:支持TOTP验证
|
||||
- **安全密钥**:支持硬件安全密钥
|
||||
|
||||
### 3.2 仪表板模块
|
||||
#### 3.2.1 数据概览
|
||||
- **用户统计**:总用户数、新增用户、活跃用户
|
||||
- **活动统计**:总活动数、进行中活动、已完成活动
|
||||
- **交易统计**:总交易额、今日交易、交易趋势
|
||||
- **商家统计**:入驻商家数、活跃商家、商家收入
|
||||
|
||||
#### 3.2.2 实时监控
|
||||
- **系统状态**:服务器状态、数据库状态、缓存状态
|
||||
- **性能指标**:CPU使用率、内存使用率、磁盘使用率
|
||||
- **错误监控**:系统错误数量、错误类型分布
|
||||
- **用户活动**:实时在线用户数、用户行为热力图
|
||||
|
||||
#### 3.2.3 快捷操作
|
||||
- **待处理事项**:待审核内容、待处理投诉、待回复消息
|
||||
- **快速导航**:常用功能的快速入口
|
||||
- **最近操作**:最近执行的管理操作记录
|
||||
- **系统通知**:重要系统通知和提醒
|
||||
|
||||
### 3.3 用户管理模块
|
||||
#### 3.3.1 用户列表
|
||||
- **用户搜索**:支持多条件搜索用户
|
||||
- 用户ID、昵称、手机号、邮箱搜索
|
||||
- 注册时间范围筛选
|
||||
- 用户状态筛选(正常/冻结/注销)
|
||||
- 认证状态筛选(已认证/未认证)
|
||||
|
||||
- **用户信息展示**:
|
||||
- 基本信息:头像、昵称、手机号、注册时间
|
||||
- 状态信息:在线状态、认证状态、账户状态
|
||||
- 统计信息:活动参与数、消费金额、积分余额
|
||||
|
||||
#### 3.3.2 用户详情
|
||||
- **基本信息管理**:
|
||||
- 查看和编辑用户基本资料
|
||||
- 查看用户认证信息和证件
|
||||
- 管理用户标签和分组
|
||||
- 查看用户登录历史
|
||||
|
||||
- **账户管理**:
|
||||
- 账户状态控制(正常/冻结/注销)
|
||||
- 密码重置功能
|
||||
- 余额和积分管理
|
||||
- 权限设置(如发布活动权限)
|
||||
|
||||
- **行为记录**:
|
||||
- 用户操作日志
|
||||
- 活动参与记录
|
||||
- 交易记录
|
||||
- 投诉举报记录
|
||||
|
||||
#### 3.3.3 用户分析
|
||||
- **用户画像**:
|
||||
- 年龄分布、性别分布、地域分布
|
||||
- 兴趣偏好分析
|
||||
- 消费行为分析
|
||||
- 活跃度分析
|
||||
|
||||
- **用户分群**:
|
||||
- 自定义用户分群规则
|
||||
- 用户生命周期分析
|
||||
- 流失用户分析
|
||||
- 高价值用户识别
|
||||
|
||||
### 3.4 活动管理模块
|
||||
#### 3.4.1 活动列表
|
||||
- **活动搜索筛选**:
|
||||
- 活动标题、创建者搜索
|
||||
- 活动类型筛选
|
||||
- 活动状态筛选
|
||||
- 时间范围筛选
|
||||
- 地理位置筛选
|
||||
|
||||
- **活动信息展示**:
|
||||
- 活动基本信息:标题、类型、时间、地点
|
||||
- 参与情况:报名人数、参与人数、取消人数
|
||||
- 状态信息:审核状态、活动状态
|
||||
- 操作按钮:查看详情、编辑、删除、审核
|
||||
|
||||
#### 3.4.2 活动审核
|
||||
- **审核流程**:
|
||||
- 待审核活动列表
|
||||
- 活动详情查看
|
||||
- 审核意见填写
|
||||
- 审核结果处理(通过/拒绝/要求修改)
|
||||
|
||||
- **审核标准**:
|
||||
- 内容合规性检查
|
||||
- 信息完整性验证
|
||||
- 安全风险评估
|
||||
- 商业合理性判断
|
||||
|
||||
#### 3.4.3 活动监控
|
||||
- **活动状态监控**:
|
||||
- 活动进行状态实时监控
|
||||
- 异常活动预警
|
||||
- 活动取消处理
|
||||
- 纠纷处理
|
||||
|
||||
- **数据统计**:
|
||||
- 活动参与率统计
|
||||
- 活动满意度调查
|
||||
- 活动收入统计
|
||||
- 活动地域分布
|
||||
|
||||
### 3.5 商家管理模块
|
||||
#### 3.5.1 商家入驻管理
|
||||
- **入驻申请列表**:
|
||||
- 待审核申请展示
|
||||
- 申请信息详情查看
|
||||
- 资质文件查看和下载
|
||||
- 审核进度跟踪
|
||||
|
||||
- **审核流程**:
|
||||
- 资质审核:营业执照、相关许可证
|
||||
- 信息核实:联系方式、经营地址
|
||||
- 风险评估:信用记录、经营风险
|
||||
- 审核决策:通过/拒绝/补充材料
|
||||
|
||||
#### 3.5.2 商家信息管理
|
||||
- **商家档案**:
|
||||
- 基本信息:商家名称、类型、联系方式
|
||||
- 经营信息:经营范围、营业时间、服务区域
|
||||
- 资质信息:证照信息、有效期管理
|
||||
- 财务信息:保证金、分成比例、结算方式
|
||||
|
||||
- **商家状态管理**:
|
||||
- 状态控制:正常/暂停/关闭
|
||||
- 权限管理:发布权限、推广权限
|
||||
- 违规处理:警告、限制、封禁
|
||||
- 申诉处理:申诉受理、调查、结果反馈
|
||||
|
||||
#### 3.5.3 商家服务监控
|
||||
- **服务质量监控**:
|
||||
- 服务评分统计
|
||||
- 投诉处理记录
|
||||
- 服务响应时间
|
||||
- 订单完成率
|
||||
|
||||
- **经营数据分析**:
|
||||
- 销售数据统计
|
||||
- 收入趋势分析
|
||||
- 商品热销排行
|
||||
- 客户满意度分析
|
||||
|
||||
### 3.6 内容管理模块
|
||||
#### 3.6.1 内容审核
|
||||
- **待审核内容**:
|
||||
- 用户发布的动态内容
|
||||
- 活动描述和图片
|
||||
- 商家商品信息
|
||||
- 用户评价和反馈
|
||||
|
||||
- **审核工具**:
|
||||
- 内容违规检测
|
||||
- 图片内容识别
|
||||
- 敏感词过滤
|
||||
- 人工审核界面
|
||||
|
||||
#### 3.6.2 内容管理
|
||||
- **内容分类管理**:
|
||||
- 活动分类设置
|
||||
- 商品分类管理
|
||||
- 标签体系管理
|
||||
- 推荐内容设置
|
||||
|
||||
- **内容推荐**:
|
||||
- 首页推荐内容
|
||||
- 热门活动推荐
|
||||
- 优质商家推荐
|
||||
- 个性化推荐算法
|
||||
|
||||
### 3.7 订单管理模块
|
||||
#### 3.7.1 订单列表
|
||||
- **订单搜索**:
|
||||
- 订单号、用户信息搜索
|
||||
- 订单状态筛选
|
||||
- 时间范围筛选
|
||||
- 金额范围筛选
|
||||
- 商家筛选
|
||||
|
||||
- **订单信息展示**:
|
||||
- 订单基本信息:订单号、用户、商家、金额
|
||||
- 订单状态:待支付、已支付、已发货、已完成、已取消
|
||||
- 时间信息:下单时间、支付时间、发货时间
|
||||
- 操作按钮:查看详情、处理、退款
|
||||
|
||||
#### 3.7.2 订单处理
|
||||
- **订单详情**:
|
||||
- 完整订单信息查看
|
||||
- 支付信息和流水
|
||||
- 物流信息跟踪
|
||||
- 用户和商家沟通记录
|
||||
|
||||
- **异常订单处理**:
|
||||
- 支付异常处理
|
||||
- 发货延迟处理
|
||||
- 退款申请审核
|
||||
- 纠纷调解
|
||||
|
||||
#### 3.7.3 财务管理
|
||||
- **收入统计**:
|
||||
- 平台总收入统计
|
||||
- 分类收入统计
|
||||
- 商家分成统计
|
||||
- 退款统计
|
||||
|
||||
- **结算管理**:
|
||||
- 商家结算周期设置
|
||||
- 结算单生成和审核
|
||||
- 结算状态跟踪
|
||||
- 财务对账
|
||||
|
||||
### 3.8 消息管理模块
|
||||
#### 3.8.1 消息中心
|
||||
- **消息列表**:
|
||||
- 用户消息查看
|
||||
- 系统通知管理
|
||||
- 客服对话记录
|
||||
- 群发消息记录
|
||||
|
||||
- **消息发送**:
|
||||
- 单用户消息发送
|
||||
- 批量消息发送
|
||||
- 定时消息发送
|
||||
- 模板消息管理
|
||||
|
||||
#### 3.8.2 客服系统
|
||||
- **在线客服**:
|
||||
- 实时客服对话
|
||||
- 客服工作台
|
||||
- 对话记录管理
|
||||
- 客服绩效统计
|
||||
|
||||
- **工单系统**:
|
||||
- 工单创建和分配
|
||||
- 工单处理流程
|
||||
- 工单状态跟踪
|
||||
- 工单统计分析
|
||||
|
||||
### 3.9 数据统计模块
|
||||
#### 3.9.1 业务数据统计
|
||||
- **用户数据**:
|
||||
- 用户增长趋势
|
||||
- 用户活跃度分析
|
||||
- 用户留存率分析
|
||||
- 用户价值分析
|
||||
|
||||
- **业务数据**:
|
||||
- 活动数据统计
|
||||
- 交易数据分析
|
||||
- 商家经营数据
|
||||
- 收入利润分析
|
||||
|
||||
#### 3.9.2 报表管理
|
||||
- **预设报表**:
|
||||
- 日报、周报、月报
|
||||
- 用户报表、业务报表、财务报表
|
||||
- 商家报表、活动报表
|
||||
|
||||
- **自定义报表**:
|
||||
- 报表模板设计
|
||||
- 数据源配置
|
||||
- 图表类型选择
|
||||
- 报表导出功能
|
||||
|
||||
### 3.10 系统管理模块
|
||||
#### 3.10.1 系统配置
|
||||
- **基础配置**:
|
||||
- 系统参数设置
|
||||
- 业务规则配置
|
||||
- 第三方服务配置
|
||||
- 安全策略设置
|
||||
|
||||
- **功能开关**:
|
||||
- 功能模块开关
|
||||
- 实验性功能控制
|
||||
- 维护模式设置
|
||||
- 紧急停服功能
|
||||
|
||||
#### 3.10.2 日志管理
|
||||
- **操作日志**:
|
||||
- 管理员操作记录
|
||||
- 用户行为日志
|
||||
- 系统事件日志
|
||||
- 安全事件日志
|
||||
|
||||
- **日志分析**:
|
||||
- 日志搜索和筛选
|
||||
- 异常日志监控
|
||||
- 日志统计分析
|
||||
- 日志导出功能
|
||||
|
||||
## 4. 界面设计需求
|
||||
|
||||
### 4.1 整体设计风格
|
||||
#### 4.1.1 设计原则
|
||||
- **简洁明了**:界面简洁,信息层次清晰
|
||||
- **一致性**:保持设计风格和交互的一致性
|
||||
- **易用性**:操作简单直观,学习成本低
|
||||
- **专业性**:体现管理系统的专业性和权威性
|
||||
|
||||
#### 4.1.2 视觉风格
|
||||
- **色彩方案**:以蓝色为主色调,体现专业和信任
|
||||
- **字体规范**:使用清晰易读的字体,合理的字号层级
|
||||
- **图标系统**:统一的图标风格,语义明确
|
||||
- **布局规范**:合理的间距和对齐,良好的视觉节奏
|
||||
|
||||
### 4.2 布局设计
|
||||
#### 4.2.1 整体布局
|
||||
- **顶部导航栏**:Logo、用户信息、系统通知、退出登录
|
||||
- **左侧菜单栏**:功能模块导航,支持折叠展开
|
||||
- **主内容区域**:页面主要内容展示区域
|
||||
- **底部信息栏**:版权信息、系统状态、帮助链接
|
||||
|
||||
#### 4.2.2 响应式设计
|
||||
- **桌面端适配**:1920px、1440px、1366px等常见分辨率
|
||||
- **平板端适配**:iPad等平板设备的横竖屏适配
|
||||
- **移动端适配**:手机端的基本功能访问支持
|
||||
- **弹性布局**:使用Flex和Grid布局,适应不同屏幕
|
||||
|
||||
### 4.3 交互设计
|
||||
#### 4.3.1 导航交互
|
||||
- **面包屑导航**:显示当前页面位置,支持快速返回
|
||||
- **标签页导航**:支持多标签页切换,提高操作效率
|
||||
- **搜索功能**:全局搜索和模块内搜索
|
||||
- **快捷键支持**:常用操作的快捷键支持
|
||||
|
||||
#### 4.3.2 数据交互
|
||||
- **表格操作**:排序、筛选、分页、批量操作
|
||||
- **表单设计**:清晰的表单布局,实时验证反馈
|
||||
- **弹窗设计**:模态框、抽屉、气泡等不同场景的弹窗
|
||||
- **加载状态**:加载动画、骨架屏、进度条等
|
||||
|
||||
### 4.4 组件设计
|
||||
#### 4.4.1 基础组件
|
||||
- **按钮组件**:不同类型和状态的按钮
|
||||
- **表单组件**:输入框、选择器、日期选择器等
|
||||
- **数据展示组件**:表格、卡片、列表等
|
||||
- **反馈组件**:消息提示、确认框、通知等
|
||||
|
||||
#### 4.4.2 业务组件
|
||||
- **用户选择器**:用户搜索和选择组件
|
||||
- **时间范围选择器**:日期时间范围选择
|
||||
- **地址选择器**:省市区地址选择
|
||||
- **富文本编辑器**:内容编辑和发布
|
||||
|
||||
## 5. 性能需求
|
||||
|
||||
### 5.1 响应性能
|
||||
- **页面加载时间**:首屏加载时间 < 2秒
|
||||
- **接口响应时间**:API接口响应时间 < 1秒
|
||||
- **操作响应时间**:用户操作响应时间 < 500ms
|
||||
- **大数据处理**:大量数据的分页和虚拟滚动
|
||||
|
||||
### 5.2 并发性能
|
||||
- **同时在线用户**:支持100+管理员同时在线
|
||||
- **并发操作**:支持多用户同时操作不同模块
|
||||
- **数据一致性**:确保并发操作的数据一致性
|
||||
- **冲突处理**:合理处理并发操作冲突
|
||||
|
||||
### 5.3 稳定性要求
|
||||
- **系统可用性**:99.9%的系统可用性
|
||||
- **错误处理**:完善的错误处理和恢复机制
|
||||
- **数据备份**:重要操作的数据备份和恢复
|
||||
- **容错能力**:系统异常时的容错和降级处理
|
||||
|
||||
## 6. 安全需求
|
||||
|
||||
### 6.1 访问安全
|
||||
- **身份认证**:强制登录验证,支持多因素认证
|
||||
- **权限控制**:细粒度的权限控制和验证
|
||||
- **会话管理**:安全的会话管理和超时控制
|
||||
- **IP限制**:支持IP白名单和黑名单
|
||||
|
||||
### 6.2 数据安全
|
||||
- **数据加密**:敏感数据的加密传输和存储
|
||||
- **操作审计**:完整的操作日志和审计跟踪
|
||||
- **数据脱敏**:敏感信息的脱敏显示
|
||||
- **备份恢复**:定期数据备份和恢复机制
|
||||
|
||||
### 6.3 系统安全
|
||||
- **XSS防护**:防止跨站脚本攻击
|
||||
- **CSRF防护**:防止跨站请求伪造
|
||||
- **SQL注入防护**:防止SQL注入攻击
|
||||
- **文件上传安全**:文件类型和大小限制
|
||||
|
||||
## 7. 兼容性需求
|
||||
|
||||
### 7.1 浏览器兼容
|
||||
- **Chrome**:Chrome 80+
|
||||
- **Firefox**:Firefox 75+
|
||||
- **Safari**:Safari 13+
|
||||
- **Edge**:Edge 80+
|
||||
|
||||
### 7.2 设备兼容
|
||||
- **桌面设备**:Windows、macOS、Linux
|
||||
- **平板设备**:iPad、Android平板
|
||||
- **移动设备**:基本功能的移动端支持
|
||||
- **分辨率适配**:1366x768 到 4K分辨率
|
||||
|
||||
## 8. 维护需求
|
||||
|
||||
### 8.1 系统维护
|
||||
- **版本更新**:支持在线更新和回滚
|
||||
- **配置管理**:动态配置更新,无需重启
|
||||
- **监控告警**:系统状态监控和异常告警
|
||||
- **性能优化**:持续的性能监控和优化
|
||||
|
||||
### 8.2 内容维护
|
||||
- **数据清理**:定期清理过期和无效数据
|
||||
- **缓存管理**:缓存更新和清理机制
|
||||
- **日志管理**:日志轮转和归档机制
|
||||
- **备份策略**:定期备份和恢复测试
|
||||
@@ -1,783 +0,0 @@
|
||||
# 管理员后台系统API文档
|
||||
|
||||
## 概述
|
||||
|
||||
管理员后台系统提供了完整的系统管理功能,包括用户管理、动物管理、数据统计、系统监控等功能,支持管理员对整个平台进行全面的管理和监控。
|
||||
|
||||
## 基础信息
|
||||
|
||||
- **基础URL**: `/api/v1/admin`
|
||||
- **认证方式**: Bearer Token
|
||||
- **数据格式**: JSON
|
||||
- **字符编码**: UTF-8
|
||||
- **权限要求**: 管理员权限(admin 或 super_admin)
|
||||
|
||||
## 权限说明
|
||||
|
||||
### 角色类型
|
||||
- **super_admin**: 超级管理员,拥有所有权限
|
||||
- **admin**: 普通管理员,拥有大部分管理权限
|
||||
- **manager**: 部门经理,拥有部分管理权限
|
||||
|
||||
### 权限控制
|
||||
所有管理员接口都需要通过Bearer Token进行身份验证,并根据用户角色进行权限控制。
|
||||
|
||||
## 用户管理模块
|
||||
|
||||
### 1. 获取用户列表
|
||||
|
||||
**接口地址**: `GET /admin/users`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"keyword": "搜索关键词",
|
||||
"user_type": "farmer",
|
||||
"status": "active",
|
||||
"start_date": "2024-01-01",
|
||||
"end_date": "2024-12-31",
|
||||
"sort_by": "created_at",
|
||||
"sort_order": "desc"
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "获取成功",
|
||||
"data": {
|
||||
"users": [
|
||||
{
|
||||
"id": 1,
|
||||
"username": "张三",
|
||||
"email": "zhangsan@example.com",
|
||||
"phone": "13800138001",
|
||||
"user_type": "farmer",
|
||||
"status": "active",
|
||||
"level": "bronze",
|
||||
"points": 1200,
|
||||
"travel_count": 5,
|
||||
"claim_count": 2,
|
||||
"last_login_at": "2024-12-01T10:30:00.000Z",
|
||||
"created_at": "2024-01-15T08:00:00.000Z"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"current_page": 1,
|
||||
"per_page": 10,
|
||||
"total": 1000,
|
||||
"total_pages": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 获取用户详情
|
||||
|
||||
**接口地址**: `GET /admin/users/{user_id}`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "获取成功",
|
||||
"data": {
|
||||
"user": {
|
||||
"id": 1,
|
||||
"username": "张三",
|
||||
"email": "zhangsan@example.com",
|
||||
"phone": "13800138001",
|
||||
"user_type": "farmer",
|
||||
"status": "active",
|
||||
"level": "bronze",
|
||||
"points": 1200,
|
||||
"profile": {
|
||||
"real_name": "张三",
|
||||
"avatar": "/uploads/avatars/user1.jpg",
|
||||
"bio": "热爱农业的城市青年"
|
||||
}
|
||||
},
|
||||
"statistics": {
|
||||
"travel_count": 5,
|
||||
"claim_count": 2,
|
||||
"order_count": 8,
|
||||
"total_spent": 2500.00
|
||||
},
|
||||
"recentActivities": [
|
||||
{
|
||||
"type": "travel_created",
|
||||
"description": "创建了新的旅行计划",
|
||||
"created_at": "2024-12-01T10:00:00.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 更新用户状态
|
||||
|
||||
**接口地址**: `PUT /admin/users/{user_id}/status`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"status": "suspended",
|
||||
"reason": "违反平台规定"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 批量更新用户状态
|
||||
|
||||
**接口地址**: `PUT /admin/users/batch/status`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"user_ids": [1, 2, 3],
|
||||
"status": "suspended",
|
||||
"reason": "批量处理违规用户"
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 获取用户统计信息
|
||||
|
||||
**接口地址**: `GET /admin/users/statistics`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "获取成功",
|
||||
"data": {
|
||||
"totalStats": {
|
||||
"total_users": 10000,
|
||||
"active_users": 8500,
|
||||
"new_users_today": 50,
|
||||
"new_users_week": 300
|
||||
},
|
||||
"typeStats": [
|
||||
{
|
||||
"user_type": "farmer",
|
||||
"count": 6000,
|
||||
"percentage": 60.0
|
||||
},
|
||||
{
|
||||
"user_type": "merchant",
|
||||
"count": 4000,
|
||||
"percentage": 40.0
|
||||
}
|
||||
],
|
||||
"levelStats": [
|
||||
{
|
||||
"level": "bronze",
|
||||
"count": 5000,
|
||||
"avg_points": 800
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 导出用户数据
|
||||
|
||||
**接口地址**: `GET /admin/users/export`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"format": "csv",
|
||||
"user_type": "farmer",
|
||||
"status": "active",
|
||||
"start_date": "2024-01-01",
|
||||
"end_date": "2024-12-31"
|
||||
}
|
||||
```
|
||||
|
||||
## 动物管理模块
|
||||
|
||||
### 1. 获取动物列表
|
||||
|
||||
**接口地址**: `GET /admin/animals`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"keyword": "小白",
|
||||
"species": "dog",
|
||||
"status": "available",
|
||||
"merchant_id": 1,
|
||||
"start_date": "2024-01-01",
|
||||
"end_date": "2024-12-31",
|
||||
"sort_by": "created_at",
|
||||
"sort_order": "desc"
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "获取成功",
|
||||
"data": {
|
||||
"animals": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "小白",
|
||||
"species": "dog",
|
||||
"breed": "金毛",
|
||||
"age": 12,
|
||||
"gender": "male",
|
||||
"price": 1200.00,
|
||||
"status": "available",
|
||||
"merchant_id": 1,
|
||||
"merchant_name": "阳光农场",
|
||||
"claim_count": 3,
|
||||
"created_at": "2024-01-15T08:00:00.000Z"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"current_page": 1,
|
||||
"per_page": 10,
|
||||
"total": 500,
|
||||
"total_pages": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 获取动物详情
|
||||
|
||||
**接口地址**: `GET /admin/animals/{animal_id}`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "获取成功",
|
||||
"data": {
|
||||
"animal": {
|
||||
"id": 1,
|
||||
"name": "小白",
|
||||
"species": "dog",
|
||||
"breed": "金毛",
|
||||
"age": 12,
|
||||
"gender": "male",
|
||||
"price": 1200.00,
|
||||
"status": "available",
|
||||
"description": "温顺可爱的金毛犬",
|
||||
"images": ["/uploads/animals/dog1.jpg"],
|
||||
"merchant_name": "阳光农场"
|
||||
},
|
||||
"claimStats": {
|
||||
"total_claims": 5,
|
||||
"pending_claims": 1,
|
||||
"approved_claims": 3,
|
||||
"rejected_claims": 1
|
||||
},
|
||||
"recentClaims": [
|
||||
{
|
||||
"id": 1,
|
||||
"user_name": "张三",
|
||||
"status": "approved",
|
||||
"created_at": "2024-12-01T10:00:00.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 更新动物状态
|
||||
|
||||
**接口地址**: `PUT /admin/animals/{animal_id}/status`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"status": "unavailable",
|
||||
"reason": "动物健康检查"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 获取动物统计信息
|
||||
|
||||
**接口地址**: `GET /admin/animals/statistics`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "获取成功",
|
||||
"data": {
|
||||
"totalStats": {
|
||||
"total_animals": 500,
|
||||
"available_animals": 300,
|
||||
"claimed_animals": 150,
|
||||
"total_claims": 800,
|
||||
"avg_price": 1500.00
|
||||
},
|
||||
"speciesStats": [
|
||||
{
|
||||
"species": "dog",
|
||||
"count": 200,
|
||||
"avg_price": 1200.00
|
||||
}
|
||||
],
|
||||
"monthlyTrend": [
|
||||
{
|
||||
"month": "2024-12",
|
||||
"new_animals": 20,
|
||||
"new_claims": 35
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 数据统计模块
|
||||
|
||||
### 1. 获取系统概览统计
|
||||
|
||||
**接口地址**: `GET /admin/statistics/overview`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"users": {
|
||||
"total_users": 10000,
|
||||
"active_users": 8500,
|
||||
"new_users_today": 50,
|
||||
"new_users_week": 300
|
||||
},
|
||||
"travels": {
|
||||
"total_travels": 2000,
|
||||
"published_travels": 1500,
|
||||
"new_travels_today": 10
|
||||
},
|
||||
"animals": {
|
||||
"total_animals": 500,
|
||||
"available_animals": 300,
|
||||
"claimed_animals": 150
|
||||
},
|
||||
"orders": {
|
||||
"total_orders": 5000,
|
||||
"completed_orders": 4500,
|
||||
"total_revenue": 500000.00
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 获取用户增长趋势
|
||||
|
||||
**接口地址**: `GET /admin/statistics/user-growth`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"period": "30d"
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"period": "30d",
|
||||
"trendData": [
|
||||
{
|
||||
"date": "2024-12-01",
|
||||
"new_users": 25,
|
||||
"cumulative_users": 9975
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 获取业务数据统计
|
||||
|
||||
**接口地址**: `GET /admin/statistics/business`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"period": "30d"
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"period": "30d",
|
||||
"travelStats": [
|
||||
{
|
||||
"date": "2024-12-01",
|
||||
"new_travels": 5,
|
||||
"published_travels": 4,
|
||||
"matched_travels": 3
|
||||
}
|
||||
],
|
||||
"claimStats": [
|
||||
{
|
||||
"date": "2024-12-01",
|
||||
"new_claims": 8,
|
||||
"approved_claims": 6,
|
||||
"rejected_claims": 1
|
||||
}
|
||||
],
|
||||
"orderStats": [
|
||||
{
|
||||
"date": "2024-12-01",
|
||||
"new_orders": 15,
|
||||
"completed_orders": 12,
|
||||
"daily_revenue": 2500.00
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 获取地域分布统计
|
||||
|
||||
**接口地址**: `GET /admin/statistics/geographic`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"userDistribution": [
|
||||
{
|
||||
"province": "北京市",
|
||||
"city": "北京市",
|
||||
"user_count": 1500
|
||||
}
|
||||
],
|
||||
"provinceStats": [
|
||||
{
|
||||
"province": "北京市",
|
||||
"user_count": 1500,
|
||||
"farmer_count": 900,
|
||||
"merchant_count": 600
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 获取用户行为分析
|
||||
|
||||
**接口地址**: `GET /admin/statistics/user-behavior`
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"activityStats": [
|
||||
{
|
||||
"activity_level": "high",
|
||||
"user_count": 2000
|
||||
}
|
||||
],
|
||||
"levelDistribution": [
|
||||
{
|
||||
"level": "bronze",
|
||||
"user_count": 5000,
|
||||
"avg_points": 800,
|
||||
"avg_travel_count": 2.5,
|
||||
"avg_claim_count": 1.2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 获取收入统计
|
||||
|
||||
**接口地址**: `GET /admin/statistics/revenue`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"period": "30d"
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"period": "30d",
|
||||
"revenueTrend": [
|
||||
{
|
||||
"date": "2024-12-01",
|
||||
"daily_revenue": 2500.00,
|
||||
"completed_orders": 12,
|
||||
"total_orders": 15
|
||||
}
|
||||
],
|
||||
"revenueSource": [
|
||||
{
|
||||
"order_type": "travel",
|
||||
"order_count": 800,
|
||||
"total_revenue": 120000.00,
|
||||
"avg_order_value": 150.00
|
||||
}
|
||||
],
|
||||
"paymentMethodStats": [
|
||||
{
|
||||
"payment_method": "wechat",
|
||||
"order_count": 3000,
|
||||
"total_amount": 300000.00
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7. 导出统计报告
|
||||
|
||||
**接口地址**: `GET /admin/statistics/export`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"reportType": "overview",
|
||||
"period": "30d",
|
||||
"format": "csv"
|
||||
}
|
||||
```
|
||||
|
||||
## 错误码说明
|
||||
|
||||
| 错误码 | 说明 |
|
||||
|--------|------|
|
||||
| 200 | 请求成功 |
|
||||
| 400 | 参数错误 |
|
||||
| 401 | 未授权,需要登录 |
|
||||
| 403 | 权限不足 |
|
||||
| 404 | 资源不存在 |
|
||||
| 422 | 参数验证失败 |
|
||||
| 500 | 服务器内部错误 |
|
||||
|
||||
## 状态说明
|
||||
|
||||
### 用户状态
|
||||
- **active**: 正常状态
|
||||
- **suspended**: 已暂停
|
||||
- **banned**: 已封禁
|
||||
- **inactive**: 未激活
|
||||
|
||||
### 动物状态
|
||||
- **available**: 可认领
|
||||
- **claimed**: 已认领
|
||||
- **unavailable**: 不可认领
|
||||
|
||||
### 认领状态
|
||||
- **pending**: 待审核
|
||||
- **approved**: 已通过
|
||||
- **rejected**: 已拒绝
|
||||
- **cancelled**: 已取消
|
||||
|
||||
## 业务规则
|
||||
|
||||
### 用户管理规则
|
||||
1. 只有超级管理员可以创建和删除管理员账户
|
||||
2. 普通管理员可以管理普通用户,但不能管理其他管理员
|
||||
3. 用户状态变更需要记录操作原因和操作人
|
||||
4. 批量操作有数量限制,单次最多处理100个用户
|
||||
|
||||
### 动物管理规则
|
||||
1. 动物状态变更需要记录操作原因
|
||||
2. 已有认领申请的动物不能直接删除
|
||||
3. 动物价格修改需要管理员审核
|
||||
4. 动物图片上传有格式和大小限制
|
||||
|
||||
### 数据统计规则
|
||||
1. 统计数据每小时更新一次
|
||||
2. 导出功能有频率限制,每个管理员每天最多导出10次
|
||||
3. 敏感数据需要特殊权限才能查看
|
||||
4. 历史数据保留期限为2年
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **权限控制**: 所有接口都需要管理员权限,请确保在请求头中包含有效的Bearer Token
|
||||
2. **参数验证**: 请求参数会进行严格验证,确保传入正确的数据类型和格式
|
||||
3. **频率限制**: 部分接口有频率限制,请合理控制请求频率
|
||||
4. **数据安全**: 敏感数据会进行脱敏处理,完整数据需要特殊权限
|
||||
5. **操作日志**: 所有管理操作都会记录日志,便于审计和追踪
|
||||
|
||||
## 集成示例
|
||||
|
||||
### JavaScript示例
|
||||
|
||||
```javascript
|
||||
// 获取用户列表
|
||||
async function getUserList(page = 1, limit = 10) {
|
||||
try {
|
||||
const response = await fetch('/api/v1/admin/users?' + new URLSearchParams({
|
||||
page,
|
||||
limit,
|
||||
sort_by: 'created_at',
|
||||
sort_order: 'desc'
|
||||
}), {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
console.log('用户列表:', result.data.users);
|
||||
return result.data;
|
||||
} else {
|
||||
throw new Error(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取用户列表失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新用户状态
|
||||
async function updateUserStatus(userId, status, reason) {
|
||||
try {
|
||||
const response = await fetch(`/api/v1/admin/users/${userId}/status`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
status,
|
||||
reason
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
console.log('用户状态更新成功');
|
||||
return result;
|
||||
} else {
|
||||
throw new Error(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('更新用户状态失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取系统统计数据
|
||||
async function getSystemOverview() {
|
||||
try {
|
||||
const response = await fetch('/api/v1/admin/statistics/overview', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
console.log('系统概览:', result.data);
|
||||
return result.data;
|
||||
} else {
|
||||
throw new Error(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取系统统计失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Python示例
|
||||
|
||||
```python
|
||||
import requests
|
||||
import json
|
||||
|
||||
class AdminAPI:
|
||||
def __init__(self, base_url, token):
|
||||
self.base_url = base_url
|
||||
self.headers = {
|
||||
'Authorization': f'Bearer {token}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
def get_user_list(self, page=1, limit=10, **kwargs):
|
||||
"""获取用户列表"""
|
||||
params = {'page': page, 'limit': limit, **kwargs}
|
||||
response = requests.get(
|
||||
f'{self.base_url}/admin/users',
|
||||
headers=self.headers,
|
||||
params=params
|
||||
)
|
||||
return response.json()
|
||||
|
||||
def update_user_status(self, user_id, status, reason=None):
|
||||
"""更新用户状态"""
|
||||
data = {'status': status}
|
||||
if reason:
|
||||
data['reason'] = reason
|
||||
|
||||
response = requests.put(
|
||||
f'{self.base_url}/admin/users/{user_id}/status',
|
||||
headers=self.headers,
|
||||
json=data
|
||||
)
|
||||
return response.json()
|
||||
|
||||
def get_system_overview(self):
|
||||
"""获取系统概览"""
|
||||
response = requests.get(
|
||||
f'{self.base_url}/admin/statistics/overview',
|
||||
headers=self.headers
|
||||
)
|
||||
return response.json()
|
||||
|
||||
# 使用示例
|
||||
api = AdminAPI('https://api.example.com/api/v1', 'your_token_here')
|
||||
|
||||
# 获取用户列表
|
||||
users = api.get_user_list(page=1, limit=20, user_type='farmer')
|
||||
print(f"获取到 {len(users['data']['users'])} 个用户")
|
||||
|
||||
# 更新用户状态
|
||||
result = api.update_user_status(1, 'suspended', '违反平台规定')
|
||||
if result['success']:
|
||||
print("用户状态更新成功")
|
||||
|
||||
# 获取系统统计
|
||||
overview = api.get_system_overview()
|
||||
print(f"系统用户总数: {overview['data']['users']['total_users']}")
|
||||
```
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.0.0 (2024-12-01)
|
||||
- 初始版本发布
|
||||
- 实现用户管理基础功能
|
||||
- 实现动物管理基础功能
|
||||
- 实现数据统计基础功能
|
||||
|
||||
### v1.1.0 (计划中)
|
||||
- 增加订单管理功能
|
||||
- 增加商家管理功能
|
||||
- 增加系统配置管理
|
||||
- 优化统计报表功能
|
||||
527
docs/系统架构文档.md
527
docs/系统架构文档.md
@@ -1,527 +0,0 @@
|
||||
# 🏗️ 结伴客系统架构文档
|
||||
|
||||
## 📋 项目概述
|
||||
|
||||
结伴客是一个综合性的社交旅行平台,采用现代化的微服务架构设计,包含后台管理系统、微信小程序和官方网站三个主要模块。系统支持结伴旅行、动物认领、商家服务等核心业务功能。
|
||||
|
||||
## 🎯 技术选型
|
||||
|
||||
### 前端技术栈
|
||||
|
||||
#### 微信小程序
|
||||
- **开发框架**:原生微信小程序
|
||||
- **UI组件库**:Vant Weapp
|
||||
- **状态管理**:原生状态管理
|
||||
- **网络请求**:wx.request封装
|
||||
- **构建工具**:微信开发者工具
|
||||
|
||||
#### 后台管理系统
|
||||
- **开发框架**:Vue 3 + TypeScript
|
||||
- **UI组件库**:Element Plus
|
||||
- **状态管理**:Pinia
|
||||
- **路由管理**:Vue Router 4
|
||||
- **HTTP客户端**:Axios
|
||||
- **构建工具**:Vite
|
||||
|
||||
#### 官方网站
|
||||
- **开发框架**:Vue 3 + JavaScript
|
||||
- **UI框架**:自定义CSS + 响应式设计
|
||||
- **路由管理**:Vue Router
|
||||
- **构建工具**:Vite
|
||||
- **SEO优化**:Vue Meta
|
||||
|
||||
### 后端技术栈
|
||||
|
||||
#### Node.js版本(主要)
|
||||
- **运行环境**:Node.js 16.x+
|
||||
- **Web框架**:Express.js
|
||||
- **数据库ORM**:Sequelize
|
||||
- **认证授权**:JWT + bcrypt
|
||||
- **参数验证**:Joi
|
||||
- **日志管理**:Winston
|
||||
- **进程管理**:PM2
|
||||
|
||||
#### Java微服务版本(备选)
|
||||
- **开发框架**:Spring Boot 2.7+
|
||||
- **微服务框架**:Spring Cloud
|
||||
- **数据库ORM**:MyBatis Plus
|
||||
- **服务注册**:Eureka Server
|
||||
- **API网关**:Spring Cloud Gateway
|
||||
- **配置中心**:Spring Cloud Config
|
||||
|
||||
### 数据存储
|
||||
|
||||
#### 关系型数据库
|
||||
- **主数据库**:MySQL 8.0
|
||||
- **连接池**:HikariCP
|
||||
- **数据迁移**:Sequelize Migrations
|
||||
- **备份策略**:定时全量备份 + 增量备份
|
||||
|
||||
#### 缓存系统
|
||||
- **内存缓存**:Redis 6.0+
|
||||
- **缓存策略**:LRU淘汰策略
|
||||
- **数据类型**:String、Hash、List、Set
|
||||
- **持久化**:RDB + AOF
|
||||
|
||||
#### 文件存储
|
||||
- **对象存储**:MinIO / 阿里云OSS
|
||||
- **CDN加速**:阿里云CDN
|
||||
- **图片处理**:ImageMagick
|
||||
- **文件类型**:图片、文档、视频
|
||||
|
||||
### 开发工具
|
||||
|
||||
#### 版本控制
|
||||
- **代码仓库**:Git
|
||||
- **分支策略**:Git Flow
|
||||
- **代码审查**:Pull Request
|
||||
|
||||
#### 代码质量
|
||||
- **代码规范**:ESLint + Prettier
|
||||
- **类型检查**:TypeScript
|
||||
- **单元测试**:Jest + Supertest
|
||||
- **集成测试**:Postman + Newman
|
||||
|
||||
#### 容器化部署
|
||||
- **容器技术**:Docker
|
||||
- **编排工具**:Docker Compose
|
||||
- **镜像仓库**:Docker Hub / 阿里云容器镜像服务
|
||||
|
||||
## 🏢 系统架构设计
|
||||
|
||||
### 整体架构图
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "客户端层"
|
||||
A[微信小程序]
|
||||
B[后台管理系统]
|
||||
C[官方网站]
|
||||
end
|
||||
|
||||
subgraph "网关层"
|
||||
D[Nginx负载均衡]
|
||||
E[API网关]
|
||||
end
|
||||
|
||||
subgraph "应用服务层"
|
||||
F[用户服务]
|
||||
G[旅行服务]
|
||||
H[动物服务]
|
||||
I[商家服务]
|
||||
J[订单服务]
|
||||
K[消息服务]
|
||||
end
|
||||
|
||||
subgraph "数据存储层"
|
||||
L[MySQL主库]
|
||||
M[MySQL从库]
|
||||
N[Redis缓存]
|
||||
O[MinIO对象存储]
|
||||
end
|
||||
|
||||
subgraph "基础设施层"
|
||||
P[监控系统]
|
||||
Q[日志系统]
|
||||
R[配置中心]
|
||||
end
|
||||
|
||||
A --> D
|
||||
B --> D
|
||||
C --> D
|
||||
D --> E
|
||||
E --> F
|
||||
E --> G
|
||||
E --> H
|
||||
E --> I
|
||||
E --> J
|
||||
E --> K
|
||||
F --> L
|
||||
G --> L
|
||||
H --> L
|
||||
I --> L
|
||||
J --> L
|
||||
K --> L
|
||||
L --> M
|
||||
F --> N
|
||||
G --> N
|
||||
H --> N
|
||||
I --> O
|
||||
F --> P
|
||||
G --> Q
|
||||
H --> R
|
||||
```
|
||||
|
||||
### 微服务架构(Java版本)
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "服务注册中心"
|
||||
A[Eureka Server]
|
||||
end
|
||||
|
||||
subgraph "API网关"
|
||||
B[Gateway Service]
|
||||
end
|
||||
|
||||
subgraph "业务服务"
|
||||
C[用户服务 User Service]
|
||||
D[认证服务 Auth Service]
|
||||
E[旅行服务 Travel Service]
|
||||
F[动物服务 Animal Service]
|
||||
G[订单服务 Order Service]
|
||||
H[推广服务 Promotion Service]
|
||||
end
|
||||
|
||||
subgraph "数据层"
|
||||
I[MySQL集群]
|
||||
J[Redis集群]
|
||||
K[消息队列 RabbitMQ]
|
||||
end
|
||||
|
||||
B --> A
|
||||
C --> A
|
||||
D --> A
|
||||
E --> A
|
||||
F --> A
|
||||
G --> A
|
||||
H --> A
|
||||
|
||||
B --> C
|
||||
B --> D
|
||||
B --> E
|
||||
B --> F
|
||||
B --> G
|
||||
B --> H
|
||||
|
||||
C --> I
|
||||
D --> I
|
||||
E --> I
|
||||
F --> I
|
||||
G --> I
|
||||
H --> I
|
||||
|
||||
C --> J
|
||||
E --> J
|
||||
F --> J
|
||||
|
||||
G --> K
|
||||
H --> K
|
||||
```
|
||||
|
||||
## 🗄️ 数据库设计
|
||||
|
||||
### 数据库架构
|
||||
|
||||
#### 主从复制架构
|
||||
```mermaid
|
||||
graph LR
|
||||
A[应用服务器] --> B[MySQL主库]
|
||||
B --> C[MySQL从库1]
|
||||
B --> D[MySQL从库2]
|
||||
A --> C
|
||||
A --> D
|
||||
```
|
||||
|
||||
#### 分库分表策略
|
||||
- **用户表**:按用户ID取模分表
|
||||
- **订单表**:按时间分表(月表)
|
||||
- **日志表**:按日期分表(日表)
|
||||
|
||||
### 核心表结构
|
||||
|
||||
#### 用户相关表
|
||||
```sql
|
||||
-- 用户基础信息表
|
||||
CREATE TABLE users (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
openid VARCHAR(100) UNIQUE NOT NULL COMMENT '微信openid',
|
||||
nickname VARCHAR(50) NOT NULL COMMENT '用户昵称',
|
||||
avatar VARCHAR(255) COMMENT '头像URL',
|
||||
gender ENUM('male', 'female', 'unknown') DEFAULT 'unknown',
|
||||
birthday DATE COMMENT '生日',
|
||||
phone VARCHAR(20) COMMENT '手机号',
|
||||
email VARCHAR(100) COMMENT '邮箱',
|
||||
travel_count INT DEFAULT 0 COMMENT '旅行次数',
|
||||
animal_claim_count INT DEFAULT 0 COMMENT '认领动物数量',
|
||||
status ENUM('active', 'inactive', 'banned') DEFAULT 'active',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_openid (openid),
|
||||
INDEX idx_phone (phone),
|
||||
INDEX idx_status (status)
|
||||
);
|
||||
```
|
||||
|
||||
#### 旅行相关表
|
||||
```sql
|
||||
-- 旅行计划表
|
||||
CREATE TABLE travel_plans (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
user_id INT NOT NULL,
|
||||
destination VARCHAR(100) NOT NULL COMMENT '目的地',
|
||||
start_date DATE NOT NULL COMMENT '开始日期',
|
||||
end_date DATE NOT NULL COMMENT '结束日期',
|
||||
budget DECIMAL(10,2) COMMENT '预算',
|
||||
interests TEXT COMMENT '兴趣偏好',
|
||||
description TEXT COMMENT '行程描述',
|
||||
visibility ENUM('public', 'friends', 'private') DEFAULT 'public',
|
||||
max_participants INT DEFAULT 4 COMMENT '最大参与人数',
|
||||
current_participants INT DEFAULT 1 COMMENT '当前参与人数',
|
||||
status ENUM('active', 'completed', 'cancelled') DEFAULT 'active',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
INDEX idx_destination (destination),
|
||||
INDEX idx_date_range (start_date, end_date),
|
||||
INDEX idx_status (status)
|
||||
);
|
||||
```
|
||||
|
||||
#### 动物认领表
|
||||
```sql
|
||||
-- 动物信息表
|
||||
CREATE TABLE animals (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
merchant_id INT NOT NULL,
|
||||
name VARCHAR(50) NOT NULL COMMENT '动物名称',
|
||||
type ENUM('cow', 'sheep', 'pig', 'chicken') NOT NULL COMMENT '动物类型',
|
||||
breed VARCHAR(50) COMMENT '品种',
|
||||
age INT COMMENT '年龄(月)',
|
||||
gender ENUM('male', 'female') COMMENT '性别',
|
||||
description TEXT COMMENT '动物描述',
|
||||
images JSON COMMENT '动物图片',
|
||||
price DECIMAL(10,2) NOT NULL COMMENT '认领价格',
|
||||
farm_location VARCHAR(100) COMMENT '农场位置',
|
||||
status ENUM('available', 'claimed', 'unavailable') DEFAULT 'available',
|
||||
claim_count INT DEFAULT 0 COMMENT '被认领次数',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (merchant_id) REFERENCES merchants(id),
|
||||
INDEX idx_type (type),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_price (price)
|
||||
);
|
||||
```
|
||||
|
||||
## 🔐 安全架构
|
||||
|
||||
### 认证授权机制
|
||||
|
||||
#### JWT Token认证
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as 客户端
|
||||
participant A as 认证服务
|
||||
participant S as 业务服务
|
||||
participant D as 数据库
|
||||
|
||||
C->>A: 微信登录请求
|
||||
A->>D: 验证用户信息
|
||||
D-->>A: 返回用户数据
|
||||
A-->>C: 返回JWT Token
|
||||
C->>S: 携带Token请求业务接口
|
||||
S->>S: 验证Token有效性
|
||||
S->>D: 查询业务数据
|
||||
D-->>S: 返回业务数据
|
||||
S-->>C: 返回业务响应
|
||||
```
|
||||
|
||||
#### 权限控制
|
||||
- **角色定义**:普通用户、商家用户、管理员
|
||||
- **权限粒度**:接口级权限控制
|
||||
- **权限验证**:中间件统一验证
|
||||
|
||||
### 数据安全
|
||||
|
||||
#### 数据加密
|
||||
- **传输加密**:HTTPS/TLS 1.3
|
||||
- **存储加密**:敏感数据AES-256加密
|
||||
- **密码加密**:bcrypt哈希算法
|
||||
|
||||
#### 数据脱敏
|
||||
- **手机号脱敏**:中间4位显示为*
|
||||
- **身份证脱敏**:中间部分显示为*
|
||||
- **银行卡脱敏**:只显示后4位
|
||||
|
||||
## 🚀 性能优化
|
||||
|
||||
### 缓存策略
|
||||
|
||||
#### Redis缓存设计
|
||||
```mermaid
|
||||
graph TB
|
||||
A[客户端请求] --> B{缓存命中?}
|
||||
B -->|是| C[返回缓存数据]
|
||||
B -->|否| D[查询数据库]
|
||||
D --> E[更新缓存]
|
||||
E --> F[返回数据]
|
||||
```
|
||||
|
||||
#### 缓存层级
|
||||
- **L1缓存**:应用内存缓存(Node.js内存)
|
||||
- **L2缓存**:Redis分布式缓存
|
||||
- **L3缓存**:CDN边缘缓存
|
||||
|
||||
### 数据库优化
|
||||
|
||||
#### 索引策略
|
||||
- **主键索引**:所有表必须有主键
|
||||
- **唯一索引**:唯一字段建立唯一索引
|
||||
- **复合索引**:多字段查询建立复合索引
|
||||
- **覆盖索引**:高频查询建立覆盖索引
|
||||
|
||||
#### 查询优化
|
||||
- **分页查询**:使用LIMIT + OFFSET
|
||||
- **批量操作**:使用批量插入/更新
|
||||
- **读写分离**:读操作走从库,写操作走主库
|
||||
|
||||
## 📊 监控运维
|
||||
|
||||
### 系统监控
|
||||
|
||||
#### 监控指标
|
||||
- **系统指标**:CPU、内存、磁盘、网络
|
||||
- **应用指标**:QPS、响应时间、错误率
|
||||
- **业务指标**:用户活跃度、订单量、收入
|
||||
|
||||
#### 监控工具
|
||||
- **系统监控**:Prometheus + Grafana
|
||||
- **应用监控**:APM工具
|
||||
- **日志监控**:ELK Stack
|
||||
|
||||
### 日志管理
|
||||
|
||||
#### 日志分类
|
||||
- **访问日志**:记录所有API请求
|
||||
- **错误日志**:记录系统异常和错误
|
||||
- **业务日志**:记录关键业务操作
|
||||
- **审计日志**:记录敏感操作
|
||||
|
||||
#### 日志格式
|
||||
```json
|
||||
{
|
||||
"timestamp": "2025-01-01T12:00:00.000Z",
|
||||
"level": "info",
|
||||
"service": "user-service",
|
||||
"traceId": "abc123",
|
||||
"userId": 1001,
|
||||
"action": "login",
|
||||
"message": "用户登录成功",
|
||||
"duration": 150,
|
||||
"ip": "192.168.1.100"
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 部署架构
|
||||
|
||||
### 容器化部署
|
||||
|
||||
#### Docker容器设计
|
||||
```dockerfile
|
||||
# Node.js应用容器
|
||||
FROM node:16-alpine
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
COPY . .
|
||||
EXPOSE 3000
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
#### Docker Compose编排
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- "3000:3000"
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
|
||||
redis:
|
||||
image: redis:6-alpine
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
redis_data:
|
||||
```
|
||||
|
||||
### 负载均衡
|
||||
|
||||
#### Nginx配置
|
||||
```nginx
|
||||
upstream backend {
|
||||
server app1:3000 weight=1;
|
||||
server app2:3000 weight=1;
|
||||
server app3:3000 weight=1;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.jiebanke.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://backend;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📈 扩展性设计
|
||||
|
||||
### 水平扩展
|
||||
|
||||
#### 应用层扩展
|
||||
- **无状态设计**:应用服务无状态,支持水平扩展
|
||||
- **负载均衡**:通过负载均衡器分发请求
|
||||
- **自动扩缩容**:基于CPU/内存使用率自动扩缩容
|
||||
|
||||
#### 数据层扩展
|
||||
- **读写分离**:主库写入,从库读取
|
||||
- **分库分表**:按业务或数据量分库分表
|
||||
- **缓存集群**:Redis集群模式
|
||||
|
||||
### 垂直扩展
|
||||
|
||||
#### 服务拆分
|
||||
- **按业务拆分**:用户服务、订单服务、支付服务
|
||||
- **按功能拆分**:认证服务、通知服务、文件服务
|
||||
- **按数据拆分**:用户数据、业务数据、日志数据
|
||||
|
||||
## 🔮 技术演进规划
|
||||
|
||||
### 短期规划(3-6个月)
|
||||
- 完善监控告警系统
|
||||
- 优化数据库性能
|
||||
- 增强安全防护机制
|
||||
|
||||
### 中期规划(6-12个月)
|
||||
- 微服务架构改造
|
||||
- 引入消息队列
|
||||
- 实现服务治理
|
||||
|
||||
### 长期规划(1-2年)
|
||||
- 云原生架构转型
|
||||
- 大数据分析平台
|
||||
- AI智能推荐系统
|
||||
|
||||
---
|
||||
|
||||
*文档版本:v1.0*
|
||||
*最后更新:2025年1月*
|
||||
1969
docs/系统集成和部署文档.md
1969
docs/系统集成和部署文档.md
File diff suppressed because it is too large
Load Diff
275
docs/贡献指南.md
275
docs/贡献指南.md
@@ -1,275 +0,0 @@
|
||||
# 贡献指南
|
||||
|
||||
感谢您对结伴客项目的关注!我们欢迎所有形式的贡献,包括但不限于代码、文档、测试、反馈和建议。
|
||||
|
||||
## 🤝 如何贡献
|
||||
|
||||
### 报告问题
|
||||
如果您发现了bug或有功能建议,请:
|
||||
|
||||
1. 检查 [Issues](https://github.com/jiebanke/jiebanke/issues) 确认问题未被报告
|
||||
2. 创建新的 Issue,详细描述问题或建议
|
||||
3. 使用合适的标签标记 Issue
|
||||
|
||||
### 提交代码
|
||||
我们使用 Git Flow 工作流程:
|
||||
|
||||
1. **Fork 项目**
|
||||
```bash
|
||||
git clone https://github.com/your-username/jiebanke.git
|
||||
cd jiebanke
|
||||
```
|
||||
|
||||
2. **创建功能分支**
|
||||
```bash
|
||||
git checkout -b feature/your-feature-name
|
||||
```
|
||||
|
||||
3. **开发和测试**
|
||||
- 遵循项目代码规范
|
||||
- 编写必要的测试
|
||||
- 确保所有测试通过
|
||||
|
||||
4. **提交代码**
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "feat: 添加新功能描述"
|
||||
git push origin feature/your-feature-name
|
||||
```
|
||||
|
||||
5. **创建 Pull Request**
|
||||
- 详细描述变更内容
|
||||
- 关联相关的 Issue
|
||||
- 等待代码审查
|
||||
|
||||
## 📝 开发规范
|
||||
|
||||
### 代码风格
|
||||
- **JavaScript/TypeScript**: 使用 ESLint + Prettier
|
||||
- **Vue**: 遵循 Vue 3 官方风格指南
|
||||
- **CSS**: 使用 BEM 命名规范
|
||||
- **文件命名**: 使用 kebab-case
|
||||
|
||||
### 提交消息规范
|
||||
使用 [Conventional Commits](https://www.conventionalcommits.org/zh-hans/v1.0.0/) 规范:
|
||||
|
||||
```
|
||||
<类型>[可选的作用域]: <描述>
|
||||
|
||||
[可选的正文]
|
||||
|
||||
[可选的脚注]
|
||||
```
|
||||
|
||||
**类型说明:**
|
||||
- `feat`: 新功能
|
||||
- `fix`: 修复bug
|
||||
- `docs`: 文档更新
|
||||
- `style`: 代码格式调整
|
||||
- `refactor`: 代码重构
|
||||
- `test`: 测试相关
|
||||
- `chore`: 构建过程或辅助工具的变动
|
||||
|
||||
**示例:**
|
||||
```
|
||||
feat(user): 添加用户头像上传功能
|
||||
|
||||
- 支持jpg、png格式
|
||||
- 自动压缩和裁剪
|
||||
- 添加上传进度显示
|
||||
|
||||
Closes #123
|
||||
```
|
||||
|
||||
### 分支命名规范
|
||||
- `feature/功能名称`: 新功能开发
|
||||
- `bugfix/问题描述`: bug修复
|
||||
- `hotfix/紧急修复`: 紧急修复
|
||||
- `docs/文档更新`: 文档更新
|
||||
|
||||
## 🧪 测试规范
|
||||
|
||||
### 单元测试
|
||||
- 使用 Jest 进行单元测试
|
||||
- 测试覆盖率应达到 80% 以上
|
||||
- 为核心业务逻辑编写测试
|
||||
|
||||
### 集成测试
|
||||
- 使用 Cypress 进行端到端测试
|
||||
- 覆盖主要用户流程
|
||||
- 确保跨浏览器兼容性
|
||||
|
||||
### 测试命令
|
||||
```bash
|
||||
# 运行所有测试
|
||||
npm test
|
||||
|
||||
# 运行单元测试
|
||||
npm run test:unit
|
||||
|
||||
# 运行集成测试
|
||||
npm run test:e2e
|
||||
|
||||
# 生成测试覆盖率报告
|
||||
npm run test:coverage
|
||||
```
|
||||
|
||||
## 🏗️ 项目结构
|
||||
|
||||
### 后端 (backend/)
|
||||
```
|
||||
backend/
|
||||
├── src/
|
||||
│ ├── controllers/ # 控制器
|
||||
│ ├── models/ # 数据模型
|
||||
│ ├── routes/ # 路由定义
|
||||
│ ├── services/ # 业务逻辑
|
||||
│ ├── middleware/ # 中间件
|
||||
│ └── utils/ # 工具函数
|
||||
├── tests/ # 测试文件
|
||||
└── docs/ # API文档
|
||||
```
|
||||
|
||||
### 前端 (admin-system/)
|
||||
```
|
||||
admin-system/
|
||||
├── src/
|
||||
│ ├── components/ # 公共组件
|
||||
│ ├── pages/ # 页面组件
|
||||
│ ├── stores/ # 状态管理
|
||||
│ ├── api/ # API接口
|
||||
│ ├── utils/ # 工具函数
|
||||
│ └── styles/ # 样式文件
|
||||
├── tests/ # 测试文件
|
||||
└── public/ # 静态资源
|
||||
```
|
||||
|
||||
## 🔧 开发环境搭建
|
||||
|
||||
### 环境要求
|
||||
- Node.js 16.x+
|
||||
- MySQL 8.0+
|
||||
- Redis 6.x+
|
||||
- Git 2.x+
|
||||
|
||||
### 快速开始
|
||||
1. **克隆项目**
|
||||
```bash
|
||||
git clone https://github.com/jiebanke/jiebanke.git
|
||||
cd jiebanke
|
||||
```
|
||||
|
||||
2. **安装依赖**
|
||||
```bash
|
||||
# 安装后端依赖
|
||||
cd backend && npm install
|
||||
|
||||
# 安装前端依赖
|
||||
cd ../admin-system && npm install
|
||||
```
|
||||
|
||||
3. **配置环境变量**
|
||||
```bash
|
||||
# 复制环境变量模板
|
||||
cp backend/.env.example backend/.env
|
||||
cp admin-system/.env.example admin-system/.env
|
||||
```
|
||||
|
||||
4. **启动开发服务**
|
||||
```bash
|
||||
# 启动后端服务
|
||||
cd backend && npm run dev
|
||||
|
||||
# 启动前端服务 (新终端)
|
||||
cd admin-system && npm run dev
|
||||
```
|
||||
|
||||
## 📋 代码审查清单
|
||||
|
||||
提交 Pull Request 前,请确认:
|
||||
|
||||
### 功能性
|
||||
- [ ] 功能按预期工作
|
||||
- [ ] 处理了边界情况
|
||||
- [ ] 错误处理完善
|
||||
- [ ] 性能表现良好
|
||||
|
||||
### 代码质量
|
||||
- [ ] 代码风格符合规范
|
||||
- [ ] 变量和函数命名清晰
|
||||
- [ ] 代码结构合理
|
||||
- [ ] 避免重复代码
|
||||
|
||||
### 测试
|
||||
- [ ] 编写了必要的测试
|
||||
- [ ] 所有测试通过
|
||||
- [ ] 测试覆盖率达标
|
||||
- [ ] 手动测试通过
|
||||
|
||||
### 文档
|
||||
- [ ] 更新了相关文档
|
||||
- [ ] API文档保持同步
|
||||
- [ ] 注释清晰准确
|
||||
- [ ] README更新(如需要)
|
||||
|
||||
## 🎯 贡献领域
|
||||
|
||||
我们特别欢迎以下方面的贡献:
|
||||
|
||||
### 代码贡献
|
||||
- 新功能开发
|
||||
- Bug修复
|
||||
- 性能优化
|
||||
- 代码重构
|
||||
|
||||
### 文档贡献
|
||||
- API文档完善
|
||||
- 使用指南编写
|
||||
- 最佳实践分享
|
||||
- 多语言翻译
|
||||
|
||||
### 测试贡献
|
||||
- 单元测试编写
|
||||
- 集成测试完善
|
||||
- 性能测试
|
||||
- 安全测试
|
||||
|
||||
### 设计贡献
|
||||
- UI/UX设计优化
|
||||
- 交互体验改进
|
||||
- 视觉设计规范
|
||||
- 无障碍访问支持
|
||||
|
||||
## 🏆 贡献者认可
|
||||
|
||||
我们重视每一位贡献者的付出:
|
||||
|
||||
- 贡献者将在项目README中被列出
|
||||
- 重要贡献者将获得项目维护者权限
|
||||
- 优秀贡献将在项目博客中专门介绍
|
||||
- 定期举办贡献者聚会和技术分享
|
||||
|
||||
## 📞 联系我们
|
||||
|
||||
如有任何问题,欢迎通过以下方式联系:
|
||||
|
||||
- **GitHub Issues**: [项目Issues页面](https://github.com/jiebanke/jiebanke/issues)
|
||||
- **邮箱**: dev@jiebanke.com
|
||||
- **微信群**: 扫描README中的二维码加入
|
||||
- **技术论坛**: [结伴客开发者社区](https://dev.jiebanke.com)
|
||||
|
||||
## 📜 行为准则
|
||||
|
||||
参与项目时,请遵守我们的[行为准则](CODE_OF_CONDUCT.md):
|
||||
|
||||
- 尊重所有参与者
|
||||
- 保持友好和专业
|
||||
- 接受建设性批评
|
||||
- 关注项目整体利益
|
||||
- 遵守开源协议
|
||||
|
||||
---
|
||||
|
||||
再次感谢您的贡献!让我们一起打造更好的结伴客项目! 🚀
|
||||
|
||||
*最后更新:2024年1月*
|
||||
1359
docs/运维文档.md
Normal file
1359
docs/运维文档.md
Normal file
File diff suppressed because it is too large
Load Diff
1080
docs/部署和运维文档.md
1080
docs/部署和运维文档.md
File diff suppressed because it is too large
Load Diff
708
docs/部署指南.md
708
docs/部署指南.md
@@ -1,708 +0,0 @@
|
||||
# 📦 结伴客系统部署指南
|
||||
|
||||
## 📋 部署概述
|
||||
|
||||
本文档详细说明了结伴客项目的完整部署流程,包括开发环境、测试环境和生产环境的部署配置。项目采用容器化部署方式,支持快速部署和弹性扩容。
|
||||
|
||||
## 🛠️ 环境要求
|
||||
|
||||
### 系统要求
|
||||
- **操作系统**:Ubuntu 20.04+ / CentOS 7+ / macOS 10.15+
|
||||
- **CPU**:最低2核,推荐4核+
|
||||
- **内存**:最低4GB,推荐8GB+
|
||||
- **存储**:最低20GB可用空间,推荐50GB+
|
||||
- **网络**:稳定的互联网连接,带宽10Mbps+
|
||||
|
||||
### 软件依赖
|
||||
|
||||
#### 基础软件
|
||||
- **Node.js**:16.x 或 18.x LTS版本
|
||||
- **npm**:8.x+ 或 yarn 1.22+
|
||||
- **Git**:2.30+
|
||||
- **Docker**:20.10+
|
||||
- **Docker Compose**:2.0+
|
||||
|
||||
#### 数据库
|
||||
- **MySQL**:8.0+
|
||||
- **Redis**:6.0+(可选,用于缓存)
|
||||
|
||||
#### 其他工具
|
||||
- **Nginx**:1.18+(用于反向代理)
|
||||
- **PM2**:5.0+(用于进程管理)
|
||||
- **微信开发者工具**:最新版本
|
||||
|
||||
## 🚀 快速部署
|
||||
|
||||
### 一键部署脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 快速部署脚本 - deploy.sh
|
||||
|
||||
echo "开始部署结伴客项目..."
|
||||
|
||||
# 1. 克隆项目
|
||||
git clone https://github.com/your-org/jiebanke.git
|
||||
cd jiebanke
|
||||
|
||||
# 2. 安装依赖
|
||||
echo "安装项目依赖..."
|
||||
npm install
|
||||
|
||||
# 3. 配置环境变量
|
||||
echo "配置环境变量..."
|
||||
cp .env.example .env
|
||||
|
||||
# 4. 初始化数据库
|
||||
echo "初始化数据库..."
|
||||
npm run db:migrate
|
||||
npm run db:seed
|
||||
|
||||
# 5. 构建项目
|
||||
echo "构建项目..."
|
||||
npm run build
|
||||
|
||||
# 6. 启动服务
|
||||
echo "启动服务..."
|
||||
npm run start:prod
|
||||
|
||||
echo "部署完成!访问 http://localhost:3000"
|
||||
```
|
||||
|
||||
### Docker一键部署
|
||||
|
||||
```bash
|
||||
# 使用Docker Compose一键部署
|
||||
docker-compose up -d
|
||||
|
||||
# 查看服务状态
|
||||
docker-compose ps
|
||||
|
||||
# 查看日志
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
## 🏗️ 开发环境部署
|
||||
|
||||
### 1. 环境准备
|
||||
|
||||
#### 安装Node.js
|
||||
```bash
|
||||
# 使用nvm安装Node.js
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
|
||||
source ~/.bashrc
|
||||
nvm install 18
|
||||
nvm use 18
|
||||
```
|
||||
|
||||
#### 安装MySQL
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt update
|
||||
sudo apt install mysql-server
|
||||
|
||||
# macOS
|
||||
brew install mysql
|
||||
brew services start mysql
|
||||
|
||||
# 创建数据库
|
||||
mysql -u root -p
|
||||
CREATE DATABASE jiebandata CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE USER 'jieban'@'localhost' IDENTIFIED BY 'password';
|
||||
GRANT ALL PRIVILEGES ON jiebandata.* TO 'jieban'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
### 2. 项目配置
|
||||
|
||||
#### 克隆项目代码
|
||||
```bash
|
||||
git clone https://github.com/your-org/jiebanke.git
|
||||
cd jiebanke
|
||||
```
|
||||
|
||||
#### 安装项目依赖
|
||||
```bash
|
||||
# 后端依赖
|
||||
cd backend
|
||||
npm install
|
||||
|
||||
# 前端管理系统依赖
|
||||
cd ../admin-system
|
||||
npm install
|
||||
|
||||
# 小程序依赖
|
||||
cd ../mini-program
|
||||
npm install
|
||||
|
||||
# 官网依赖
|
||||
cd ../website
|
||||
npm install
|
||||
```
|
||||
|
||||
#### 配置环境变量
|
||||
```bash
|
||||
# 复制环境变量模板
|
||||
cd backend
|
||||
cp .env.example .env
|
||||
|
||||
# 编辑环境变量
|
||||
vim .env
|
||||
```
|
||||
|
||||
**环境变量配置示例:**
|
||||
```env
|
||||
# 应用配置
|
||||
NODE_ENV=development
|
||||
PORT=3000
|
||||
APP_NAME=结伴客
|
||||
|
||||
# 数据库配置
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_NAME=jiebandata
|
||||
DB_USER=jieban
|
||||
DB_PASSWORD=password
|
||||
|
||||
# Redis配置
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
|
||||
# JWT配置
|
||||
JWT_SECRET=your-jwt-secret-key
|
||||
JWT_EXPIRES_IN=7d
|
||||
|
||||
# 微信小程序配置
|
||||
WECHAT_APP_ID=your-wechat-app-id
|
||||
WECHAT_APP_SECRET=your-wechat-app-secret
|
||||
|
||||
# 文件上传配置
|
||||
UPLOAD_PATH=./uploads
|
||||
MAX_FILE_SIZE=10485760
|
||||
|
||||
# 邮件配置
|
||||
SMTP_HOST=smtp.qq.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=your-email@qq.com
|
||||
SMTP_PASS=your-email-password
|
||||
```
|
||||
|
||||
### 3. 数据库初始化
|
||||
|
||||
```bash
|
||||
# 运行数据库迁移
|
||||
cd backend
|
||||
npm run db:migrate
|
||||
|
||||
# 运行数据库种子文件
|
||||
npm run db:seed
|
||||
|
||||
# 或者直接执行SQL文件
|
||||
mysql -u jieban -p jiebandata < scripts/init-database.sql
|
||||
```
|
||||
|
||||
### 4. 启动开发服务
|
||||
|
||||
```bash
|
||||
# 启动后端服务
|
||||
cd backend
|
||||
npm run dev
|
||||
|
||||
# 启动前端管理系统(新终端)
|
||||
cd admin-system
|
||||
npm run dev
|
||||
|
||||
# 启动官网(新终端)
|
||||
cd website
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### 5. 验证部署
|
||||
|
||||
访问以下地址验证部署是否成功:
|
||||
- 后端API:http://localhost:3000/api/health
|
||||
- 管理系统:http://localhost:8080
|
||||
- 官网:http://localhost:8081
|
||||
|
||||
## 🧪 测试环境部署
|
||||
|
||||
### 1. 服务器配置
|
||||
|
||||
#### 服务器信息
|
||||
- **主机**:192.168.0.240
|
||||
- **操作系统**:Ubuntu 20.04
|
||||
- **用户**:deploy
|
||||
- **部署路径**:/var/www/jiebanke
|
||||
|
||||
#### 环境变量配置
|
||||
```env
|
||||
NODE_ENV=testing
|
||||
PORT=3000
|
||||
DB_HOST=192.168.0.240
|
||||
DB_PORT=3306
|
||||
DB_NAME=jiebandata_test
|
||||
DB_USER=jieban_test
|
||||
DB_PASSWORD=test_password
|
||||
```
|
||||
|
||||
### 2. 自动化部署脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 测试环境部署脚本 - deploy-test.sh
|
||||
|
||||
SERVER_HOST="192.168.0.240"
|
||||
SERVER_USER="deploy"
|
||||
DEPLOY_PATH="/var/www/jiebanke"
|
||||
|
||||
echo "开始部署到测试环境..."
|
||||
|
||||
# 1. 构建项目
|
||||
echo "构建项目..."
|
||||
npm run build
|
||||
|
||||
# 2. 打包文件
|
||||
echo "打包部署文件..."
|
||||
tar -czf jiebanke-$(date +%Y%m%d-%H%M%S).tar.gz \
|
||||
backend/ admin-system/dist/ website/dist/ \
|
||||
package.json docker-compose.yml
|
||||
|
||||
# 3. 上传到服务器
|
||||
echo "上传文件到服务器..."
|
||||
scp jiebanke-*.tar.gz $SERVER_USER@$SERVER_HOST:$DEPLOY_PATH/
|
||||
|
||||
# 4. 远程部署
|
||||
echo "执行远程部署..."
|
||||
ssh $SERVER_USER@$SERVER_HOST << 'EOF'
|
||||
cd /var/www/jiebanke
|
||||
tar -xzf jiebanke-*.tar.gz
|
||||
docker-compose down
|
||||
docker-compose up -d --build
|
||||
docker-compose ps
|
||||
EOF
|
||||
|
||||
echo "测试环境部署完成!"
|
||||
```
|
||||
|
||||
## 🌐 生产环境部署
|
||||
|
||||
### 1. 服务器配置
|
||||
|
||||
#### 服务器信息
|
||||
- **主机**:129.211.213.226
|
||||
- **端口**:9527
|
||||
- **操作系统**:CentOS 7
|
||||
- **用户**:root
|
||||
- **部署路径**:/opt/jiebanke
|
||||
|
||||
#### 高可用架构
|
||||
```mermaid
|
||||
graph TB
|
||||
A[负载均衡器 Nginx] --> B[应用服务器1]
|
||||
A --> C[应用服务器2]
|
||||
A --> D[应用服务器3]
|
||||
B --> E[MySQL主库]
|
||||
C --> E
|
||||
D --> E
|
||||
E --> F[MySQL从库1]
|
||||
E --> G[MySQL从库2]
|
||||
B --> H[Redis集群]
|
||||
C --> H
|
||||
D --> H
|
||||
```
|
||||
|
||||
### 2. Docker容器化部署
|
||||
|
||||
#### Dockerfile配置
|
||||
```dockerfile
|
||||
# 后端服务Dockerfile
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production && npm cache clean --force
|
||||
|
||||
FROM node:18-alpine
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
EXPOSE 3000
|
||||
USER node
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
#### Docker Compose配置
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# 后端API服务
|
||||
api:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- DB_HOST=mysql
|
||||
- REDIS_HOST=redis
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- jiebanke-network
|
||||
|
||||
# 前端管理系统
|
||||
admin:
|
||||
build:
|
||||
context: ./admin-system
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "8080:80"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- jiebanke-network
|
||||
|
||||
# MySQL数据库
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
||||
MYSQL_DATABASE: jiebandata
|
||||
MYSQL_USER: jieban
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./scripts/init-database.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
ports:
|
||||
- "3306:3306"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- jiebanke-network
|
||||
|
||||
# Redis缓存
|
||||
redis:
|
||||
image: redis:6-alpine
|
||||
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
ports:
|
||||
- "6379:6379"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- jiebanke-network
|
||||
|
||||
# Nginx反向代理
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./nginx/ssl:/etc/nginx/ssl
|
||||
depends_on:
|
||||
- api
|
||||
- admin
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- jiebanke-network
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
redis_data:
|
||||
|
||||
networks:
|
||||
jiebanke-network:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
### 3. Nginx配置
|
||||
|
||||
```nginx
|
||||
# nginx.conf
|
||||
upstream api_backend {
|
||||
server api:3000;
|
||||
}
|
||||
|
||||
upstream admin_backend {
|
||||
server admin:80;
|
||||
}
|
||||
|
||||
# API服务器配置
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.jiebanke.com;
|
||||
|
||||
# 重定向到HTTPS
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name api.jiebanke.com;
|
||||
|
||||
# SSL证书配置
|
||||
ssl_certificate /etc/nginx/ssl/api.jiebanke.com.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/api.jiebanke.com.key;
|
||||
|
||||
# SSL安全配置
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# 安全头
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# API代理
|
||||
location /api/ {
|
||||
proxy_pass http://api_backend;
|
||||
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;
|
||||
|
||||
# 超时配置
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
|
||||
# 文件上传大小限制
|
||||
client_max_body_size 10M;
|
||||
}
|
||||
|
||||
# 管理系统配置
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name admin.jiebanke.com;
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/admin.jiebanke.com.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/admin.jiebanke.com.key;
|
||||
|
||||
location / {
|
||||
proxy_pass http://admin_backend;
|
||||
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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 生产环境部署脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 生产环境部署脚本 - deploy-prod.sh
|
||||
|
||||
set -e
|
||||
|
||||
PROD_SERVER="129.211.213.226"
|
||||
PROD_USER="root"
|
||||
DEPLOY_PATH="/opt/jiebanke"
|
||||
BACKUP_PATH="/opt/backups"
|
||||
|
||||
echo "开始生产环境部署..."
|
||||
|
||||
# 1. 备份当前版本
|
||||
echo "备份当前版本..."
|
||||
ssh $PROD_USER@$PROD_SERVER << EOF
|
||||
if [ -d "$DEPLOY_PATH" ]; then
|
||||
sudo mkdir -p $BACKUP_PATH
|
||||
sudo tar -czf $BACKUP_PATH/jiebanke-backup-$(date +%Y%m%d-%H%M%S).tar.gz -C $DEPLOY_PATH .
|
||||
fi
|
||||
EOF
|
||||
|
||||
# 2. 构建生产版本
|
||||
echo "构建生产版本..."
|
||||
NODE_ENV=production npm run build
|
||||
|
||||
# 3. 创建部署包
|
||||
echo "创建部署包..."
|
||||
tar -czf jiebanke-prod-$(date +%Y%m%d-%H%M%S).tar.gz \
|
||||
backend/ admin-system/dist/ website/dist/ \
|
||||
docker-compose.prod.yml nginx/ scripts/
|
||||
|
||||
# 4. 上传到生产服务器
|
||||
echo "上传到生产服务器..."
|
||||
scp jiebanke-prod-*.tar.gz $PROD_USER@$PROD_SERVER:$DEPLOY_PATH/
|
||||
|
||||
# 5. 执行部署
|
||||
echo "执行生产部署..."
|
||||
ssh $PROD_USER@$PROD_SERVER << 'EOF'
|
||||
cd /opt/jiebanke
|
||||
tar -xzf jiebanke-prod-*.tar.gz
|
||||
|
||||
# 停止旧服务
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
|
||||
# 启动新服务
|
||||
docker-compose -f docker-compose.prod.yml up -d --build
|
||||
|
||||
# 等待服务启动
|
||||
sleep 30
|
||||
|
||||
# 检查服务状态
|
||||
docker-compose -f docker-compose.prod.yml ps
|
||||
|
||||
# 健康检查
|
||||
curl -f http://localhost:3000/api/health || exit 1
|
||||
|
||||
echo "生产环境部署成功!"
|
||||
EOF
|
||||
|
||||
echo "部署完成!"
|
||||
```
|
||||
|
||||
## 🔍 部署验证
|
||||
|
||||
### 健康检查
|
||||
|
||||
```bash
|
||||
# API健康检查
|
||||
curl -X GET http://localhost:3000/api/health
|
||||
|
||||
# 数据库连接检查
|
||||
curl -X GET http://localhost:3000/api/health/db
|
||||
|
||||
# Redis连接检查
|
||||
curl -X GET http://localhost:3000/api/health/redis
|
||||
```
|
||||
|
||||
### 性能测试
|
||||
|
||||
```bash
|
||||
# 使用Apache Bench进行压力测试
|
||||
ab -n 1000 -c 10 http://localhost:3000/api/health
|
||||
|
||||
# 使用wrk进行性能测试
|
||||
wrk -t12 -c400 -d30s http://localhost:3000/api/health
|
||||
```
|
||||
|
||||
## 📊 监控配置
|
||||
|
||||
### 系统监控
|
||||
|
||||
#### Prometheus配置
|
||||
```yaml
|
||||
# prometheus.yml
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'jiebanke-api'
|
||||
static_configs:
|
||||
- targets: ['localhost:3000']
|
||||
metrics_path: '/metrics'
|
||||
```
|
||||
|
||||
#### Grafana仪表板
|
||||
- **系统指标**:CPU、内存、磁盘使用率
|
||||
- **应用指标**:QPS、响应时间、错误率
|
||||
- **业务指标**:用户注册量、订单量、收入
|
||||
|
||||
### 日志管理
|
||||
|
||||
#### 日志收集配置
|
||||
```yaml
|
||||
# filebeat.yml
|
||||
filebeat.inputs:
|
||||
- type: log
|
||||
enabled: true
|
||||
paths:
|
||||
- /opt/jiebanke/logs/*.log
|
||||
fields:
|
||||
service: jiebanke
|
||||
environment: production
|
||||
|
||||
output.elasticsearch:
|
||||
hosts: ["elasticsearch:9200"]
|
||||
```
|
||||
|
||||
## 🚨 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 1. 数据库连接失败
|
||||
```bash
|
||||
# 检查数据库服务状态
|
||||
docker-compose ps mysql
|
||||
|
||||
# 查看数据库日志
|
||||
docker-compose logs mysql
|
||||
|
||||
# 测试数据库连接
|
||||
mysql -h localhost -u jieban -p jiebandata
|
||||
```
|
||||
|
||||
#### 2. Redis连接失败
|
||||
```bash
|
||||
# 检查Redis服务状态
|
||||
docker-compose ps redis
|
||||
|
||||
# 测试Redis连接
|
||||
redis-cli -h localhost -p 6379 ping
|
||||
```
|
||||
|
||||
#### 3. 应用启动失败
|
||||
```bash
|
||||
# 查看应用日志
|
||||
docker-compose logs api
|
||||
|
||||
# 检查环境变量
|
||||
docker-compose exec api env
|
||||
|
||||
# 进入容器调试
|
||||
docker-compose exec api sh
|
||||
```
|
||||
|
||||
### 回滚操作
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 回滚脚本 - rollback.sh
|
||||
|
||||
BACKUP_FILE=$1
|
||||
DEPLOY_PATH="/opt/jiebanke"
|
||||
|
||||
if [ -z "$BACKUP_FILE" ]; then
|
||||
echo "请指定备份文件名"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "开始回滚到版本: $BACKUP_FILE"
|
||||
|
||||
# 停止当前服务
|
||||
docker-compose down
|
||||
|
||||
# 恢复备份
|
||||
tar -xzf /opt/backups/$BACKUP_FILE -C $DEPLOY_PATH
|
||||
|
||||
# 启动服务
|
||||
docker-compose up -d
|
||||
|
||||
echo "回滚完成!"
|
||||
```
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
### 联系方式
|
||||
- **技术支持邮箱**:tech-support@jiebanke.com
|
||||
- **紧急联系电话**:400-xxx-xxxx
|
||||
- **技术文档**:https://docs.jiebanke.com
|
||||
|
||||
### 支持时间
|
||||
- **工作日**:9:00 - 18:00
|
||||
- **紧急故障**:7×24小时响应
|
||||
|
||||
---
|
||||
|
||||
*文档版本:v1.0*
|
||||
*最后更新:2025年1月*
|
||||
763
docs/部署文档.md
Normal file
763
docs/部署文档.md
Normal file
@@ -0,0 +1,763 @@
|
||||
# 解班客项目部署文档
|
||||
|
||||
## 1. 部署概述
|
||||
|
||||
### 1.1 部署架构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A[用户] --> B[CDN/负载均衡]
|
||||
B --> C[Nginx反向代理]
|
||||
C --> D[小程序静态资源]
|
||||
C --> E[管理后台静态资源]
|
||||
C --> F[后端API服务]
|
||||
|
||||
F --> G[Redis缓存]
|
||||
F --> H[MySQL主库]
|
||||
H --> I[MySQL从库]
|
||||
|
||||
F --> J[文件存储OSS]
|
||||
F --> K[消息队列]
|
||||
|
||||
subgraph "服务器集群"
|
||||
L[Web服务器1]
|
||||
M[Web服务器2]
|
||||
N[API服务器1]
|
||||
O[API服务器2]
|
||||
end
|
||||
|
||||
C --> L
|
||||
C --> M
|
||||
F --> N
|
||||
F --> O
|
||||
```
|
||||
|
||||
### 1.2 环境规划
|
||||
|
||||
| 环境 | 用途 | 服务器配置 | 域名 |
|
||||
|------|------|------------|------|
|
||||
| 开发环境 | 开发测试 | 2C4G | dev.jiebanke.com |
|
||||
| 测试环境 | 功能测试 | 4C8G | test.jiebanke.com |
|
||||
| 预发布环境 | 集成测试 | 8C16G | pre.jiebanke.com |
|
||||
| 生产环境 | 线上服务 | 16C32G | www.jiebanke.com |
|
||||
|
||||
## 2. 服务器环境准备
|
||||
|
||||
### 2.1 系统要求
|
||||
|
||||
```bash
|
||||
# CentOS 7/8 或 Ubuntu 18.04+
|
||||
# 最低配置:4C8G,推荐:8C16G
|
||||
# 磁盘空间:100GB+
|
||||
# 网络:带宽10Mbps+
|
||||
|
||||
# 系统更新
|
||||
sudo yum update -y # CentOS
|
||||
sudo apt update && sudo apt upgrade -y # Ubuntu
|
||||
```
|
||||
|
||||
### 2.2 基础软件安装
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# install-base.sh - 基础环境安装脚本
|
||||
|
||||
# 安装Docker
|
||||
curl -fsSL https://get.docker.com | bash
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
sudo usermod -aG docker $USER
|
||||
|
||||
# 安装Docker Compose
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# 安装Node.js
|
||||
curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -
|
||||
sudo yum install -y nodejs
|
||||
|
||||
# 安装PM2
|
||||
sudo npm install -g pm2
|
||||
|
||||
# 安装Nginx
|
||||
sudo yum install -y nginx
|
||||
sudo systemctl start nginx
|
||||
sudo systemctl enable nginx
|
||||
|
||||
echo "基础环境安装完成"
|
||||
```
|
||||
|
||||
### 2.3 目录结构规划
|
||||
|
||||
```bash
|
||||
# 创建项目目录结构
|
||||
sudo mkdir -p /opt/jiebanke/{
|
||||
backend,
|
||||
admin-system,
|
||||
mini-program,
|
||||
website,
|
||||
nginx,
|
||||
logs,
|
||||
data,
|
||||
scripts,
|
||||
ssl
|
||||
}
|
||||
|
||||
# 设置权限
|
||||
sudo chown -R $USER:$USER /opt/jiebanke
|
||||
chmod -R 755 /opt/jiebanke
|
||||
```
|
||||
|
||||
## 3. 数据库部署
|
||||
|
||||
### 3.1 MySQL主从部署
|
||||
|
||||
```yaml
|
||||
# docker-compose-mysql.yml
|
||||
version: '3.8'
|
||||
services:
|
||||
mysql-master:
|
||||
image: mysql:8.0
|
||||
container_name: mysql-master
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
||||
MYSQL_DATABASE: jiebanke
|
||||
MYSQL_USER: jiebanke
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
||||
volumes:
|
||||
- ./data/mysql-master:/var/lib/mysql
|
||||
- ./config/mysql-master.cnf:/etc/mysql/conf.d/mysql.cnf
|
||||
ports:
|
||||
- "3306:3306"
|
||||
command: --server-id=1 --log-bin=mysql-bin --binlog-format=ROW
|
||||
networks:
|
||||
- jiebanke-network
|
||||
|
||||
mysql-slave:
|
||||
image: mysql:8.0
|
||||
container_name: mysql-slave
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
||||
MYSQL_DATABASE: jiebanke
|
||||
MYSQL_USER: jiebanke
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
||||
volumes:
|
||||
- ./data/mysql-slave:/var/lib/mysql
|
||||
- ./config/mysql-slave.cnf:/etc/mysql/conf.d/mysql.cnf
|
||||
ports:
|
||||
- "3307:3306"
|
||||
command: --server-id=2 --relay-log=relay-bin --read-only=1
|
||||
depends_on:
|
||||
- mysql-master
|
||||
networks:
|
||||
- jiebanke-network
|
||||
|
||||
networks:
|
||||
jiebanke-network:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
### 3.2 Redis集群部署
|
||||
|
||||
```yaml
|
||||
# docker-compose-redis.yml
|
||||
version: '3.8'
|
||||
services:
|
||||
redis-master:
|
||||
image: redis:7-alpine
|
||||
container_name: redis-master
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- ./data/redis-master:/data
|
||||
- ./config/redis-master.conf:/usr/local/etc/redis/redis.conf
|
||||
command: redis-server /usr/local/etc/redis/redis.conf
|
||||
networks:
|
||||
- jiebanke-network
|
||||
|
||||
redis-slave:
|
||||
image: redis:7-alpine
|
||||
container_name: redis-slave
|
||||
ports:
|
||||
- "6380:6379"
|
||||
volumes:
|
||||
- ./data/redis-slave:/data
|
||||
- ./config/redis-slave.conf:/usr/local/etc/redis/redis.conf
|
||||
command: redis-server /usr/local/etc/redis/redis.conf --slaveof redis-master 6379
|
||||
depends_on:
|
||||
- redis-master
|
||||
networks:
|
||||
- jiebanke-network
|
||||
```
|
||||
|
||||
## 4. 后端服务部署
|
||||
|
||||
### 4.1 后端API服务
|
||||
|
||||
```dockerfile
|
||||
# backend/Dockerfile
|
||||
FROM node:18-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# 复制package文件
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# 复制源代码
|
||||
COPY . .
|
||||
|
||||
# 构建应用
|
||||
RUN npm run build
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 3000
|
||||
|
||||
# 启动命令
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
### 4.2 PM2配置
|
||||
|
||||
```javascript
|
||||
// ecosystem.config.js
|
||||
module.exports = {
|
||||
apps: [{
|
||||
name: 'jiebanke-api',
|
||||
script: './dist/app.js',
|
||||
instances: 'max',
|
||||
exec_mode: 'cluster',
|
||||
env: {
|
||||
NODE_ENV: 'production',
|
||||
PORT: 3000
|
||||
},
|
||||
env_production: {
|
||||
NODE_ENV: 'production',
|
||||
PORT: 3000,
|
||||
DB_HOST: 'localhost',
|
||||
DB_PORT: 3306,
|
||||
DB_NAME: 'jiebanke',
|
||||
REDIS_HOST: 'localhost',
|
||||
REDIS_PORT: 6379
|
||||
},
|
||||
log_file: '/opt/jiebanke/logs/api.log',
|
||||
error_file: '/opt/jiebanke/logs/api-error.log',
|
||||
out_file: '/opt/jiebanke/logs/api-out.log',
|
||||
log_date_format: 'YYYY-MM-DD HH:mm:ss',
|
||||
max_memory_restart: '1G',
|
||||
node_args: '--max_old_space_size=1024'
|
||||
}]
|
||||
};
|
||||
```
|
||||
|
||||
### 4.3 部署脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# deploy-backend.sh - 后端部署脚本
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="/opt/jiebanke"
|
||||
BACKEND_DIR="$PROJECT_DIR/backend"
|
||||
BACKUP_DIR="$PROJECT_DIR/backup/$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
echo "开始部署后端服务..."
|
||||
|
||||
# 创建备份
|
||||
if [ -d "$BACKEND_DIR" ]; then
|
||||
echo "创建备份..."
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
cp -r "$BACKEND_DIR" "$BACKUP_DIR/"
|
||||
fi
|
||||
|
||||
# 拉取最新代码
|
||||
cd "$PROJECT_DIR"
|
||||
git pull origin main
|
||||
|
||||
# 安装依赖
|
||||
cd "$BACKEND_DIR"
|
||||
npm ci --only=production
|
||||
|
||||
# 构建项目
|
||||
npm run build
|
||||
|
||||
# 数据库迁移
|
||||
npm run migrate
|
||||
|
||||
# 重启服务
|
||||
pm2 reload ecosystem.config.js --env production
|
||||
|
||||
# 健康检查
|
||||
sleep 10
|
||||
if curl -f http://localhost:3000/health; then
|
||||
echo "后端服务部署成功"
|
||||
else
|
||||
echo "后端服务部署失败,回滚..."
|
||||
pm2 stop jiebanke-api
|
||||
rm -rf "$BACKEND_DIR"
|
||||
cp -r "$BACKUP_DIR/backend" "$PROJECT_DIR/"
|
||||
cd "$BACKEND_DIR"
|
||||
pm2 start ecosystem.config.js --env production
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
## 5. 前端部署
|
||||
|
||||
### 5.1 管理后台部署
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# deploy-admin.sh - 管理后台部署脚本
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="/opt/jiebanke"
|
||||
ADMIN_DIR="$PROJECT_DIR/admin-system"
|
||||
NGINX_DIR="/var/www/admin"
|
||||
|
||||
echo "开始部署管理后台..."
|
||||
|
||||
# 构建项目
|
||||
cd "$ADMIN_DIR"
|
||||
npm ci
|
||||
npm run build
|
||||
|
||||
# 部署到Nginx目录
|
||||
sudo rm -rf "$NGINX_DIR"
|
||||
sudo mkdir -p "$NGINX_DIR"
|
||||
sudo cp -r dist/* "$NGINX_DIR/"
|
||||
sudo chown -R nginx:nginx "$NGINX_DIR"
|
||||
|
||||
# 重载Nginx配置
|
||||
sudo nginx -t && sudo nginx -s reload
|
||||
|
||||
echo "管理后台部署完成"
|
||||
```
|
||||
|
||||
### 5.2 小程序部署
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# deploy-miniprogram.sh - 小程序部署脚本
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="/opt/jiebanke"
|
||||
MINI_DIR="$PROJECT_DIR/mini-program"
|
||||
|
||||
echo "开始构建小程序..."
|
||||
|
||||
cd "$MINI_DIR"
|
||||
npm ci
|
||||
npm run build
|
||||
|
||||
echo "小程序构建完成,请使用微信开发者工具上传"
|
||||
echo "构建产物位置: $MINI_DIR/dist"
|
||||
```
|
||||
|
||||
## 6. Nginx配置
|
||||
|
||||
### 6.1 主配置文件
|
||||
|
||||
```nginx
|
||||
# /etc/nginx/nginx.conf
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
error_log /var/log/nginx/error.log;
|
||||
pid /run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
use epoll;
|
||||
multi_accept on;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# 日志格式
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
# 基础配置
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
client_max_body_size 50M;
|
||||
|
||||
# Gzip压缩
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
# 包含站点配置
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 站点配置
|
||||
|
||||
```nginx
|
||||
# /etc/nginx/conf.d/jiebanke.conf
|
||||
# API服务负载均衡
|
||||
upstream api_backend {
|
||||
server 127.0.0.1:3000 weight=1 max_fails=3 fail_timeout=30s;
|
||||
server 127.0.0.1:3001 weight=1 max_fails=3 fail_timeout=30s;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
# 管理后台
|
||||
server {
|
||||
listen 80;
|
||||
server_name admin.jiebanke.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name admin.jiebanke.com;
|
||||
|
||||
# SSL配置
|
||||
ssl_certificate /opt/jiebanke/ssl/admin.crt;
|
||||
ssl_certificate_key /opt/jiebanke/ssl/admin.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
root /var/www/admin;
|
||||
index index.html;
|
||||
|
||||
# 静态资源缓存
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# SPA路由支持
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# API代理
|
||||
location /api/ {
|
||||
proxy_pass http://api_backend;
|
||||
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;
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
}
|
||||
|
||||
# API服务
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.jiebanke.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name api.jiebanke.com;
|
||||
|
||||
# SSL配置
|
||||
ssl_certificate /opt/jiebanke/ssl/api.crt;
|
||||
ssl_certificate_key /opt/jiebanke/ssl/api.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# API代理
|
||||
location / {
|
||||
proxy_pass http://api_backend;
|
||||
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;
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
|
||||
# CORS配置
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7. SSL证书配置
|
||||
|
||||
### 7.1 Let's Encrypt证书
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# ssl-setup.sh - SSL证书配置脚本
|
||||
|
||||
# 安装certbot
|
||||
sudo yum install -y certbot python3-certbot-nginx
|
||||
|
||||
# 申请证书
|
||||
sudo certbot --nginx -d admin.jiebanke.com -d api.jiebanke.com
|
||||
|
||||
# 设置自动续期
|
||||
echo "0 12 * * * /usr/bin/certbot renew --quiet" | sudo crontab -
|
||||
```
|
||||
|
||||
### 7.2 证书更新脚本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# renew-ssl.sh - SSL证书更新脚本
|
||||
|
||||
# 更新证书
|
||||
certbot renew --quiet
|
||||
|
||||
# 重载Nginx
|
||||
if [ $? -eq 0 ]; then
|
||||
nginx -s reload
|
||||
echo "SSL证书更新成功"
|
||||
else
|
||||
echo "SSL证书更新失败"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
## 8. 监控和日志
|
||||
|
||||
### 8.1 系统监控
|
||||
|
||||
```yaml
|
||||
# docker-compose-monitoring.yml
|
||||
version: '3.8'
|
||||
services:
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
container_name: prometheus
|
||||
ports:
|
||||
- "9090:9090"
|
||||
volumes:
|
||||
- ./config/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
- prometheus_data:/prometheus
|
||||
command:
|
||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||
- '--storage.tsdb.path=/prometheus'
|
||||
- '--web.console.libraries=/etc/prometheus/console_libraries'
|
||||
- '--web.console.templates=/etc/prometheus/consoles'
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana:latest
|
||||
container_name: grafana
|
||||
ports:
|
||||
- "3001:3000"
|
||||
volumes:
|
||||
- grafana_data:/var/lib/grafana
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin123
|
||||
|
||||
node-exporter:
|
||||
image: prom/node-exporter:latest
|
||||
container_name: node-exporter
|
||||
ports:
|
||||
- "9100:9100"
|
||||
volumes:
|
||||
- /proc:/host/proc:ro
|
||||
- /sys:/host/sys:ro
|
||||
- /:/rootfs:ro
|
||||
command:
|
||||
- '--path.procfs=/host/proc'
|
||||
- '--path.sysfs=/host/sys'
|
||||
- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
|
||||
|
||||
volumes:
|
||||
prometheus_data:
|
||||
grafana_data:
|
||||
```
|
||||
|
||||
### 8.2 日志管理
|
||||
|
||||
```yaml
|
||||
# docker-compose-logging.yml
|
||||
version: '3.8'
|
||||
services:
|
||||
elasticsearch:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:8.8.0
|
||||
container_name: elasticsearch
|
||||
environment:
|
||||
- discovery.type=single-node
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
- xpack.security.enabled=false
|
||||
ports:
|
||||
- "9200:9200"
|
||||
volumes:
|
||||
- elasticsearch_data:/usr/share/elasticsearch/data
|
||||
|
||||
logstash:
|
||||
image: docker.elastic.co/logstash/logstash:8.8.0
|
||||
container_name: logstash
|
||||
ports:
|
||||
- "5044:5044"
|
||||
volumes:
|
||||
- ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
|
||||
kibana:
|
||||
image: docker.elastic.co/kibana/kibana:8.8.0
|
||||
container_name: kibana
|
||||
ports:
|
||||
- "5601:5601"
|
||||
environment:
|
||||
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
|
||||
volumes:
|
||||
elasticsearch_data:
|
||||
```
|
||||
|
||||
## 9. 备份和恢复
|
||||
|
||||
### 9.1 数据库备份
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# backup-database.sh - 数据库备份脚本
|
||||
|
||||
BACKUP_DIR="/opt/jiebanke/backup/database"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
DB_NAME="jiebanke"
|
||||
DB_USER="root"
|
||||
DB_PASSWORD="your_password"
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# 备份数据库
|
||||
mysqldump -u"$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" > "$BACKUP_DIR/jiebanke_$DATE.sql"
|
||||
|
||||
# 压缩备份文件
|
||||
gzip "$BACKUP_DIR/jiebanke_$DATE.sql"
|
||||
|
||||
# 删除7天前的备份
|
||||
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -delete
|
||||
|
||||
echo "数据库备份完成: jiebanke_$DATE.sql.gz"
|
||||
```
|
||||
|
||||
### 9.2 文件备份
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# backup-files.sh - 文件备份脚本
|
||||
|
||||
BACKUP_DIR="/opt/jiebanke/backup/files"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
SOURCE_DIRS=("/opt/jiebanke/backend" "/var/www/admin" "/opt/jiebanke/data")
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# 备份文件
|
||||
for dir in "${SOURCE_DIRS[@]}"; do
|
||||
if [ -d "$dir" ]; then
|
||||
tar -czf "$BACKUP_DIR/$(basename $dir)_$DATE.tar.gz" -C "$(dirname $dir)" "$(basename $dir)"
|
||||
fi
|
||||
done
|
||||
|
||||
# 删除30天前的备份
|
||||
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete
|
||||
|
||||
echo "文件备份完成"
|
||||
```
|
||||
|
||||
## 10. 部署检查清单
|
||||
|
||||
### 10.1 部署前检查
|
||||
|
||||
- [ ] 服务器资源充足(CPU、内存、磁盘)
|
||||
- [ ] 网络连通性正常
|
||||
- [ ] 域名DNS解析配置
|
||||
- [ ] SSL证书准备就绪
|
||||
- [ ] 数据库连接测试
|
||||
- [ ] 缓存服务正常
|
||||
- [ ] 文件存储服务配置
|
||||
|
||||
### 10.2 部署后验证
|
||||
|
||||
- [ ] 服务启动状态检查
|
||||
- [ ] 接口功能测试
|
||||
- [ ] 前端页面访问测试
|
||||
- [ ] 数据库连接测试
|
||||
- [ ] 缓存功能测试
|
||||
- [ ] 日志输出正常
|
||||
- [ ] 监控指标正常
|
||||
- [ ] 备份任务配置
|
||||
|
||||
### 10.3 性能验证
|
||||
|
||||
- [ ] 接口响应时间 < 500ms
|
||||
- [ ] 页面加载时间 < 2s
|
||||
- [ ] 并发处理能力测试
|
||||
- [ ] 内存使用率 < 80%
|
||||
- [ ] CPU使用率 < 70%
|
||||
- [ ] 磁盘IO正常
|
||||
|
||||
## 11. 故障排查
|
||||
|
||||
### 11.1 常见问题
|
||||
|
||||
| 问题 | 可能原因 | 解决方案 |
|
||||
|------|----------|----------|
|
||||
| 服务无法启动 | 端口占用、配置错误 | 检查端口、配置文件 |
|
||||
| 数据库连接失败 | 网络、权限问题 | 检查网络、用户权限 |
|
||||
| 接口响应慢 | 数据库查询、网络延迟 | 优化查询、检查网络 |
|
||||
| 内存不足 | 内存泄漏、配置不当 | 检查内存使用、调整配置 |
|
||||
| SSL证书错误 | 证书过期、配置错误 | 更新证书、检查配置 |
|
||||
|
||||
### 11.2 日志查看命令
|
||||
|
||||
```bash
|
||||
# 查看应用日志
|
||||
pm2 logs jiebanke-api
|
||||
|
||||
# 查看Nginx日志
|
||||
tail -f /var/log/nginx/error.log
|
||||
tail -f /var/log/nginx/access.log
|
||||
|
||||
# 查看系统日志
|
||||
journalctl -u nginx -f
|
||||
journalctl -u docker -f
|
||||
|
||||
# 查看容器日志
|
||||
docker logs -f mysql-master
|
||||
docker logs -f redis-master
|
||||
```
|
||||
|
||||
## 12. 总结
|
||||
|
||||
本部署文档涵盖了解班客项目的完整部署流程,包括:
|
||||
|
||||
- **基础环境**:服务器配置、软件安装
|
||||
- **数据库部署**:MySQL主从、Redis集群
|
||||
- **应用部署**:后端API、前端应用
|
||||
- **负载均衡**:Nginx配置、SSL证书
|
||||
- **监控日志**:系统监控、日志管理
|
||||
- **备份恢复**:数据备份、故障恢复
|
||||
|
||||
通过遵循本文档的部署流程,可以确保系统的稳定性、可靠性和可维护性。
|
||||
@@ -1,859 +0,0 @@
|
||||
# 错误处理和日志系统文档
|
||||
|
||||
## 概述
|
||||
|
||||
错误处理和日志系统是解班客平台的核心基础设施,提供统一的错误处理机制、完善的日志记录功能和系统监控能力。系统采用分层设计,支持多种错误类型处理、多级日志记录和实时监控。
|
||||
|
||||
## 系统架构
|
||||
|
||||
### 核心组件
|
||||
|
||||
1. **错误处理中间件** (`middleware/errorHandler.js`)
|
||||
- 全局错误捕获
|
||||
- 错误分类处理
|
||||
- 统一错误响应
|
||||
- 错误日志记录
|
||||
|
||||
2. **日志记录系统** (`utils/logger.js`)
|
||||
- 多级日志记录
|
||||
- 日志格式化
|
||||
- 日志轮转管理
|
||||
- 性能监控
|
||||
|
||||
3. **自定义错误类**
|
||||
- 业务错误定义
|
||||
- 错误码管理
|
||||
- 错误信息国际化
|
||||
- 错误堆栈追踪
|
||||
|
||||
## 错误处理机制
|
||||
|
||||
### 错误分类
|
||||
|
||||
#### 1. 业务错误 (Business Errors)
|
||||
- **用户认证错误**: 登录失败、token过期等
|
||||
- **权限错误**: 无权限访问、操作被拒绝等
|
||||
- **数据验证错误**: 参数格式错误、必填项缺失等
|
||||
- **业务逻辑错误**: 余额不足、状态不允许等
|
||||
|
||||
#### 2. 系统错误 (System Errors)
|
||||
- **数据库错误**: 连接失败、查询超时等
|
||||
- **网络错误**: 请求超时、连接中断等
|
||||
- **文件系统错误**: 文件不存在、权限不足等
|
||||
- **第三方服务错误**: API调用失败、服务不可用等
|
||||
|
||||
#### 3. 程序错误 (Programming Errors)
|
||||
- **语法错误**: 代码语法问题
|
||||
- **运行时错误**: 空指针、类型错误等
|
||||
- **内存错误**: 内存溢出、内存泄漏等
|
||||
- **配置错误**: 配置文件错误、环境变量缺失等
|
||||
|
||||
### 错误处理流程
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[请求开始] --> B[业务逻辑处理]
|
||||
B --> C{是否发生错误?}
|
||||
C -->|否| D[正常响应]
|
||||
C -->|是| E[错误捕获]
|
||||
E --> F[错误分类]
|
||||
F --> G[错误日志记录]
|
||||
G --> H[错误响应格式化]
|
||||
H --> I[返回错误响应]
|
||||
D --> J[请求结束]
|
||||
I --> J
|
||||
```
|
||||
|
||||
### 自定义错误类
|
||||
|
||||
#### AppError 类
|
||||
```javascript
|
||||
class AppError extends Error {
|
||||
constructor(message, statusCode, errorCode = null, isOperational = true) {
|
||||
super(message);
|
||||
|
||||
this.statusCode = statusCode;
|
||||
this.errorCode = errorCode;
|
||||
this.isOperational = isOperational;
|
||||
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
|
||||
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误类型定义
|
||||
```javascript
|
||||
const ErrorTypes = {
|
||||
// 认证相关错误
|
||||
AUTH_TOKEN_MISSING: { code: 'AUTH_001', message: '缺少认证令牌' },
|
||||
AUTH_TOKEN_INVALID: { code: 'AUTH_002', message: '无效的认证令牌' },
|
||||
AUTH_TOKEN_EXPIRED: { code: 'AUTH_003', message: '认证令牌已过期' },
|
||||
|
||||
// 权限相关错误
|
||||
PERMISSION_DENIED: { code: 'PERM_001', message: '权限不足' },
|
||||
RESOURCE_FORBIDDEN: { code: 'PERM_002', message: '资源访问被禁止' },
|
||||
|
||||
// 验证相关错误
|
||||
VALIDATION_FAILED: { code: 'VALID_001', message: '数据验证失败' },
|
||||
REQUIRED_FIELD_MISSING: { code: 'VALID_002', message: '必填字段缺失' },
|
||||
INVALID_FORMAT: { code: 'VALID_003', message: '数据格式无效' },
|
||||
|
||||
// 业务逻辑错误
|
||||
RESOURCE_NOT_FOUND: { code: 'BIZ_001', message: '资源不存在' },
|
||||
RESOURCE_ALREADY_EXISTS: { code: 'BIZ_002', message: '资源已存在' },
|
||||
OPERATION_NOT_ALLOWED: { code: 'BIZ_003', message: '操作不被允许' },
|
||||
|
||||
// 系统错误
|
||||
DATABASE_ERROR: { code: 'SYS_001', message: '数据库操作失败' },
|
||||
FILE_SYSTEM_ERROR: { code: 'SYS_002', message: '文件系统错误' },
|
||||
NETWORK_ERROR: { code: 'SYS_003', message: '网络连接错误' },
|
||||
|
||||
// 第三方服务错误
|
||||
THIRD_PARTY_SERVICE_ERROR: { code: 'EXT_001', message: '第三方服务错误' },
|
||||
API_RATE_LIMIT_EXCEEDED: { code: 'EXT_002', message: 'API调用频率超限' }
|
||||
};
|
||||
```
|
||||
|
||||
### 错误响应格式
|
||||
|
||||
#### 标准错误响应
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "AUTH_002",
|
||||
"message": "无效的认证令牌",
|
||||
"details": "Token signature verification failed",
|
||||
"timestamp": "2024-01-15T10:30:00.000Z",
|
||||
"path": "/api/v1/admin/users",
|
||||
"method": "GET",
|
||||
"requestId": "req_1234567890"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 验证错误响应
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "VALID_001",
|
||||
"message": "数据验证失败",
|
||||
"details": {
|
||||
"email": ["邮箱格式不正确"],
|
||||
"password": ["密码长度至少8位", "密码必须包含数字和字母"]
|
||||
},
|
||||
"timestamp": "2024-01-15T10:30:00.000Z",
|
||||
"path": "/api/v1/auth/register",
|
||||
"method": "POST",
|
||||
"requestId": "req_1234567891"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 日志系统
|
||||
|
||||
### 日志级别
|
||||
|
||||
#### 1. ERROR (错误)
|
||||
- **用途**: 记录系统错误和异常
|
||||
- **示例**: 数据库连接失败、未捕获的异常
|
||||
- **处理**: 需要立即关注和处理
|
||||
|
||||
#### 2. WARN (警告)
|
||||
- **用途**: 记录潜在问题和警告信息
|
||||
- **示例**: 性能警告、配置问题
|
||||
- **处理**: 需要关注,但不影响系统运行
|
||||
|
||||
#### 3. INFO (信息)
|
||||
- **用途**: 记录重要的业务操作和系统状态
|
||||
- **示例**: 用户登录、重要配置变更
|
||||
- **处理**: 用于审计和监控
|
||||
|
||||
#### 4. HTTP (HTTP请求)
|
||||
- **用途**: 记录HTTP请求和响应信息
|
||||
- **示例**: API调用、响应时间
|
||||
- **处理**: 用于性能分析和调试
|
||||
|
||||
#### 5. DEBUG (调试)
|
||||
- **用途**: 记录详细的调试信息
|
||||
- **示例**: 变量值、执行流程
|
||||
- **处理**: 仅在开发环境使用
|
||||
|
||||
### 日志格式
|
||||
|
||||
#### 标准日志格式
|
||||
```
|
||||
[2024-01-15 10:30:00.123] [INFO] [USER_AUTH] 用户登录成功 - userId: 12345, ip: 192.168.1.100, userAgent: Mozilla/5.0...
|
||||
```
|
||||
|
||||
#### JSON格式日志
|
||||
```json
|
||||
{
|
||||
"timestamp": "2024-01-15T10:30:00.123Z",
|
||||
"level": "INFO",
|
||||
"category": "USER_AUTH",
|
||||
"message": "用户登录成功",
|
||||
"metadata": {
|
||||
"userId": 12345,
|
||||
"ip": "192.168.1.100",
|
||||
"userAgent": "Mozilla/5.0...",
|
||||
"requestId": "req_1234567890",
|
||||
"duration": 150
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 日志分类
|
||||
|
||||
#### 1. 请求日志 (Request Logs)
|
||||
```javascript
|
||||
// 记录HTTP请求信息
|
||||
logger.http('API请求', {
|
||||
method: 'POST',
|
||||
url: '/api/v1/users',
|
||||
ip: '192.168.1.100',
|
||||
userAgent: 'Mozilla/5.0...',
|
||||
requestId: 'req_1234567890',
|
||||
userId: 12345,
|
||||
duration: 150,
|
||||
statusCode: 200
|
||||
});
|
||||
```
|
||||
|
||||
#### 2. 业务日志 (Business Logs)
|
||||
```javascript
|
||||
// 记录业务操作
|
||||
logger.business('用户注册', {
|
||||
action: 'USER_REGISTER',
|
||||
userId: 12345,
|
||||
email: 'user@example.com',
|
||||
ip: '192.168.1.100',
|
||||
success: true
|
||||
});
|
||||
```
|
||||
|
||||
#### 3. 安全日志 (Security Logs)
|
||||
```javascript
|
||||
// 记录安全事件
|
||||
logger.security('登录失败', {
|
||||
event: 'LOGIN_FAILED',
|
||||
email: 'user@example.com',
|
||||
ip: '192.168.1.100',
|
||||
reason: 'INVALID_PASSWORD',
|
||||
attempts: 3
|
||||
});
|
||||
```
|
||||
|
||||
#### 4. 性能日志 (Performance Logs)
|
||||
```javascript
|
||||
// 记录性能数据
|
||||
logger.performance('数据库查询', {
|
||||
operation: 'SELECT',
|
||||
table: 'users',
|
||||
duration: 50,
|
||||
rowCount: 100,
|
||||
query: 'SELECT * FROM users WHERE status = ?'
|
||||
});
|
||||
```
|
||||
|
||||
#### 5. 系统日志 (System Logs)
|
||||
```javascript
|
||||
// 记录系统事件
|
||||
logger.system('服务启动', {
|
||||
event: 'SERVER_START',
|
||||
port: 3000,
|
||||
environment: 'production',
|
||||
version: '1.0.0'
|
||||
});
|
||||
```
|
||||
|
||||
### 日志存储和轮转
|
||||
|
||||
#### 日志文件结构
|
||||
```
|
||||
logs/
|
||||
├── app.log # 应用主日志
|
||||
├── error.log # 错误日志
|
||||
├── access.log # 访问日志
|
||||
├── security.log # 安全日志
|
||||
├── performance.log # 性能日志
|
||||
├── business.log # 业务日志
|
||||
└── archived/ # 归档日志
|
||||
├── app-2024-01-14.log
|
||||
├── error-2024-01-14.log
|
||||
└── ...
|
||||
```
|
||||
|
||||
#### 日志轮转配置
|
||||
```javascript
|
||||
const winston = require('winston');
|
||||
require('winston-daily-rotate-file');
|
||||
|
||||
const transport = new winston.transports.DailyRotateFile({
|
||||
filename: 'logs/app-%DATE%.log',
|
||||
datePattern: 'YYYY-MM-DD',
|
||||
zippedArchive: true,
|
||||
maxSize: '20m',
|
||||
maxFiles: '30d'
|
||||
});
|
||||
```
|
||||
|
||||
## 监控和告警
|
||||
|
||||
### 错误监控
|
||||
|
||||
#### 1. 错误率监控
|
||||
- **指标**: 每分钟错误数量、错误率
|
||||
- **阈值**: 错误率超过5%触发告警
|
||||
- **处理**: 自动发送告警通知
|
||||
|
||||
#### 2. 响应时间监控
|
||||
- **指标**: 平均响应时间、95%分位数
|
||||
- **阈值**: 响应时间超过2秒触发告警
|
||||
- **处理**: 性能优化建议
|
||||
|
||||
#### 3. 系统资源监控
|
||||
- **指标**: CPU使用率、内存使用率、磁盘空间
|
||||
- **阈值**: 资源使用率超过80%触发告警
|
||||
- **处理**: 资源扩容建议
|
||||
|
||||
### 日志分析
|
||||
|
||||
#### 1. 实时日志分析
|
||||
```javascript
|
||||
// 实时错误统计
|
||||
const errorStats = {
|
||||
total: 0,
|
||||
byType: {},
|
||||
byEndpoint: {},
|
||||
recentErrors: []
|
||||
};
|
||||
|
||||
// 更新错误统计
|
||||
function updateErrorStats(error, req) {
|
||||
errorStats.total++;
|
||||
errorStats.byType[error.code] = (errorStats.byType[error.code] || 0) + 1;
|
||||
errorStats.byEndpoint[req.path] = (errorStats.byEndpoint[req.path] || 0) + 1;
|
||||
|
||||
errorStats.recentErrors.unshift({
|
||||
timestamp: new Date(),
|
||||
code: error.code,
|
||||
message: error.message,
|
||||
path: req.path,
|
||||
method: req.method
|
||||
});
|
||||
|
||||
// 保持最近100个错误
|
||||
if (errorStats.recentErrors.length > 100) {
|
||||
errorStats.recentErrors.pop();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 日志聚合分析
|
||||
```javascript
|
||||
// 按时间段聚合日志
|
||||
function aggregateLogs(startTime, endTime) {
|
||||
return {
|
||||
totalRequests: 0,
|
||||
successRequests: 0,
|
||||
errorRequests: 0,
|
||||
averageResponseTime: 0,
|
||||
topEndpoints: [],
|
||||
topErrors: [],
|
||||
userActivity: {}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 告警机制
|
||||
|
||||
#### 1. 邮件告警
|
||||
```javascript
|
||||
const nodemailer = require('nodemailer');
|
||||
|
||||
async function sendErrorAlert(error, context) {
|
||||
const transporter = nodemailer.createTransporter({
|
||||
// 邮件服务配置
|
||||
});
|
||||
|
||||
const mailOptions = {
|
||||
from: 'system@jiebanke.com',
|
||||
to: 'admin@jiebanke.com',
|
||||
subject: `[解班客] 系统错误告警 - ${error.code}`,
|
||||
html: `
|
||||
<h2>系统错误告警</h2>
|
||||
<p><strong>错误代码:</strong> ${error.code}</p>
|
||||
<p><strong>错误信息:</strong> ${error.message}</p>
|
||||
<p><strong>发生时间:</strong> ${new Date().toLocaleString()}</p>
|
||||
<p><strong>请求路径:</strong> ${context.path}</p>
|
||||
<p><strong>用户ID:</strong> ${context.userId || '未知'}</p>
|
||||
<p><strong>IP地址:</strong> ${context.ip}</p>
|
||||
<pre><strong>错误堆栈:</strong>\n${error.stack}</pre>
|
||||
`
|
||||
};
|
||||
|
||||
await transporter.sendMail(mailOptions);
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 钉钉/企业微信告警
|
||||
```javascript
|
||||
async function sendDingTalkAlert(error, context) {
|
||||
const webhook = process.env.DINGTALK_WEBHOOK;
|
||||
|
||||
const message = {
|
||||
msgtype: 'markdown',
|
||||
markdown: {
|
||||
title: '系统错误告警',
|
||||
text: `
|
||||
### 系统错误告警
|
||||
- **错误代码**: ${error.code}
|
||||
- **错误信息**: ${error.message}
|
||||
- **发生时间**: ${new Date().toLocaleString()}
|
||||
- **请求路径**: ${context.path}
|
||||
- **用户ID**: ${context.userId || '未知'}
|
||||
- **IP地址**: ${context.ip}
|
||||
`
|
||||
}
|
||||
};
|
||||
|
||||
await fetch(webhook, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(message)
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 日志性能优化
|
||||
|
||||
#### 1. 异步日志写入
|
||||
```javascript
|
||||
const winston = require('winston');
|
||||
|
||||
const logger = winston.createLogger({
|
||||
transports: [
|
||||
new winston.transports.File({
|
||||
filename: 'logs/app.log',
|
||||
// 启用异步写入
|
||||
options: { flags: 'a' }
|
||||
})
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
#### 2. 日志缓冲
|
||||
```javascript
|
||||
class LogBuffer {
|
||||
constructor(flushInterval = 1000, maxBufferSize = 100) {
|
||||
this.buffer = [];
|
||||
this.flushInterval = flushInterval;
|
||||
this.maxBufferSize = maxBufferSize;
|
||||
|
||||
// 定时刷新缓冲区
|
||||
setInterval(() => this.flush(), flushInterval);
|
||||
}
|
||||
|
||||
add(logEntry) {
|
||||
this.buffer.push(logEntry);
|
||||
|
||||
// 缓冲区满时立即刷新
|
||||
if (this.buffer.length >= this.maxBufferSize) {
|
||||
this.flush();
|
||||
}
|
||||
}
|
||||
|
||||
flush() {
|
||||
if (this.buffer.length === 0) return;
|
||||
|
||||
const logs = this.buffer.splice(0);
|
||||
// 批量写入日志
|
||||
this.writeLogs(logs);
|
||||
}
|
||||
|
||||
writeLogs(logs) {
|
||||
// 实现批量日志写入
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 日志采样
|
||||
```javascript
|
||||
class LogSampler {
|
||||
constructor(sampleRate = 0.1) {
|
||||
this.sampleRate = sampleRate;
|
||||
}
|
||||
|
||||
shouldLog(level) {
|
||||
// 错误日志始终记录
|
||||
if (level === 'error') return true;
|
||||
|
||||
// 其他日志按采样率记录
|
||||
return Math.random() < this.sampleRate;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 错误处理性能优化
|
||||
|
||||
#### 1. 错误缓存
|
||||
```javascript
|
||||
const errorCache = new Map();
|
||||
|
||||
function cacheError(error, context) {
|
||||
const key = `${error.code}_${context.path}`;
|
||||
const cached = errorCache.get(key);
|
||||
|
||||
if (cached && Date.now() - cached.timestamp < 60000) {
|
||||
// 1分钟内相同错误不重复处理
|
||||
return false;
|
||||
}
|
||||
|
||||
errorCache.set(key, {
|
||||
timestamp: Date.now(),
|
||||
count: (cached?.count || 0) + 1
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 错误聚合
|
||||
```javascript
|
||||
class ErrorAggregator {
|
||||
constructor(windowSize = 60000) {
|
||||
this.windowSize = windowSize;
|
||||
this.errors = new Map();
|
||||
|
||||
// 定期清理过期错误
|
||||
setInterval(() => this.cleanup(), windowSize);
|
||||
}
|
||||
|
||||
add(error, context) {
|
||||
const key = `${error.code}_${context.path}`;
|
||||
const now = Date.now();
|
||||
|
||||
if (!this.errors.has(key)) {
|
||||
this.errors.set(key, {
|
||||
first: now,
|
||||
last: now,
|
||||
count: 1,
|
||||
error,
|
||||
context
|
||||
});
|
||||
} else {
|
||||
const entry = this.errors.get(key);
|
||||
entry.last = now;
|
||||
entry.count++;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
const now = Date.now();
|
||||
for (const [key, entry] of this.errors.entries()) {
|
||||
if (now - entry.last > this.windowSize) {
|
||||
this.errors.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基础错误处理
|
||||
|
||||
#### 1. 控制器中的错误处理
|
||||
```javascript
|
||||
const { AppError, ErrorTypes, catchAsync } = require('../middleware/errorHandler');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
// 获取用户信息
|
||||
const getUser = catchAsync(async (req, res, next) => {
|
||||
const { userId } = req.params;
|
||||
|
||||
// 参数验证
|
||||
if (!userId || !mongoose.Types.ObjectId.isValid(userId)) {
|
||||
return next(new AppError(
|
||||
ErrorTypes.INVALID_FORMAT.message,
|
||||
400,
|
||||
ErrorTypes.INVALID_FORMAT.code
|
||||
));
|
||||
}
|
||||
|
||||
// 查询用户
|
||||
const user = await User.findById(userId);
|
||||
if (!user) {
|
||||
return next(new AppError(
|
||||
ErrorTypes.RESOURCE_NOT_FOUND.message,
|
||||
404,
|
||||
ErrorTypes.RESOURCE_NOT_FOUND.code
|
||||
));
|
||||
}
|
||||
|
||||
// 权限检查
|
||||
if (req.user.id !== userId && req.user.role !== 'admin') {
|
||||
return next(new AppError(
|
||||
ErrorTypes.PERMISSION_DENIED.message,
|
||||
403,
|
||||
ErrorTypes.PERMISSION_DENIED.code
|
||||
));
|
||||
}
|
||||
|
||||
// 记录业务日志
|
||||
logger.business('查看用户信息', {
|
||||
action: 'VIEW_USER',
|
||||
targetUserId: userId,
|
||||
operatorId: req.user.id,
|
||||
ip: req.ip
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: { user }
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
#### 2. 数据库操作错误处理
|
||||
```javascript
|
||||
const { handleDatabaseError } = require('../middleware/errorHandler');
|
||||
|
||||
async function createUser(userData) {
|
||||
try {
|
||||
const user = new User(userData);
|
||||
await user.save();
|
||||
|
||||
logger.business('用户创建成功', {
|
||||
action: 'CREATE_USER',
|
||||
userId: user._id,
|
||||
email: user.email
|
||||
});
|
||||
|
||||
return user;
|
||||
} catch (error) {
|
||||
// 处理数据库错误
|
||||
throw handleDatabaseError(error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 高级日志记录
|
||||
|
||||
#### 1. 请求日志中间件使用
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const { requestLogger } = require('../utils/logger');
|
||||
|
||||
const app = express();
|
||||
|
||||
// 使用请求日志中间件
|
||||
app.use(requestLogger);
|
||||
|
||||
// 路由定义
|
||||
app.get('/api/users', (req, res) => {
|
||||
// 业务逻辑
|
||||
});
|
||||
```
|
||||
|
||||
#### 2. 性能监控
|
||||
```javascript
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
async function performDatabaseQuery(query) {
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
const result = await db.query(query);
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
// 记录性能日志
|
||||
logger.performance('数据库查询', {
|
||||
query: query.sql,
|
||||
duration,
|
||||
rowCount: result.length,
|
||||
success: true
|
||||
});
|
||||
|
||||
// 慢查询告警
|
||||
if (duration > 1000) {
|
||||
logger.warn('慢查询检测', {
|
||||
query: query.sql,
|
||||
duration,
|
||||
threshold: 1000
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
logger.performance('数据库查询失败', {
|
||||
query: query.sql,
|
||||
duration,
|
||||
error: error.message,
|
||||
success: false
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 安全事件记录
|
||||
```javascript
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
// 登录失败记录
|
||||
function recordLoginFailure(email, ip, reason) {
|
||||
logger.security('登录失败', {
|
||||
event: 'LOGIN_FAILED',
|
||||
email,
|
||||
ip,
|
||||
reason,
|
||||
timestamp: new Date(),
|
||||
severity: 'medium'
|
||||
});
|
||||
}
|
||||
|
||||
// 可疑活动记录
|
||||
function recordSuspiciousActivity(userId, activity, details) {
|
||||
logger.security('可疑活动', {
|
||||
event: 'SUSPICIOUS_ACTIVITY',
|
||||
userId,
|
||||
activity,
|
||||
details,
|
||||
timestamp: new Date(),
|
||||
severity: 'high'
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 1. 日志文件过大
|
||||
**问题**: 日志文件增长过快,占用大量磁盘空间
|
||||
**解决方案**:
|
||||
- 启用日志轮转
|
||||
- 调整日志级别
|
||||
- 实施日志采样
|
||||
- 定期清理旧日志
|
||||
|
||||
#### 2. 错误信息泄露
|
||||
**问题**: 错误响应包含敏感信息
|
||||
**解决方案**:
|
||||
- 使用统一错误响应格式
|
||||
- 过滤敏感信息
|
||||
- 区分开发和生产环境
|
||||
- 记录详细日志但返回简化错误
|
||||
|
||||
#### 3. 性能影响
|
||||
**问题**: 日志记录影响系统性能
|
||||
**解决方案**:
|
||||
- 使用异步日志写入
|
||||
- 实施日志缓冲
|
||||
- 优化日志格式
|
||||
- 使用日志采样
|
||||
|
||||
### 调试技巧
|
||||
|
||||
#### 1. 启用调试日志
|
||||
```javascript
|
||||
// 设置环境变量
|
||||
NODE_ENV=development
|
||||
LOG_LEVEL=debug
|
||||
|
||||
// 或在代码中动态设置
|
||||
logger.level = 'debug';
|
||||
```
|
||||
|
||||
#### 2. 错误追踪
|
||||
```javascript
|
||||
// 添加请求ID用于追踪
|
||||
const { v4: uuidv4 } = require('uuid');
|
||||
|
||||
app.use((req, res, next) => {
|
||||
req.requestId = uuidv4();
|
||||
res.setHeader('X-Request-ID', req.requestId);
|
||||
next();
|
||||
});
|
||||
|
||||
// 在日志中包含请求ID
|
||||
logger.info('处理请求', {
|
||||
requestId: req.requestId,
|
||||
method: req.method,
|
||||
url: req.url
|
||||
});
|
||||
```
|
||||
|
||||
#### 3. 错误重现
|
||||
```javascript
|
||||
// 保存错误上下文用于重现
|
||||
function saveErrorContext(error, req) {
|
||||
const context = {
|
||||
timestamp: new Date(),
|
||||
error: {
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
code: error.code
|
||||
},
|
||||
request: {
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
headers: req.headers,
|
||||
body: req.body,
|
||||
params: req.params,
|
||||
query: req.query
|
||||
},
|
||||
user: req.user,
|
||||
session: req.session
|
||||
};
|
||||
|
||||
// 保存到文件或数据库
|
||||
fs.writeFileSync(
|
||||
`error-contexts/${Date.now()}.json`,
|
||||
JSON.stringify(context, null, 2)
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 错误处理最佳实践
|
||||
|
||||
1. **统一错误格式**: 使用统一的错误响应格式
|
||||
2. **错误分类**: 明确区分业务错误和系统错误
|
||||
3. **错误码管理**: 使用有意义的错误码
|
||||
4. **安全考虑**: 不在错误响应中暴露敏感信息
|
||||
5. **用户友好**: 提供用户友好的错误信息
|
||||
|
||||
### 日志记录最佳实践
|
||||
|
||||
1. **结构化日志**: 使用JSON格式记录结构化数据
|
||||
2. **上下文信息**: 记录足够的上下文信息用于调试
|
||||
3. **性能考虑**: 避免日志记录影响系统性能
|
||||
4. **安全性**: 不在日志中记录敏感信息
|
||||
5. **可搜索性**: 使用一致的字段名和格式
|
||||
|
||||
### 监控告警最佳实践
|
||||
|
||||
1. **合理阈值**: 设置合理的告警阈值
|
||||
2. **告警分级**: 区分不同级别的告警
|
||||
3. **避免告警疲劳**: 防止过多无用告警
|
||||
4. **快速响应**: 建立快速响应机制
|
||||
5. **持续优化**: 根据实际情况调整监控策略
|
||||
|
||||
## 总结
|
||||
|
||||
错误处理和日志系统是解班客平台稳定运行的重要保障。通过统一的错误处理机制、完善的日志记录功能和实时监控告警,系统能够快速发现和解决问题,提供稳定可靠的服务。
|
||||
|
||||
系统采用分层设计,支持多种错误类型和日志级别,提供了灵活的配置选项和丰富的功能特性。通过性能优化和最佳实践,确保系统在高负载情况下仍能正常运行。
|
||||
|
||||
未来将继续完善系统功能,增加更多监控指标和告警机制,为平台的稳定运行提供更强有力的支持。
|
||||
285
docs/项目开发进度报告.md
285
docs/项目开发进度报告.md
@@ -1,285 +0,0 @@
|
||||
# 解班客项目开发进度报告
|
||||
|
||||
## 📋 项目概况
|
||||
|
||||
### 项目基本信息
|
||||
- **项目名称**:解班客 - 流浪动物救助平台
|
||||
- **项目类型**:Web应用 + 微信小程序
|
||||
- **开发周期**:2024年1月 - 2024年6月(预计)
|
||||
- **当前版本**:v0.8.0-beta
|
||||
- **项目状态**:开发阶段
|
||||
|
||||
### 团队组成
|
||||
| 角色 | 人数 | 主要职责 |
|
||||
|------|------|----------|
|
||||
| 项目经理 | 1 | 项目管理、进度控制、资源协调 |
|
||||
| 前端开发 | 2 | Vue.js开发、UI实现、用户体验优化 |
|
||||
| 后端开发 | 2 | Node.js API开发、数据库设计、系统架构 |
|
||||
| UI/UX设计师 | 1 | 界面设计、交互设计、视觉规范 |
|
||||
| 测试工程师 | 1 | 功能测试、性能测试、质量保证 |
|
||||
| 运维工程师 | 1 | 部署配置、监控运维、安全管理 |
|
||||
|
||||
## 📊 整体进度概览
|
||||
|
||||
### 项目里程碑
|
||||
```mermaid
|
||||
gantt
|
||||
title 解班客项目开发时间线
|
||||
dateFormat YYYY-MM-DD
|
||||
section 需求分析
|
||||
需求调研 :done, req1, 2024-01-01, 2024-01-15
|
||||
原型设计 :done, req2, 2024-01-10, 2024-01-25
|
||||
技术选型 :done, req3, 2024-01-20, 2024-01-30
|
||||
|
||||
section 系统设计
|
||||
架构设计 :done, arch1, 2024-01-25, 2024-02-10
|
||||
数据库设计 :done, arch2, 2024-02-05, 2024-02-20
|
||||
API设计 :done, arch3, 2024-02-15, 2024-02-28
|
||||
|
||||
section 开发阶段
|
||||
基础框架搭建 :done, dev1, 2024-03-01, 2024-03-15
|
||||
用户认证模块 :done, dev2, 2024-03-10, 2024-03-25
|
||||
动物管理模块 :done, dev3, 2024-03-20, 2024-04-10
|
||||
领养流程模块 :active, dev4, 2024-04-01, 2024-04-20
|
||||
管理后台模块 :active, dev5, 2024-04-10, 2024-04-30
|
||||
小程序开发 :dev6, 2024-04-15, 2024-05-10
|
||||
|
||||
section 测试阶段
|
||||
单元测试 :test1, 2024-04-20, 2024-05-05
|
||||
集成测试 :test2, 2024-05-01, 2024-05-15
|
||||
用户验收测试 :test3, 2024-05-10, 2024-05-25
|
||||
|
||||
section 部署上线
|
||||
生产环境部署 :deploy1, 2024-05-20, 2024-05-30
|
||||
正式发布 :deploy2, 2024-06-01, 2024-06-05
|
||||
```
|
||||
|
||||
### 当前进度统计
|
||||
| 模块 | 计划功能点 | 已完成 | 进行中 | 待开始 | 完成率 |
|
||||
|------|------------|--------|--------|--------|--------|
|
||||
| 用户认证 | 12 | 12 | 0 | 0 | 100% |
|
||||
| 动物管理 | 18 | 16 | 2 | 0 | 89% |
|
||||
| 领养流程 | 15 | 8 | 5 | 2 | 53% |
|
||||
| 内容管理 | 10 | 7 | 2 | 1 | 70% |
|
||||
| 管理后台 | 20 | 5 | 8 | 7 | 25% |
|
||||
| 小程序端 | 25 | 0 | 3 | 22 | 0% |
|
||||
| **总计** | **100** | **48** | **20** | **32** | **48%** |
|
||||
- **文件管理**: 文件上传、列表、删除、统计、清理功能
|
||||
- **系统监控**: 错误日志、性能监控、告警机制
|
||||
|
||||
#### 基础设施 (100%)
|
||||
- **文件上传系统**:
|
||||
- 支持多种文件类型(图片、文档等)
|
||||
- 图片自动压缩和缩略图生成
|
||||
- 文件分类存储和管理
|
||||
- 安全验证和大小限制
|
||||
|
||||
- **错误处理系统**:
|
||||
- 统一错误处理中间件
|
||||
- 自定义错误类型
|
||||
- 详细的错误日志记录
|
||||
- 友好的错误响应格式
|
||||
|
||||
- **日志系统**:
|
||||
- 多级别日志记录(error, warn, info, debug)
|
||||
- 日志文件自动轮转
|
||||
- 结构化日志格式
|
||||
- 性能监控和统计
|
||||
|
||||
### ✅ 数据库设计 (95%)
|
||||
|
||||
#### 核心数据表
|
||||
- **用户表** (users): 用户基本信息、认证信息
|
||||
- **动物表** (animals): 动物详细信息、状态管理
|
||||
- **认领表** (adoptions): 认领申请、审核流程
|
||||
- **消息表** (messages): 站内消息系统
|
||||
- **文件表** (files): 文件上传记录
|
||||
- **管理员表** (admins): 管理员账户信息
|
||||
- **日志表** (logs): 系统操作日志
|
||||
|
||||
#### 数据关系
|
||||
- 完整的外键约束设计
|
||||
- 索引优化配置
|
||||
- 数据完整性保证
|
||||
|
||||
### ✅ 文档系统 (100%)
|
||||
|
||||
#### 完整文档体系
|
||||
1. **[API接口文档](API接口文档.md)** - 详细的API接口说明
|
||||
2. **[数据库设计文档](数据库设计文档.md)** - 完整的数据库设计
|
||||
3. **[前端开发文档](前端开发文档.md)** - 前端架构和开发规范
|
||||
4. **[后端开发文档](后端开发文档.md)** - 后端架构和开发规范
|
||||
5. **[管理员后台系统API文档](管理员后台系统API文档.md)** - 管理后台功能说明
|
||||
6. **[文件上传系统文档](文件上传系统文档.md)** - 文件系统详细说明
|
||||
7. **[错误处理和日志系统文档](错误处理和日志系统文档.md)** - 错误处理机制
|
||||
8. **[系统集成和部署文档](系统集成和部署文档.md)** - 部署和运维指南
|
||||
|
||||
## 🔄 进行中的工作
|
||||
|
||||
### 前端用户界面 (60%)
|
||||
|
||||
#### 已完成
|
||||
- 项目基础架构搭建
|
||||
- Vue 3 + Element Plus 环境配置
|
||||
- 基础路由和状态管理
|
||||
- 用户认证组件
|
||||
|
||||
#### 进行中
|
||||
- 动物列表和详情页面
|
||||
- 认领申请流程界面
|
||||
- 个人中心页面
|
||||
- 地图集成功能
|
||||
|
||||
### 部署配置 (80%)
|
||||
|
||||
#### 已完成
|
||||
- Docker 容器化配置
|
||||
- Docker Compose 多服务编排
|
||||
- Nginx 反向代理配置
|
||||
- 环境变量管理
|
||||
|
||||
#### 进行中
|
||||
- Kubernetes 部署配置
|
||||
- CI/CD 流水线优化
|
||||
- 监控和告警系统集成
|
||||
|
||||
## 📋 待完成任务
|
||||
|
||||
### 高优先级
|
||||
|
||||
1. **前端开发完善** (预计2周)
|
||||
- 完成核心页面开发
|
||||
- 实现响应式设计
|
||||
- 添加用户交互功能
|
||||
- 集成地图API
|
||||
|
||||
2. **测试用例编写** (预计1周)
|
||||
- 单元测试覆盖
|
||||
- 集成测试
|
||||
- API接口测试
|
||||
- 前端组件测试
|
||||
|
||||
3. **性能优化** (预计1周)
|
||||
- 数据库查询优化
|
||||
- 缓存策略实施
|
||||
- 前端资源优化
|
||||
- 接口响应时间优化
|
||||
|
||||
### 中优先级
|
||||
|
||||
4. **安全加固** (预计1周)
|
||||
- 输入验证增强
|
||||
- SQL注入防护
|
||||
- XSS攻击防护
|
||||
- 权限控制完善
|
||||
|
||||
5. **监控完善** (预计3天)
|
||||
- 应用性能监控
|
||||
- 业务指标监控
|
||||
- 告警规则配置
|
||||
- 日志分析优化
|
||||
|
||||
### 低优先级
|
||||
|
||||
6. **功能扩展** (预计2周)
|
||||
- 微信小程序开发
|
||||
- 移动端适配
|
||||
- 第三方登录集成
|
||||
- 支付功能集成
|
||||
|
||||
## 🎯 里程碑计划
|
||||
|
||||
### 第一阶段 - MVP版本 (已完成 90%)
|
||||
- ✅ 核心后端API开发
|
||||
- ✅ 管理员后台系统
|
||||
- ✅ 基础设施搭建
|
||||
- ✅ 文档体系建立
|
||||
- 🔄 前端基础功能 (60%)
|
||||
|
||||
### 第二阶段 - 完整版本 (计划中)
|
||||
- 📋 前端功能完善
|
||||
- 📋 测试用例补充
|
||||
- 📋 性能优化
|
||||
- 📋 安全加固
|
||||
|
||||
### 第三阶段 - 扩展版本 (规划中)
|
||||
- 📋 移动端应用
|
||||
- 📋 高级功能
|
||||
- 📋 第三方集成
|
||||
- 📋 数据分析
|
||||
|
||||
## 📊 技术指标
|
||||
|
||||
### 代码质量
|
||||
- **后端代码行数**: ~8,000行
|
||||
- **前端代码行数**: ~3,000行 (进行中)
|
||||
- **测试覆盖率**: 40% (目标: 80%)
|
||||
- **文档完整度**: 100%
|
||||
|
||||
### 性能指标
|
||||
- **API响应时间**: <200ms (目标)
|
||||
- **数据库查询**: <100ms (目标)
|
||||
- **页面加载时间**: <2s (目标)
|
||||
- **并发用户数**: 1000+ (目标)
|
||||
|
||||
### 功能完整度
|
||||
- **用户功能**: 85%
|
||||
- **管理功能**: 95%
|
||||
- **系统功能**: 90%
|
||||
- **文档系统**: 100%
|
||||
|
||||
## 🚀 下一步计划
|
||||
|
||||
### 本周计划 (第1周)
|
||||
1. 完成前端动物列表页面
|
||||
2. 实现认领申请流程
|
||||
3. 添加地图集成功能
|
||||
4. 编写核心API测试用例
|
||||
|
||||
### 下周计划 (第2周)
|
||||
1. 完善用户个人中心
|
||||
2. 优化移动端适配
|
||||
3. 性能测试和优化
|
||||
4. 安全测试和加固
|
||||
|
||||
### 月度计划 (第3-4周)
|
||||
1. 完成所有前端功能
|
||||
2. 达到80%测试覆盖率
|
||||
3. 部署生产环境
|
||||
4. 用户验收测试
|
||||
|
||||
## 🔍 风险评估
|
||||
|
||||
### 技术风险
|
||||
- **前端开发进度**: 中等风险,需要加快开发速度
|
||||
- **性能优化**: 低风险,已有完善的架构基础
|
||||
- **安全问题**: 低风险,已实施基础安全措施
|
||||
|
||||
### 项目风险
|
||||
- **时间进度**: 中等风险,前端开发可能延期
|
||||
- **资源投入**: 低风险,技术栈成熟稳定
|
||||
- **需求变更**: 低风险,需求相对稳定
|
||||
|
||||
## 📝 总结
|
||||
|
||||
项目整体进展良好,后端系统和基础设施已基本完成,文档体系完整。当前主要工作集中在前端开发和测试完善上。预计在接下来的4周内可以完成MVP版本的开发,并进入测试和优化阶段。
|
||||
|
||||
### 主要成就
|
||||
1. ✅ 完整的后端API系统
|
||||
2. ✅ 功能完善的管理后台
|
||||
3. ✅ 健壮的基础设施
|
||||
4. ✅ 完整的文档体系
|
||||
5. ✅ 规范的开发流程
|
||||
|
||||
### 关键挑战
|
||||
1. 🔄 前端开发进度需要加快
|
||||
2. 📋 测试用例需要补充完善
|
||||
3. 📋 性能优化需要持续关注
|
||||
|
||||
项目有望按计划在预定时间内完成,为用户提供一个功能完整、性能优秀的宠物认领平台。
|
||||
|
||||
---
|
||||
|
||||
**报告生成时间**: 2024年1月15日
|
||||
**下次更新**: 2024年1月22日
|
||||
**报告人**: 开发团队
|
||||
229
docs/项目概述.md
229
docs/项目概述.md
@@ -1,229 +0,0 @@
|
||||
# 结伴客项目概述
|
||||
|
||||
## 📋 项目简介
|
||||
|
||||
结伴客是一个创新的社交旅行平台,专注于为用户提供结伴旅行服务,并融入了独特的动物认领功能。该项目包含微信小程序、后台管理系统和官方网站三个核心模块,为用户和商家提供完整的服务生态。
|
||||
|
||||
## 🎯 产品定位
|
||||
|
||||
结伴客不仅仅是一个旅行社交平台,更是一个融合了农场体验、动物互动的创新服务平台。通过结合传统的结伴旅行功能与现代的动物认领体验,为用户创造独特的旅行记忆。
|
||||
|
||||
## 👥 目标用户
|
||||
|
||||
### 普通用户
|
||||
- 热爱旅行的年轻人群
|
||||
- 希望通过旅行结识新朋友的用户
|
||||
- 对农场生活和动物互动感兴趣的用户
|
||||
- 追求个性化旅行体验的用户
|
||||
|
||||
### 商家用户
|
||||
- **花店商家**:提供鲜花产品和相关服务
|
||||
- **活动组织者**:组织各类结伴活动和旅行项目
|
||||
- **农场主**:提供动物认领和农场体验服务
|
||||
- **旅行服务商**:提供专业的旅行规划和服务
|
||||
|
||||
## 🌟 核心功能
|
||||
|
||||
### 结伴旅行
|
||||
- 智能匹配系统,根据兴趣爱好和行程安排匹配旅伴
|
||||
- 多样化的活动类型:旅行、看电影、聚餐、桌游等
|
||||
- 基于地理位置的本地化服务推荐
|
||||
|
||||
### 动物认领
|
||||
- 提供牛、羊、猪、鸡等多种动物的认领服务
|
||||
- 实时动物状态更新和成长记录
|
||||
- 农场实地探访和互动体验
|
||||
|
||||
### 商家服务
|
||||
- 完善的商家入驻和管理系统
|
||||
- 多元化的产品和服务展示平台
|
||||
- 订单管理和客户服务支持
|
||||
|
||||
## 🏗️ 技术架构
|
||||
|
||||
### 前端技术栈
|
||||
- **微信小程序**:原生小程序开发 + Vant Weapp UI组件
|
||||
- **后台管理系统**:Vue 3 + TypeScript + Element Plus
|
||||
- **官方网站**:Vue 3 + Vue Router + 响应式设计
|
||||
|
||||
### 后端技术栈
|
||||
- **Node.js版本**:Express.js + Sequelize ORM + MySQL
|
||||
- **Java微服务版本**:Spring Boot + Spring Cloud + MyBatis Plus
|
||||
- **数据存储**:MySQL 8.0 + Redis缓存
|
||||
- **认证授权**:JWT Token + 微信OAuth
|
||||
|
||||
### 部署架构
|
||||
- **容器化部署**:Docker + Docker Compose
|
||||
- **负载均衡**:Nginx反向代理
|
||||
- **数据库**:MySQL主从复制
|
||||
- **缓存系统**:Redis集群
|
||||
|
||||
## 📁 项目结构
|
||||
|
||||
```
|
||||
jiebanke/
|
||||
├── mini-program/ # 微信小程序
|
||||
├── admin-system/ # 后台管理系统
|
||||
├── website/ # 官方网站
|
||||
├── backend/ # Node.js后端服务
|
||||
├── backend-java/ # Java微服务后端
|
||||
├── fastapi-backend/ # FastAPI后端(实验性)
|
||||
├── docs/ # 项目文档
|
||||
└── scripts/ # 部署和工具脚本
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 环境要求
|
||||
- Node.js 16.x 或更高版本
|
||||
- MySQL 8.0+
|
||||
- Redis 6.0+(可选)
|
||||
- 微信开发者工具
|
||||
|
||||
### 安装步骤
|
||||
1. 克隆项目代码
|
||||
2. 安装项目依赖
|
||||
3. 配置数据库连接
|
||||
4. 启动开发服务器
|
||||
|
||||
详细的安装和部署说明请参考 [部署指南](./部署指南.md)
|
||||
|
||||
## 📚 文档导航
|
||||
|
||||
- [产品需求文档](./产品需求文档.md) - 详细的功能需求和业务逻辑
|
||||
- [系统架构文档](./系统架构文档.md) - 技术架构和系统设计
|
||||
- [API接口文档](./API接口文档.md) - 完整的API接口说明
|
||||
- [数据库设计文档](./数据库设计文档.md) - 数据库表结构和关系
|
||||
- [部署指南](./部署指南.md) - 系统部署和运维说明
|
||||
- [开发指南](./开发指南.md) - 开发规范和最佳实践
|
||||
|
||||
## 🔄 开发状态
|
||||
|
||||
### 当前版本
|
||||
- **版本号**:v1.0.0-beta
|
||||
- **发布状态**:开发中 (MVP阶段)
|
||||
- **最新更新**:2024年1月15日
|
||||
- **整体完成度**:85%
|
||||
|
||||
### 功能完成度
|
||||
|
||||
#### ✅ 已完成模块 (90%+)
|
||||
- **Node.js后端API** (90%):核心业务逻辑、用户管理、动物管理、认领系统
|
||||
- **管理员后台系统** (95%):用户管理、动物管理、数据统计、文件管理
|
||||
- **文件上传系统** (100%):图片上传、处理、存储、管理
|
||||
- **错误处理系统** (100%):统一错误处理、日志记录、监控告警
|
||||
- **数据库设计** (95%):完整的表结构设计、索引优化
|
||||
- **API文档** (100%):详细的接口文档、OpenAPI规范
|
||||
- **部署配置** (80%):Docker容器化、CI/CD流水线
|
||||
|
||||
#### 🚧 进行中模块 (50%-80%)
|
||||
- **前端用户界面** (60%):Vue.js框架搭建、基础组件开发
|
||||
- **微信小程序** (70%):核心功能完成,UI优化中
|
||||
- **官方网站** (80%):静态页面完成,动态功能开发中
|
||||
- **Java微服务后端** (40%):架构设计完成,服务开发中
|
||||
|
||||
#### 📋 待开始模块 (0%-40%)
|
||||
- **移动端APP** (0%):规划中,预计Q2开始
|
||||
- **测试用例** (40%):部分单元测试完成,集成测试待补充
|
||||
- **性能优化** (30%):基础优化完成,深度优化待进行
|
||||
- **安全加固** (50%):基础安全措施完成,高级安全待实施
|
||||
|
||||
### 技术指标
|
||||
- **代码质量**:后端8000+行,前端3000+行
|
||||
- **测试覆盖率**:40% (目标80%)
|
||||
- **文档完整度**:100%
|
||||
- **API响应时间**:<200ms (目标)
|
||||
- **并发支持**:1000+ (目标)
|
||||
|
||||
### 开发里程碑
|
||||
|
||||
#### 第一阶段 - MVP版本 (当前阶段)
|
||||
- ✅ 后端核心API开发 (90%)
|
||||
- ✅ 管理员后台系统 (95%)
|
||||
- ✅ 基础设施搭建 (100%)
|
||||
- ✅ 文档体系建立 (100%)
|
||||
- 🚧 前端用户界面 (60%)
|
||||
|
||||
#### 第二阶段 - 完整版本 (计划中)
|
||||
- 📋 前端功能完善
|
||||
- 📋 测试用例补充
|
||||
- 📋 性能优化
|
||||
- 📋 安全加固
|
||||
|
||||
#### 第三阶段 - 扩展版本 (规划中)
|
||||
- 📋 Java微服务架构
|
||||
- 📋 移动端应用
|
||||
- 📋 高级功能扩展
|
||||
- 📋 第三方集成
|
||||
|
||||
### 近期规划
|
||||
- **本周目标**:完成前端动物列表页面,实现认领申请流程
|
||||
- **本月目标**:前端核心功能完成,测试覆盖率达到60%
|
||||
- **下月目标**:MVP版本发布,用户验收测试
|
||||
- **季度目标**:完整版本上线,支持1000+并发用户
|
||||
|
||||
## 🏆 项目特色
|
||||
|
||||
### 创新亮点
|
||||
1. **独特的动物认领模式**:将传统农场体验与现代科技结合
|
||||
2. **智能匹配算法**:基于用户兴趣和地理位置的精准匹配
|
||||
3. **多端统一体验**:小程序、网站、管理后台无缝衔接
|
||||
4. **灵活的商家生态**:支持多种类型商家入驻和服务
|
||||
|
||||
### 技术优势
|
||||
1. **现代化架构**:采用微服务架构,支持水平扩展
|
||||
2. **多语言支持**:Node.js和Java双后端架构
|
||||
3. **容器化部署**:Docker容器化,支持云原生部署
|
||||
4. **完善的监控**:全链路监控和日志管理
|
||||
|
||||
## 📊 业务数据
|
||||
|
||||
### 用户规模(预期)
|
||||
- **目标用户**:10万+注册用户
|
||||
- **日活用户**:5000+
|
||||
- **月活用户**:30000+
|
||||
- **商家数量**:500+
|
||||
|
||||
### 业务指标
|
||||
- **活动发布**:每日100+个活动
|
||||
- **成功匹配**:每日50+次成功匹配
|
||||
- **动物认领**:累计1000+只动物被认领
|
||||
- **订单量**:每月2000+订单
|
||||
|
||||
## 🔐 安全与合规
|
||||
|
||||
### 数据安全
|
||||
- **数据加密**:敏感数据AES-256加密存储
|
||||
- **传输安全**:全站HTTPS,API接口SSL加密
|
||||
- **访问控制**:基于角色的权限管理(RBAC)
|
||||
- **数据备份**:每日自动备份,异地容灾
|
||||
|
||||
### 隐私保护
|
||||
- **用户隐私**:严格遵守《个人信息保护法》
|
||||
- **数据最小化**:仅收集必要的用户信息
|
||||
- **用户授权**:明确的隐私政策和用户授权
|
||||
- **数据删除**:支持用户数据删除请求
|
||||
|
||||
## 📞 联系我们
|
||||
|
||||
### 开发团队
|
||||
- **项目负责人**:dev@jiebanke.com
|
||||
- **技术支持**:tech@jiebanke.com
|
||||
- **产品反馈**:feedback@jiebanke.com
|
||||
- **商务合作**:business@jiebanke.com
|
||||
|
||||
### 社区资源
|
||||
- **GitHub仓库**:https://github.com/jiebanke/jiebanke
|
||||
- **技术文档**:https://docs.jiebanke.com
|
||||
- **API文档**:https://api.jiebanke.com/docs
|
||||
- **用户社区**:https://community.jiebanke.com
|
||||
|
||||
### 支持渠道
|
||||
- **在线客服**:工作日 9:00-18:00
|
||||
- **技术QQ群**:123456789
|
||||
- **微信群**:扫描二维码加入
|
||||
- **邮件支持**:24小时内回复
|
||||
|
||||
---
|
||||
|
||||
*文档版本:v1.2 | 最后更新时间:2024年1月20日 | 维护者:结伴客开发团队*
|
||||
@@ -36,6 +36,18 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="about.html">关于我们</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="travel.html">旅行结伴</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="animal.html">动物认领</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="flower.html">送花服务</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="reward.html">推广奖励</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="case.html">成功案例</a>
|
||||
</li>
|
||||
@@ -192,7 +204,7 @@
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card team-card text-center">
|
||||
<img src="images/team-member1.jpg" class="card-img-top rounded-circle mx-auto mt-4" alt="CEO 张总" width="150" height="150">
|
||||
<img src="images/ceo-avatar.svg" class="card-img-top rounded-circle mx-auto mt-4" alt="CEO 张总" width="150" height="150">
|
||||
<div class="card-body">
|
||||
<h3 class="h5 card-title">张总</h3>
|
||||
<p class="card-text text-muted">创始人兼CEO</p>
|
||||
@@ -203,7 +215,7 @@
|
||||
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card team-card text-center">
|
||||
<img src="images/team-member2.jpg" class="card-img-top rounded-circle mx-auto mt-4" alt="CTO 李博士" width="150" height="150">
|
||||
<img src="images/cto-avatar.svg" class="card-img-top rounded-circle mx-auto mt-4" alt="CTO 李博士" width="150" height="150">
|
||||
<div class="card-body">
|
||||
<h3 class="h5 card-title">李博士</h3>
|
||||
<p class="card-text text-muted">首席技术官</p>
|
||||
@@ -214,7 +226,7 @@
|
||||
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card team-card text-center">
|
||||
<img src="images/team-member3.jpg" class="card-img-top rounded-circle mx-auto mt-4" alt="COO 王女士" width="150" height="150">
|
||||
<img src="images/coo-avatar.svg" class="card-img-top rounded-circle mx-auto mt-4" alt="COO 王女士" width="150" height="150">
|
||||
<div class="card-body">
|
||||
<h3 class="h5 card-title">王女士</h3>
|
||||
<p class="card-text text-muted">首席运营官</p>
|
||||
@@ -310,6 +322,7 @@
|
||||
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="js/enhanced-interactions.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -62,16 +62,12 @@
|
||||
</nav>
|
||||
|
||||
<!-- 动物认领横幅 -->
|
||||
<section class="page-header animal-header">
|
||||
<div class="container h-100">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col-12 text-center text-white">
|
||||
<h1 class="display-3 fw-bold mb-4">动物认领</h1>
|
||||
<p class="lead mb-5 fs-4">认领可爱的动物,体验农场生活<br>与动物建立深厚的情感纽带</p>
|
||||
<a href="#animals" class="btn btn-light btn-lg btn-rounded me-3">查看可认领动物</a>
|
||||
<a href="#process" class="btn btn-outline-light btn-lg btn-rounded">了解认领流程</a>
|
||||
</div>
|
||||
</div>
|
||||
<section class="hero-section animal-hero">
|
||||
<div class="container text-center position-relative">
|
||||
<h1 class="display-2 fw-bold mb-4">动物认领</h1>
|
||||
<p class="lead mb-5 fs-4">认领可爱的动物,体验农场生活<br>与动物建立深厚的情感纽带</p>
|
||||
<a href="#animals" class="btn btn-light btn-lg btn-rounded me-3">查看可认领动物</a>
|
||||
<a href="#process" class="btn btn-outline-light btn-lg btn-rounded">了解认领流程</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -217,7 +213,7 @@
|
||||
<!-- 动物卡片将通过JS动态加载 -->
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card animal-card h-100">
|
||||
<img src="images/animal1.svg" class="card-img-top" alt="小羊">
|
||||
<img src="images/sheep1.svg" class="card-img-top" alt="小羊">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<h5 class="card-title">小羊咩咩</h5>
|
||||
@@ -236,7 +232,7 @@
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card animal-card h-100">
|
||||
<img src="images/animal2.svg" class="card-img-top" alt="小兔">
|
||||
<img src="images/rabbit1.svg" class="card-img-top" alt="小兔">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<h5 class="card-title">小白兔</h5>
|
||||
@@ -255,7 +251,7 @@
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card animal-card h-100">
|
||||
<img src="images/animal3.svg" class="card-img-top" alt="小鸡">
|
||||
<img src="images/chicken1.svg" class="card-img-top" alt="小鸡">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<h5 class="card-title">小花鸡</h5>
|
||||
@@ -341,7 +337,7 @@
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<img src="images/animal-success1.jpg" class="card-img-top" alt="小羊认领">
|
||||
<img src="images/animal-case1.svg" class="card-img-top" alt="小羊认领">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">小羊咩咩的成长故事</h5>
|
||||
<p class="card-text">来自北京的李女士认领了这只小羊,每月都会收到小羊的成长照片和视频,还专程到农场探访。</p>
|
||||
@@ -354,7 +350,7 @@
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<img src="images/animal-success2.jpg" class="card-img-top" alt="兔子认领">
|
||||
<img src="images/animal-case2.svg" class="card-img-top" alt="兔子认领">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">小白兔的温馨时光</h5>
|
||||
<p class="card-text">上海的王先生为孩子认领了这只兔子,让孩子学会关爱动物,体验生命教育。</p>
|
||||
@@ -367,7 +363,7 @@
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<img src="images/animal-success3.jpg" class="card-img-top" alt="鸡认领">
|
||||
<img src="images/animal-case3.svg" class="card-img-top" alt="鸡认领">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">田园生活的开始</h5>
|
||||
<p class="card-text">广州的张女士认领了一群鸡,不仅收获新鲜鸡蛋,还体验了乡村田园生活。</p>
|
||||
@@ -533,6 +529,8 @@
|
||||
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="js/enhanced-interactions.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/animal.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -36,6 +36,18 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="about.html">关于我们</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="travel.html">旅行结伴</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="animal.html">动物认领</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="flower.html">送花服务</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="reward.html">推广奖励</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="case.html">成功案例</a>
|
||||
</li>
|
||||
@@ -71,7 +83,7 @@
|
||||
<div class="card case-card h-100">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<img src="images/user-case1.jpg" class="img-fluid h-100 object-fit-cover" alt="川藏线骑行">
|
||||
<img src="images/travel-case1.svg" class="img-fluid h-100 object-fit-cover" alt="川藏线骑行">
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
@@ -91,7 +103,7 @@
|
||||
<div class="card case-card h-100">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<img src="images/user-case2.jpg" class="img-fluid h-100 object-fit-cover" alt="云南背包客">
|
||||
<img src="images/travel-case2.svg" class="img-fluid h-100 object-fit-cover" alt="云南背包客">
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
@@ -111,7 +123,7 @@
|
||||
<div class="card case-card h-100">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<img src="images/user-case3.jpg" class="img-fluid h-100 object-fit-cover" alt="东北滑雪">
|
||||
<img src="images/travel-case3.svg" class="img-fluid h-100 object-fit-cover" alt="东北滑雪">
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
@@ -131,7 +143,7 @@
|
||||
<div class="card case-card h-100">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<img src="images/user-case4.jpg" class="img-fluid h-100 object-fit-cover" alt="农场体验">
|
||||
<img src="images/farm-case.svg" class="img-fluid h-100 object-fit-cover" alt="农场体验">
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
@@ -163,7 +175,7 @@
|
||||
<div class="card case-card h-100">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<img src="images/merchant-case1.jpg" class="img-fluid h-100 object-fit-cover" alt="绿野农场">
|
||||
<img src="images/farm-case.svg" class="img-fluid h-100 object-fit-cover" alt="绿野农场">
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
@@ -183,7 +195,7 @@
|
||||
<div class="card case-card h-100">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<img src="images/merchant-case2.jpg" class="img-fluid h-100 object-fit-cover" alt="花之语花店">
|
||||
<img src="images/flower-case.svg" class="img-fluid h-100 object-fit-cover" alt="花之语花店">
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
@@ -203,7 +215,7 @@
|
||||
<div class="card case-card h-100">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<img src="images/merchant-case3.jpg" class="img-fluid h-100 object-fit-cover" alt="探险旅行社">
|
||||
<img src="images/travel-case.svg" class="img-fluid h-100 object-fit-cover" alt="探险旅行社">
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
@@ -223,7 +235,7 @@
|
||||
<div class="card case-card h-100">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<img src="images/merchant-case4.jpg" class="img-fluid h-100 object-fit-cover" alt="民宿联盟">
|
||||
<img src="images/travel-case.svg" class="img-fluid h-100 object-fit-cover" alt="民宿联盟">
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
|
||||
@@ -37,6 +37,18 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="about.html">关于我们</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="travel.html">旅行结伴</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="animal.html">动物认领</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="flower.html">送花服务</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="reward.html">推广奖励</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="case.html">成功案例</a>
|
||||
</li>
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
/* 动物认领页面样式 */
|
||||
|
||||
.page-header.animal-header {
|
||||
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)),
|
||||
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="%2327ae60"/><circle cx="30" cy="40" r="15" fill="%232ecc71" opacity="0.8"/><circle cx="70" cy="30" r="10" fill="%232ecc71" opacity="0.6"/><circle cx="50" cy="60" r="20" fill="%232ecc71" opacity="0.7"/></svg>');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
/* 动物认领页面现在使用统一的hero-section样式 */
|
||||
|
||||
.feature-icon {
|
||||
width: 80px;
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
/* 送花服务页面样式 */
|
||||
|
||||
/* 页面头部样式 */
|
||||
.flower-header {
|
||||
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)),
|
||||
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="%23ff6b6b"/><circle cx="20" cy="30" r="8" fill="%23f1c40f" opacity="0.8"/><circle cx="40" cy="20" r="6" fill="%23f1c40f" opacity="0.6"/><circle cx="30" cy="45" r="10" fill="%23f1c40f" opacity="0.7"/><circle cx="60" cy="35" r="7" fill="%23f1c40f" opacity="0.9"/><circle cx="50" cy="60" r="9" fill="%23f1c40f" opacity="0.8"/></svg>');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding: 3rem 0;
|
||||
}
|
||||
/* 送花服务页面现在使用统一的hero-section样式 */
|
||||
|
||||
/* 鲜花卡片样式 */
|
||||
.flower-card {
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* 推广奖励页面样式 */
|
||||
|
||||
/* 页面头部样式 */
|
||||
.page-header.reward-header {
|
||||
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)),
|
||||
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="%23f39c12"/><circle cx="20" cy="30" r="5" fill="%23ffffff" opacity="0.8"/><circle cx="40" cy="20" r="4" fill="%23ffffff" opacity="0.6"/><circle cx="30" cy="45" r="6" fill="%23ffffff" opacity="0.7"/><circle cx="60" cy="35" r="5" fill="%23ffffff" opacity="0.9"/><circle cx="50" cy="60" r="7" fill="%23ffffff" opacity="0.8"/><circle cx="75" cy="50" r="4" fill="%23ffffff" opacity="0.6"/></svg>');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
/* 推广奖励页面现在使用统一的hero-section样式 */
|
||||
|
||||
.benefit-box {
|
||||
text-align: center;
|
||||
|
||||
@@ -74,6 +74,93 @@ body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 各页面专属背景色 */
|
||||
.hero-section.travel-hero {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
|
||||
.hero-section.animal-hero {
|
||||
background: linear-gradient(135deg, #27ae60 0%, #219653 100%);
|
||||
}
|
||||
|
||||
.hero-section.flower-hero {
|
||||
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
|
||||
}
|
||||
|
||||
.hero-section.reward-hero {
|
||||
background: linear-gradient(135deg, #f39c12 0%, #d35400 100%);
|
||||
}
|
||||
|
||||
/* 统一页面头部样式 */
|
||||
.page-header {
|
||||
color: white;
|
||||
padding: 120px 0 100px;
|
||||
margin-bottom: 80px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
min-height: 500px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.page-header .container {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.page-header h1 {
|
||||
font-size: var(--font-size-5xl);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.page-header .lead {
|
||||
font-size: var(--font-size-xl);
|
||||
margin-bottom: 2.5rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 响应式banner高度调整 */
|
||||
@media (max-width: 768px) {
|
||||
.hero-section {
|
||||
padding: 100px 0 80px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
padding: 100px 0 80px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.page-header h1 {
|
||||
font-size: var(--font-size-4xl);
|
||||
}
|
||||
|
||||
.page-header .lead {
|
||||
font-size: var(--font-size-lg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.hero-section {
|
||||
padding: 80px 0 60px;
|
||||
min-height: 350px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
padding: 80px 0 60px;
|
||||
min-height: 350px;
|
||||
}
|
||||
|
||||
.page-header h1 {
|
||||
font-size: var(--font-size-3xl);
|
||||
}
|
||||
|
||||
.page-header .lead {
|
||||
font-size: var(--font-size-base);
|
||||
}
|
||||
}
|
||||
|
||||
.hero-section::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
|
||||
@@ -1,28 +1,6 @@
|
||||
/* 旅行结伴页面样式 */
|
||||
|
||||
.page-header.travel-header {
|
||||
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)),
|
||||
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="%232ecc71"/><path d="M20,30 Q40,10 60,30 T100,30 L100,100 L20,100 Z" fill="%2327ae60" opacity="0.7"/></svg>');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.travel-header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.travel-header::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
/* 旅行结伴页面现在使用统一的hero-section样式 */
|
||||
|
||||
.travel-plan-card {
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
|
||||
@@ -62,16 +62,12 @@
|
||||
</nav>
|
||||
|
||||
<!-- 送花服务横幅 -->
|
||||
<section class="page-header flower-header">
|
||||
<div class="container h-100">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col-12 text-center text-white">
|
||||
<h1 class="display-3 fw-bold mb-4">送花服务</h1>
|
||||
<p class="lead mb-5 fs-4">为你的结伴伙伴或重要的人订购鲜花<br>传递温暖和浪漫</p>
|
||||
<a href="#flowers" class="btn btn-light btn-lg btn-rounded me-3">精选花束</a>
|
||||
<a href="#customize" class="btn btn-outline-light btn-lg btn-rounded">定制花束</a>
|
||||
</div>
|
||||
</div>
|
||||
<section class="hero-section flower-hero">
|
||||
<div class="container text-center position-relative">
|
||||
<h1 class="display-2 fw-bold mb-4">送花服务</h1>
|
||||
<p class="lead mb-5 fs-4">为你的结伴伙伴或重要的人订购鲜花<br>传递温暖和浪漫</p>
|
||||
<a href="#flowers" class="btn btn-light btn-lg btn-rounded me-3">精选花束</a>
|
||||
<a href="#customize" class="btn btn-outline-light btn-lg btn-rounded">定制花束</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -220,7 +216,7 @@
|
||||
<!-- 鲜花卡片将通过JS动态加载 -->
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card flower-card h-100">
|
||||
<img src="images/flower1.svg" class="card-img-top" alt="玫瑰花束">
|
||||
<img src="images/flower-case1.svg" class="card-img-top" alt="玫瑰花束">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">经典红玫瑰</h5>
|
||||
<p class="card-text">99朵红玫瑰,表达热烈的爱意,是情人节和纪念日的经典选择。</p>
|
||||
@@ -236,7 +232,7 @@
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card flower-card h-100">
|
||||
<img src="images/flower2.svg" class="card-img-top" alt="康乃馨">
|
||||
<img src="images/flower-case2.svg" class="card-img-top" alt="康乃馨">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">温馨康乃馨</h5>
|
||||
<p class="card-text">12朵粉色康乃馨,传递温暖的祝福,适合母亲节和探望长辈。</p>
|
||||
@@ -252,7 +248,7 @@
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card flower-card h-100">
|
||||
<img src="images/flower3.svg" class="card-img-top" alt="向日葵">
|
||||
<img src="images/flower-case3.svg" class="card-img-top" alt="向日葵">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">阳光向日葵</h5>
|
||||
<p class="card-text">6朵向日葵搭配满天星,带来阳光般的温暖和积极的能量。</p>
|
||||
@@ -284,7 +280,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 mb-4">
|
||||
<img src="images/customize-flower.jpg" alt="定制花束" class="img-fluid rounded">
|
||||
<img src="images/flower-pattern.svg" alt="定制花束" class="img-fluid rounded">
|
||||
</div>
|
||||
<div class="col-lg-6 mb-4">
|
||||
<h3 class="h4 mb-4">个性化定制服务</h3>
|
||||
@@ -562,6 +558,8 @@
|
||||
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="js/enhanced-interactions.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/flower.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -36,6 +36,18 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="about.html">关于我们</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="travel.html">旅行结伴</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="animal.html">动物认领</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="flower.html">送花服务</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="reward.html">推广奖励</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="case.html">成功案例</a>
|
||||
</li>
|
||||
@@ -306,6 +318,7 @@
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/font-awesome/7.0.0/js/all.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="js/enhanced-interactions.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
590
website/js/enhanced-interactions.js
Normal file
590
website/js/enhanced-interactions.js
Normal file
@@ -0,0 +1,590 @@
|
||||
/**
|
||||
* 增强交互体验管理器
|
||||
* 统一管理整个网站的交互优化
|
||||
*/
|
||||
class EnhancedInteractionManager {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.setupGlobalInteractions();
|
||||
this.setupLoadingStates();
|
||||
this.setupFormEnhancements();
|
||||
this.setupScrollEffects();
|
||||
this.setupTooltips();
|
||||
this.setupNotifications();
|
||||
this.setupKeyboardNavigation();
|
||||
this.setupMobileOptimizations();
|
||||
}
|
||||
|
||||
// 全局交互设置
|
||||
setupGlobalInteractions() {
|
||||
// 平滑滚动
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(this.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 返回顶部按钮
|
||||
this.createBackToTopButton();
|
||||
|
||||
// 页面加载进度条
|
||||
this.createLoadingBar();
|
||||
|
||||
// 全局错误处理
|
||||
this.setupGlobalErrorHandling();
|
||||
}
|
||||
|
||||
// 创建返回顶部按钮
|
||||
createBackToTopButton() {
|
||||
const backToTop = document.createElement('button');
|
||||
backToTop.innerHTML = '<i class="fa fa-chevron-up"></i>';
|
||||
backToTop.className = 'btn-back-to-top';
|
||||
backToTop.setAttribute('aria-label', '返回顶部');
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.btn-back-to-top {
|
||||
position: fixed;
|
||||
bottom: 30px;
|
||||
right: 30px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.3s ease;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 4px 12px rgba(0,123,255,0.3);
|
||||
}
|
||||
.btn-back-to-top:hover {
|
||||
background: #0056b3;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(0,123,255,0.4);
|
||||
}
|
||||
.btn-back-to-top.show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.btn-back-to-top {
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
document.body.appendChild(backToTop);
|
||||
|
||||
// 滚动显示/隐藏
|
||||
window.addEventListener('scroll', () => {
|
||||
if (window.pageYOffset > 300) {
|
||||
backToTop.classList.add('show');
|
||||
} else {
|
||||
backToTop.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
// 点击返回顶部
|
||||
backToTop.addEventListener('click', () => {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 创建加载进度条
|
||||
createLoadingBar() {
|
||||
const loadingBar = document.createElement('div');
|
||||
loadingBar.className = 'loading-bar';
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.loading-bar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 0%;
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, #007bff, #28a745);
|
||||
z-index: 9999;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
document.body.appendChild(loadingBar);
|
||||
|
||||
// 页面加载进度
|
||||
let progress = 0;
|
||||
const interval = setInterval(() => {
|
||||
progress += Math.random() * 30;
|
||||
if (progress > 90) progress = 90;
|
||||
loadingBar.style.width = progress + '%';
|
||||
}, 200);
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
clearInterval(interval);
|
||||
loadingBar.style.width = '100%';
|
||||
setTimeout(() => {
|
||||
loadingBar.style.opacity = '0';
|
||||
setTimeout(() => loadingBar.remove(), 300);
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
|
||||
// 设置加载状态
|
||||
setupLoadingStates() {
|
||||
// 为所有按钮添加加载状态
|
||||
document.addEventListener('click', (e) => {
|
||||
if (e.target.matches('button[type="submit"], .btn-primary, .btn-flower, .btn-animal')) {
|
||||
this.showButtonLoading(e.target);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 显示按钮加载状态
|
||||
showButtonLoading(button) {
|
||||
const originalText = button.innerHTML;
|
||||
const originalDisabled = button.disabled;
|
||||
|
||||
button.disabled = true;
|
||||
button.innerHTML = '<i class="fa fa-spinner fa-spin me-2"></i>处理中...';
|
||||
|
||||
// 模拟加载时间
|
||||
setTimeout(() => {
|
||||
button.disabled = originalDisabled;
|
||||
button.innerHTML = originalText;
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// 表单增强
|
||||
setupFormEnhancements() {
|
||||
// 实时验证
|
||||
document.querySelectorAll('input, textarea, select').forEach(field => {
|
||||
field.addEventListener('blur', () => this.validateField(field));
|
||||
field.addEventListener('input', () => this.clearFieldError(field));
|
||||
});
|
||||
|
||||
// 表单提交增强
|
||||
document.querySelectorAll('form').forEach(form => {
|
||||
form.addEventListener('submit', (e) => {
|
||||
if (!this.validateForm(form)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 验证单个字段
|
||||
validateField(field) {
|
||||
const value = field.value.trim();
|
||||
let isValid = true;
|
||||
let message = '';
|
||||
|
||||
// 必填验证
|
||||
if (field.hasAttribute('required') && !value) {
|
||||
isValid = false;
|
||||
message = '此字段为必填项';
|
||||
}
|
||||
|
||||
// 邮箱验证
|
||||
if (field.type === 'email' && value && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
|
||||
isValid = false;
|
||||
message = '请输入有效的邮箱地址';
|
||||
}
|
||||
|
||||
// 手机号验证
|
||||
if (field.type === 'tel' && value && !/^1[3-9]\d{9}$/.test(value)) {
|
||||
isValid = false;
|
||||
message = '请输入有效的手机号码';
|
||||
}
|
||||
|
||||
// 显示验证结果
|
||||
if (!isValid) {
|
||||
this.showFieldError(field, message);
|
||||
} else {
|
||||
this.showFieldSuccess(field);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
// 显示字段错误
|
||||
showFieldError(field, message) {
|
||||
this.clearFieldFeedback(field);
|
||||
|
||||
field.classList.add('is-invalid');
|
||||
const feedback = document.createElement('div');
|
||||
feedback.className = 'invalid-feedback';
|
||||
feedback.textContent = message;
|
||||
field.parentNode.appendChild(feedback);
|
||||
}
|
||||
|
||||
// 显示字段成功
|
||||
showFieldSuccess(field) {
|
||||
this.clearFieldFeedback(field);
|
||||
field.classList.add('is-valid');
|
||||
}
|
||||
|
||||
// 清除字段错误
|
||||
clearFieldError(field) {
|
||||
field.classList.remove('is-invalid');
|
||||
const feedback = field.parentNode.querySelector('.invalid-feedback');
|
||||
if (feedback) feedback.remove();
|
||||
}
|
||||
|
||||
// 清除字段反馈
|
||||
clearFieldFeedback(field) {
|
||||
field.classList.remove('is-invalid', 'is-valid');
|
||||
const feedback = field.parentNode.querySelector('.invalid-feedback, .valid-feedback');
|
||||
if (feedback) feedback.remove();
|
||||
}
|
||||
|
||||
// 验证整个表单
|
||||
validateForm(form) {
|
||||
let isValid = true;
|
||||
const fields = form.querySelectorAll('input, textarea, select');
|
||||
|
||||
fields.forEach(field => {
|
||||
if (!this.validateField(field)) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
// 滚动效果
|
||||
setupScrollEffects() {
|
||||
// 导航栏滚动效果
|
||||
const navbar = document.querySelector('.navbar');
|
||||
if (navbar) {
|
||||
window.addEventListener('scroll', () => {
|
||||
if (window.scrollY > 100) {
|
||||
navbar.classList.add('navbar-scrolled');
|
||||
} else {
|
||||
navbar.classList.remove('navbar-scrolled');
|
||||
}
|
||||
});
|
||||
|
||||
// 添加滚动样式
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.navbar-scrolled {
|
||||
background-color: rgba(255, 255, 255, 0.95) !important;
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
// 视差滚动效果
|
||||
this.setupParallaxEffect();
|
||||
}
|
||||
|
||||
// 视差滚动效果
|
||||
setupParallaxEffect() {
|
||||
const parallaxElements = document.querySelectorAll('.hero-section');
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
const scrolled = window.pageYOffset;
|
||||
parallaxElements.forEach(element => {
|
||||
const rate = scrolled * -0.5;
|
||||
element.style.transform = `translateY(${rate}px)`;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 工具提示
|
||||
setupTooltips() {
|
||||
// 为所有带有title属性的元素添加工具提示
|
||||
document.querySelectorAll('[title]').forEach(element => {
|
||||
element.addEventListener('mouseenter', (e) => {
|
||||
this.showTooltip(e.target, e.target.getAttribute('title'));
|
||||
});
|
||||
|
||||
element.addEventListener('mouseleave', () => {
|
||||
this.hideTooltip();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 显示工具提示
|
||||
showTooltip(element, text) {
|
||||
const tooltip = document.createElement('div');
|
||||
tooltip.className = 'custom-tooltip';
|
||||
tooltip.textContent = text;
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.custom-tooltip {
|
||||
position: absolute;
|
||||
background: #333;
|
||||
color: white;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
.custom-tooltip.show {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
if (!document.querySelector('style[data-tooltip]')) {
|
||||
style.setAttribute('data-tooltip', 'true');
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
document.body.appendChild(tooltip);
|
||||
|
||||
const rect = element.getBoundingClientRect();
|
||||
tooltip.style.left = rect.left + (rect.width / 2) - (tooltip.offsetWidth / 2) + 'px';
|
||||
tooltip.style.top = rect.top - tooltip.offsetHeight - 10 + 'px';
|
||||
|
||||
setTimeout(() => tooltip.classList.add('show'), 10);
|
||||
}
|
||||
|
||||
// 隐藏工具提示
|
||||
hideTooltip() {
|
||||
const tooltip = document.querySelector('.custom-tooltip');
|
||||
if (tooltip) {
|
||||
tooltip.classList.remove('show');
|
||||
setTimeout(() => tooltip.remove(), 300);
|
||||
}
|
||||
}
|
||||
|
||||
// 通知系统
|
||||
setupNotifications() {
|
||||
this.createNotificationContainer();
|
||||
}
|
||||
|
||||
// 创建通知容器
|
||||
createNotificationContainer() {
|
||||
const container = document.createElement('div');
|
||||
container.id = 'notification-container';
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
#notification-container {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 9999;
|
||||
max-width: 400px;
|
||||
}
|
||||
.notification {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-bottom: 10px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
border-left: 4px solid #007bff;
|
||||
opacity: 0;
|
||||
transform: translateX(100%);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.notification.show {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
.notification.success { border-left-color: #28a745; }
|
||||
.notification.error { border-left-color: #dc3545; }
|
||||
.notification.warning { border-left-color: #ffc107; }
|
||||
.notification.info { border-left-color: #17a2b8; }
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
document.body.appendChild(container);
|
||||
}
|
||||
|
||||
// 显示通知
|
||||
showNotification(message, type = 'info', duration = 5000) {
|
||||
const notification = document.createElement('div');
|
||||
notification.className = `notification ${type}`;
|
||||
notification.innerHTML = `
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div>
|
||||
<strong>${this.getNotificationTitle(type)}</strong>
|
||||
<div>${message}</div>
|
||||
</div>
|
||||
<button type="button" class="btn-close" onclick="this.parentElement.parentElement.remove()"></button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.getElementById('notification-container').appendChild(notification);
|
||||
|
||||
setTimeout(() => notification.classList.add('show'), 10);
|
||||
|
||||
if (duration > 0) {
|
||||
setTimeout(() => {
|
||||
notification.classList.remove('show');
|
||||
setTimeout(() => notification.remove(), 300);
|
||||
}, duration);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取通知标题
|
||||
getNotificationTitle(type) {
|
||||
const titles = {
|
||||
success: '成功',
|
||||
error: '错误',
|
||||
warning: '警告',
|
||||
info: '提示'
|
||||
};
|
||||
return titles[type] || '通知';
|
||||
}
|
||||
|
||||
// 键盘导航
|
||||
setupKeyboardNavigation() {
|
||||
document.addEventListener('keydown', (e) => {
|
||||
// ESC键关闭模态框
|
||||
if (e.key === 'Escape') {
|
||||
const modals = document.querySelectorAll('.modal.show');
|
||||
modals.forEach(modal => {
|
||||
const modalInstance = bootstrap.Modal.getInstance(modal);
|
||||
if (modalInstance) modalInstance.hide();
|
||||
});
|
||||
}
|
||||
|
||||
// Tab键焦点管理
|
||||
if (e.key === 'Tab') {
|
||||
this.manageFocus(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 焦点管理
|
||||
manageFocus(e) {
|
||||
const focusableElements = document.querySelectorAll(
|
||||
'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled])'
|
||||
);
|
||||
|
||||
const firstElement = focusableElements[0];
|
||||
const lastElement = focusableElements[focusableElements.length - 1];
|
||||
|
||||
if (e.shiftKey && document.activeElement === firstElement) {
|
||||
e.preventDefault();
|
||||
lastElement.focus();
|
||||
} else if (!e.shiftKey && document.activeElement === lastElement) {
|
||||
e.preventDefault();
|
||||
firstElement.focus();
|
||||
}
|
||||
}
|
||||
|
||||
// 移动端优化
|
||||
setupMobileOptimizations() {
|
||||
// 触摸反馈
|
||||
document.addEventListener('touchstart', (e) => {
|
||||
if (e.target.matches('button, .btn, .card')) {
|
||||
e.target.style.transform = 'scale(0.98)';
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('touchend', (e) => {
|
||||
if (e.target.matches('button, .btn, .card')) {
|
||||
setTimeout(() => {
|
||||
e.target.style.transform = '';
|
||||
}, 150);
|
||||
}
|
||||
});
|
||||
|
||||
// 防止双击缩放
|
||||
let lastTouchEnd = 0;
|
||||
document.addEventListener('touchend', (e) => {
|
||||
const now = (new Date()).getTime();
|
||||
if (now - lastTouchEnd <= 300) {
|
||||
e.preventDefault();
|
||||
}
|
||||
lastTouchEnd = now;
|
||||
}, false);
|
||||
|
||||
// 移动端导航优化
|
||||
this.setupMobileNavigation();
|
||||
}
|
||||
|
||||
// 移动端导航优化
|
||||
setupMobileNavigation() {
|
||||
const navbarToggler = document.querySelector('.navbar-toggler');
|
||||
const navbarCollapse = document.querySelector('.navbar-collapse');
|
||||
|
||||
if (navbarToggler && navbarCollapse) {
|
||||
// 点击导航链接后自动关闭菜单
|
||||
navbarCollapse.querySelectorAll('a').forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
if (window.innerWidth < 992) {
|
||||
const collapse = new bootstrap.Collapse(navbarCollapse, {
|
||||
hide: true
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 全局错误处理
|
||||
setupGlobalErrorHandling() {
|
||||
window.addEventListener('error', (e) => {
|
||||
console.error('全局错误:', e.error);
|
||||
this.showNotification('页面出现错误,请刷新重试', 'error');
|
||||
});
|
||||
|
||||
window.addEventListener('unhandledrejection', (e) => {
|
||||
console.error('未处理的Promise错误:', e.reason);
|
||||
this.showNotification('网络请求失败,请检查网络连接', 'error');
|
||||
});
|
||||
}
|
||||
|
||||
// 性能监控
|
||||
setupPerformanceMonitoring() {
|
||||
// 页面加载性能
|
||||
window.addEventListener('load', () => {
|
||||
const perfData = performance.getEntriesByType('navigation')[0];
|
||||
const loadTime = perfData.loadEventEnd - perfData.loadEventStart;
|
||||
|
||||
if (loadTime > 3000) {
|
||||
console.warn('页面加载时间过长:', loadTime + 'ms');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 全局实例
|
||||
let enhancedInteractionManager;
|
||||
|
||||
// 页面加载完成后初始化
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
enhancedInteractionManager = new EnhancedInteractionManager();
|
||||
});
|
||||
|
||||
// 导出全局方法供其他脚本使用
|
||||
window.showNotification = function(message, type, duration) {
|
||||
if (enhancedInteractionManager) {
|
||||
enhancedInteractionManager.showNotification(message, type, duration);
|
||||
}
|
||||
};
|
||||
|
||||
window.showButtonLoading = function(button) {
|
||||
if (enhancedInteractionManager) {
|
||||
enhancedInteractionManager.showButtonLoading(button);
|
||||
}
|
||||
};
|
||||
@@ -11,18 +11,33 @@
|
||||
<meta property="og:description" content="申请成为结伴客平台合作商家,填写商家入驻申请表单,加入我们的生态体系,为旅行者提供优质服务。">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://jiebanke.com/merchant/apply.html">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.7.2/css/all.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/7.0.0/css/all.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.7.2/css/all.css" rel="stylesheet">
|
||||
<link href="../css/style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<!-- 页面加载动画 -->
|
||||
<div class="page-loader">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
<div class="loader-spinner">
|
||||
<i class="fa fa-compass fa-spin"></i>
|
||||
</div>
|
||||
</div>
|
||||
+++++++ REPLACE</div>
|
||||
</replace_in_file>
|
||||
|
||||
<replace_in_file id="mf0jdrirk6h5pux001ij263rm1o89xgr">
|
||||
<path>website/merchant/apply.html</path>
|
||||
<diff>------- SEARCH
|
||||
<!-- 页面滚动进度条 -->
|
||||
<div class="scroll-progress"></div>
|
||||
|
||||
<!-- 返回顶部按钮 -->
|
||||
<button class="back-to-top">
|
||||
<i class="fas fa-arrow-up"></i>
|
||||
</button>
|
||||
=======
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
|
||||
<div class="container">
|
||||
@@ -42,6 +57,18 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../about.html">关于我们</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../travel.html">旅行结伴</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../animal.html">动物认领</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../flower.html">送花服务</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../reward.html">推广奖励</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../case.html">成功案例</a>
|
||||
</li>
|
||||
@@ -73,8 +100,6 @@
|
||||
</section>
|
||||
|
||||
<!-- 申请步骤 -->
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="../js/main.js"></script>
|
||||
<section class="container mb-5">
|
||||
<div class="step-indicator">
|
||||
<div class="step completed">
|
||||
@@ -252,18 +277,18 @@
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-4">
|
||||
<h5 class="mb-4">
|
||||
<i class="bi bi-map-fill me-2"></i>结伴客
|
||||
<i class="fa fa-map-marker-alt me-2"></i>结伴客
|
||||
</h5>
|
||||
<p>专注于结伴旅行活动的平台,包含独特的动物认领功能。</p>
|
||||
<div class="d-flex">
|
||||
<a href="#" class="social-icon me-2">
|
||||
<i class="fa-brands fa-wechat"></i>
|
||||
<i class="fab fa-weixin"></i>
|
||||
</a>
|
||||
<a href="#" class="social-icon me-2">
|
||||
<i class="fa-brands fa-weibo"></i>
|
||||
<i class="fab fa-weibo"></i>
|
||||
</a>
|
||||
<a href="#" class="social-icon">
|
||||
<i class="fa-brands fa-qq"></i>
|
||||
<i class="fab fa-qq"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -322,6 +347,10 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/font-awesome/7.0.0/js/all.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="../js/enhanced-interactions.js"></script>
|
||||
<script src="../js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -11,16 +11,17 @@
|
||||
<meta property="og:description" content="加入结伴客商家合作生态,为旅行者提供农场、花店和活动组织服务。了解合作优势、入驻流程和商家数据。">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://jiebanke.com/merchant/">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.7.2/css/all.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/7.0.0/css/all.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.7.2/css/all.css" rel="stylesheet">
|
||||
<link href="../css/style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<!-- 页面加载动画 -->
|
||||
<div class="page-loader">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
<div class="loader-spinner">
|
||||
<i class="fa fa-compass fa-spin"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 导航栏 -->
|
||||
@@ -42,6 +43,18 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../about.html">关于我们</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../travel.html">旅行结伴</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../animal.html">动物认领</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../flower.html">送花服务</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../reward.html">推广奖励</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../case.html">成功案例</a>
|
||||
</li>
|
||||
@@ -293,7 +306,7 @@
|
||||
<p class="card-text">花店通过结伴客的送花服务功能,月订单量增长了150%,特别是在节日期间订单量激增。</p>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mt-4">
|
||||
<img src="../images/merchant-avatar2.svg" class="rounded-circle me-3" alt="花之语花店李女士" width="50" height="50">
|
||||
<img src="../images/merchant-avatar1.svg" class="rounded-circle me-3" alt="花之语花店李女士" width="50" height="50">
|
||||
<div>
|
||||
<h6 class="mb-0">李女士</h6>
|
||||
<small class="text-muted">花之语花店</small>
|
||||
@@ -310,7 +323,7 @@
|
||||
<p class="card-text">旅行社通过平台发布特色探险线路,成功吸引了大量年轻用户,成团率大幅提升。</p>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mt-4">
|
||||
<img src="../images/merchant-avatar3.svg" class="rounded-circle me-3" alt="探险旅行社张经理" width="50" height="50">
|
||||
<img src="../images/user-avatar1.svg" class="rounded-circle me-3" alt="探险旅行社张经理" width="50" height="50">
|
||||
<div>
|
||||
<h6 class="mb-0">张经理</h6>
|
||||
<small class="text-muted">探险旅行社</small>
|
||||
@@ -410,5 +423,8 @@
|
||||
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/font-awesome/7.0.0/js/all.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="../js/enhanced-interactions.js"></script>
|
||||
<script src="../js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -11,16 +11,17 @@
|
||||
<meta property="og:description" content="了解结伴客平台商家合作政策,包括合作原则、资质要求、服务标准、费用结算、权利义务等内容。">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://jiebanke.com/merchant/policy.html">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.7.2/css/all.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/7.0.0/css/all.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.7.2/css/all.css" rel="stylesheet">
|
||||
<link href="../css/style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<!-- 页面加载动画 -->
|
||||
<div class="page-loader">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
<div class="loader-spinner">
|
||||
<i class="fa fa-compass fa-spin"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 导航栏 -->
|
||||
@@ -42,6 +43,18 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../about.html">关于我们</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../travel.html">旅行结伴</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../animal.html">动物认领</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../flower.html">送花服务</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../reward.html">推广奖励</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../case.html">成功案例</a>
|
||||
</li>
|
||||
@@ -56,13 +69,7 @@
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 页面滚动进度条 -->
|
||||
<div class="scroll-progress"></div>
|
||||
|
||||
<!-- 返回顶部按钮 -->
|
||||
<button class="back-to-top">
|
||||
<i class="fas fa-arrow-up"></i>
|
||||
</button>
|
||||
|
||||
<!-- 合作政策横幅 -->
|
||||
<section class="hero-section">
|
||||
@@ -175,25 +182,23 @@
|
||||
</section>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="../js/main.js"></script>
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-4">
|
||||
<h5 class="mb-4">
|
||||
<i class="fa-solid fa-map-location me-2"></i>结伴客
|
||||
<i class="fa fa-map-marker-alt me-2"></i>结伴客
|
||||
</h5>
|
||||
<p>专注于结伴旅行活动的平台,包含独特的动物认领功能。</p>
|
||||
<div class="d-flex">
|
||||
<a href="#" class="social-icon me-2">
|
||||
<i class="fa-brands fa-weixin"></i>
|
||||
<i class="fab fa-weixin"></i>
|
||||
</a>
|
||||
<a href="#" class="social-icon me-2">
|
||||
<i class="fa-brands fa-weibo"></i>
|
||||
<i class="fab fa-weibo"></i>
|
||||
</a>
|
||||
<a href="#" class="social-icon">
|
||||
<i class="fa-brands fa-qq"></i>
|
||||
<i class="fab fa-qq"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -252,7 +257,11 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/font-awesome/7.0.0/js/all.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="../js/enhanced-interactions.js"></script>
|
||||
<script src="../js/main.js"></script>
|
||||
<script>
|
||||
// 目录滚动高亮
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
@@ -62,16 +62,12 @@
|
||||
</nav>
|
||||
|
||||
<!-- 推广奖励横幅 -->
|
||||
<section class="page-header reward-header">
|
||||
<div class="container h-100">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col-12 text-center text-white">
|
||||
<h1 class="display-3 fw-bold mb-4">推广奖励</h1>
|
||||
<p class="lead mb-5 fs-4">分享给朋友,获得丰厚奖励<br>一起创造更多价值</p>
|
||||
<a href="#benefits" class="btn btn-light btn-lg btn-rounded me-3">查看奖励详情</a>
|
||||
<a href="#calculator" class="btn btn-outline-light btn-lg btn-rounded">收益计算器</a>
|
||||
</div>
|
||||
</div>
|
||||
<section class="hero-section reward-hero">
|
||||
<div class="container text-center position-relative">
|
||||
<h1 class="display-2 fw-bold mb-4">推广奖励</h1>
|
||||
<p class="lead mb-5 fs-4">分享给朋友,获得丰厚奖励<br>一起创造更多价值</p>
|
||||
<a href="#benefits" class="btn btn-light btn-lg btn-rounded me-3">查看奖励详情</a>
|
||||
<a href="#calculator" class="btn btn-outline-light btn-lg btn-rounded">收益计算器</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -539,6 +535,8 @@
|
||||
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="js/enhanced-interactions.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/reward.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -62,16 +62,12 @@
|
||||
</nav>
|
||||
|
||||
<!-- 旅行结伴横幅 -->
|
||||
<section class="page-header travel-header">
|
||||
<div class="container h-100">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col-12 text-center text-white">
|
||||
<h1 class="display-3 fw-bold mb-4">旅行结伴</h1>
|
||||
<p class="lead mb-5 fs-4">发布你的旅行计划,寻找志同道合的伙伴<br>一起探索世界的美好</p>
|
||||
<a href="#plans" class="btn btn-light btn-lg btn-rounded me-3">查看旅行计划</a>
|
||||
<a href="#process" class="btn btn-outline-light btn-lg btn-rounded">发布我的计划</a>
|
||||
</div>
|
||||
</div>
|
||||
<section class="hero-section travel-hero">
|
||||
<div class="container text-center position-relative">
|
||||
<h1 class="display-2 fw-bold mb-4">旅行结伴</h1>
|
||||
<p class="lead mb-5 fs-4">发布你的旅行计划,寻找志同道合的伙伴<br>一起探索世界的美好</p>
|
||||
<a href="#plans" class="btn btn-light btn-lg btn-rounded me-3">查看旅行计划</a>
|
||||
<a href="#process" class="btn btn-outline-light btn-lg btn-rounded">发布我的计划</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -244,7 +240,7 @@
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<img src="images/travel-success1.jpg" class="card-img-top" alt="川藏线骑行">
|
||||
<img src="images/travel-case1.svg" class="card-img-top" alt="川藏线骑行">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">川藏线骑行</h5>
|
||||
<p class="card-text">通过结伴客平台,来自不同城市的三位骑行爱好者成功组队,完成了川藏线的挑战。</p>
|
||||
@@ -257,7 +253,7 @@
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<img src="images/travel-success2.jpg" class="card-img-top" alt="云南背包客">
|
||||
<img src="images/travel-case2.svg" class="card-img-top" alt="云南背包客">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">云南背包客之旅</h5>
|
||||
<p class="card-text">两位独自旅行的女孩通过平台相识,结伴游览了大理、丽江和香格里拉。</p>
|
||||
@@ -270,7 +266,7 @@
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<img src="images/travel-success3.jpg" class="card-img-top" alt="东北滑雪">
|
||||
<img src="images/travel-case3.svg" class="card-img-top" alt="东北滑雪">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">东北滑雪之旅</h5>
|
||||
<p class="card-text">滑雪爱好者组成的四人小队,一起探索了东北各大滑雪场。</p>
|
||||
@@ -436,6 +432,8 @@
|
||||
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.7/js/bootstrap.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/aos/2.3.4/aos.js"></script>
|
||||
<script src="js/enhanced-interactions.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/travel.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user