重构动物认领页面和导航菜单,统一使用SVG图标并优化交互体验

This commit is contained in:
ylweng
2025-09-21 21:12:27 +08:00
parent 467a4ead10
commit 14aca938de
64 changed files with 25067 additions and 18256 deletions

View 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
View File

@@ -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/` 目录下的相关文档。

View 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 };

View 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;

View 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 };

View 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 };

View 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 };

View File

@@ -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 获取
通过微信登录接口获取TokenToken有效期为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月*

File diff suppressed because it is too large Load Diff

View File

@@ -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
View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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
功能:获取数据库性能统计
```

File diff suppressed because it is too large Load Diff

1996
docs/安全文档.md Normal file

File diff suppressed because it is too large Load Diff

277
docs/官网需求文档.md Normal file
View 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优化工作

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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.loginwx.getUserProfile
- **支付API**wx.requestPayment
- **分享API**wx.shareAppMessagewx.shareTimeline
- **地图API**wx.getLocationwx.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接口安全性测试

File diff suppressed because it is too large Load Diff

View File

@@ -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月*

File diff suppressed because it is too large Load Diff

View File

@@ -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日

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}
};
```

View File

@@ -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*

View 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集成**集成人工智能技术
- **边缘计算**支持边缘计算场景
- **国际化**支持多语言和多地区部署

View 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 业务扩展
- 更多动物类型
- 国际化支持
- 企业服务
- 品牌合作

View File

@@ -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. **批量操作**: 支持批量选择和操作
## 总结
文件上传系统为解班客平台提供了完整、安全、高效的文件管理解决方案。通过模块化设计、完善的错误处理、详细的日志记录和性能优化,确保系统的稳定性和可维护性。
系统支持多种文件类型,提供了灵活的配置选项,能够满足不同场景的需求。同时,通过监控和统计功能,管理员可以实时了解系统状态,及时发现和解决问题。
未来将继续完善系统功能,增加更多高级特性,为用户提供更好的文件管理体验。

View File

@@ -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
View 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
**维护团队**:解班客技术团队

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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 设备兼容
- **桌面设备**WindowsmacOSLinux
- **平板设备**iPadAndroid平板
- **移动设备**基本功能的移动端支持
- **分辨率适配**1366x768 4K分辨率
## 8. 维护需求
### 8.1 系统维护
- **版本更新**支持在线更新和回滚
- **配置管理**动态配置更新无需重启
- **监控告警**系统状态监控和异常告警
- **性能优化**持续的性能监控和优化
### 8.2 内容维护
- **数据清理**定期清理过期和无效数据
- **缓存管理**缓存更新和清理机制
- **日志管理**日志轮转和归档机制
- **备份策略**定期备份和恢复测试

View File

@@ -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 (计划中)
- 增加订单管理功能
- 增加商家管理功能
- 增加系统配置管理
- 优化统计报表功能

View File

@@ -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月*

File diff suppressed because it is too large Load Diff

View File

@@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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. 验证部署
访问以下地址验证部署是否成功:
- 后端APIhttp://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
View 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证书
- **监控日志**系统监控日志管理
- **备份恢复**数据备份故障恢复
通过遵循本文档的部署流程可以确保系统的稳定性可靠性和可维护性

View File

@@ -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. **持续优化**: 根据实际情况调整监控策略
## 总结
错误处理和日志系统是解班客平台稳定运行的重要保障。通过统一的错误处理机制、完善的日志记录功能和实时监控告警,系统能够快速发现和解决问题,提供稳定可靠的服务。
系统采用分层设计,支持多种错误类型和日志级别,提供了灵活的配置选项和丰富的功能特性。通过性能优化和最佳实践,确保系统在高负载情况下仍能正常运行。
未来将继续完善系统功能,增加更多监控指标和告警机制,为平台的稳定运行提供更强有力的支持。

View File

@@ -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日
**报告人**: 开发团队

View File

@@ -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加密存储
- **传输安全**全站HTTPSAPI接口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日 | 维护者结伴客开发团队*

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">

View File

@@ -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>

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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>

View File

@@ -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>

View 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);
}
};

View File

@@ -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>

View File

@@ -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>

View File

@@ -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() {

View File

@@ -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>

View File

@@ -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>