修改文件结构

This commit is contained in:
ylweng
2025-09-01 02:20:36 +08:00
parent 5fbbe4a8a5
commit 7b73f2be33
24 changed files with 20878 additions and 47190 deletions

44554
.gitignore vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,375 +0,0 @@
# 📚 API 接口文档
## 📋 文档说明
本文档详细描述了杰邦科项目的所有API接口包括请求参数、响应格式和错误代码。
## 🔐 认证方式
### JWT Token 认证
所有需要认证的API必须在请求头中携带Token
```
Authorization: Bearer <your_jwt_token>
```
### Token 获取
通过登录接口获取TokenToken有效期为7天。
## 👥 用户模块
### 用户注册
**Endpoint:** `POST /api/v1/users/register`
**请求参数:**
```json
{
"username": "string, required, 3-20字符",
"password": "string, required, 6-20字符",
"email": "string, optional, 邮箱格式",
"phone": "string, optional, 手机号格式"
}
```
**响应示例:**
```json
{
"code": 200,
"message": "注册成功",
"data": {
"id": 1,
"username": "testuser",
"email": "test@example.com",
"createdAt": "2024-01-01T00:00:00.000Z"
}
}
```
**错误代码:**
- `400`: 参数验证失败
- `409`: 用户名已存在
- `500`: 服务器内部错误
### 用户登录
**Endpoint:** `POST /api/v1/users/login`
**请求参数:**
```json
{
"username": "string, required",
"password": "string, required"
}
```
**响应示例:**
```json
{
"code": 200,
"message": "登录成功",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"username": "testuser",
"email": "test@example.com"
}
}
}
```
**错误代码:**
- `400`: 参数验证失败
- `401`: 用户名或密码错误
- `500`: 服务器内部错误
### 获取用户信息
**Endpoint:** `GET /api/v1/users/profile`
**请求头:**
```
Authorization: Bearer <token>
```
**响应示例:**
```json
{
"code": 200,
"message": "获取成功",
"data": {
"id": 1,
"username": "testuser",
"email": "test@example.com",
"phone": "13800138000",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
}
```
**错误代码:**
- `401`: 未授权访问
- `404`: 用户不存在
- `500`: 服务器内部错误
## 🛒 订单模块
### 创建订单
**Endpoint:** `POST /api/v1/orders`
**请求头:**
```
Authorization: Bearer <token>
```
**请求参数:**
```json
{
"items": [
{
"productId": 1,
"quantity": 2,
"price": 100.00
}
],
"shippingAddress": {
"recipient": "张三",
"phone": "13800138000",
"address": "北京市朝阳区xxx路xxx号"
},
"remark": "string, optional"
}
```
**响应示例:**
```json
{
"code": 200,
"message": "订单创建成功",
"data": {
"id": 1001,
"orderNo": "ORDER202401010001",
"totalAmount": 200.00,
"status": "pending",
"createdAt": "2024-01-01T00:00:00.000Z"
}
}
```
### 查询订单列表
**Endpoint:** `GET /api/v1/orders`
**请求头:**
```
Authorization: Bearer <token>
```
**查询参数:**
```
?page=1&limit=10&status=pending
```
| 参数 | 类型 | 说明 |
|------|------|------|
| page | number | 页码默认1 |
| limit | number | 每页数量默认10 |
| status | string | 订单状态过滤 |
**响应示例:**
```json
{
"code": 200,
"message": "获取成功",
"data": {
"items": [
{
"id": 1001,
"orderNo": "ORDER202401010001",
"totalAmount": 200.00,
"status": "pending",
"createdAt": "2024-01-01T00:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 100,
"pages": 10
}
}
}
```
## 📦 商品模块
### 获取商品列表
**Endpoint:** `GET /api/v1/products`
**查询参数:**
```
?page=1&limit=10&category=electronics&sort=price_desc
```
| 参数 | 类型 | 说明 |
|------|------|------|
| page | number | 页码默认1 |
| limit | number | 每页数量默认10 |
| category | string | 商品分类过滤 |
| sort | string | 排序方式 |
**响应示例:**
```json
{
"code": 200,
"message": "获取成功",
"data": {
"items": [
{
"id": 1,
"name": "iPhone 15",
"price": 5999.00,
"originalPrice": 6999.00,
"image": "/images/iphone15.jpg",
"category": "electronics",
"stock": 100,
"description": "最新款iPhone手机"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 1000,
"pages": 100
}
}
}
```
### 获取商品详情
**Endpoint:** `GET /api/v1/products/:id`
**路径参数:**
- `id`: 商品ID
**响应示例:**
```json
{
"code": 200,
"message": "获取成功",
"data": {
"id": 1,
"name": "iPhone 15",
"price": 5999.00,
"originalPrice": 6999.00,
"images": [
"/images/iphone15-1.jpg",
"/images/iphone15-2.jpg"
],
"category": "electronics",
"brand": "Apple",
"stock": 100,
"description": "最新款iPhone手机",
"specifications": {
"color": "黑色",
"storage": "256GB",
"screen": "6.1英寸"
},
"reviews": {
"averageRating": 4.8,
"totalReviews": 150
}
}
}
```
## 📊 数据字典
### 订单状态
| 状态值 | 描述 |
|--------|------|
| pending | 待支付 |
| paid | 已支付 |
| shipped | 已发货 |
| completed | 已完成 |
| cancelled | 已取消 |
### 商品分类
| 分类值 | 描述 |
|--------|------|
| electronics | 电子产品 |
| clothing | 服装服饰 |
| books | 图书文具 |
| home | 家居生活 |
| sports | 运动户外 |
### 错误代码
| 代码 | 描述 |
|------|------|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 401 | 未授权访问 |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 409 | 资源冲突 |
| 500 | 服务器内部错误 |
| 503 | 服务不可用 |
## 🔗 API 版本控制
当前API版本为v1所有接口前缀为`/api/v1/`
版本更新策略:
- 向后兼容的修改直接更新
- 不兼容的修改创建新版本v2
- 旧版本API保持维护至少6个月
## 📡 接口限流
### 限流策略
- 匿名用户: 60请求/分钟
- 认证用户: 120请求/分钟
- VIP用户: 300请求/分钟
### 限流响应
当超过限流阈值时返回:
```json
{
"code": 429,
"message": "请求过于频繁,请稍后再试",
"retryAfter": 60
}
```
## 🧪 接口测试
### 使用curl测试
```bash
# 用户登录
curl -X POST http://localhost:3000/api/v1/users/login \
-H "Content-Type: application/json" \
-d '{"username":"testuser","password":"password123"}'
# 获取用户信息
curl -X GET http://localhost:3000/api/v1/users/profile \
-H "Authorization: Bearer <token>"
```
### 使用Postman测试
1. 导入Postman集合文件
2. 设置环境变量base_url, token等
3. 运行测试用例
## 📝 更新日志
### v1.0.0 (2024-01-01)
- 用户注册登录接口
- 订单管理接口
- 商品管理接口
- 基础认证系统
---
*最后更新: 2024年* 📅

162
README.md Normal file
View File

@@ -0,0 +1,162 @@
# 🏗️ 杰邦科项目
## 📋 项目概述
杰邦科是一个综合性的管理系统,包含后台管理、微信小程序和官方网站三个主要模块。
## 🗂️ 项目结构
```
jiebanke/
├── 📁 backend/ # 后端服务 (Node.js + Express)
├── 📁 admin-system/ # 后台管理系统 (Vue 3 + Element Plus)
├── 📁 website/ # 官方网站 (Vue 3)
├── 📁 mini-program/ # 微信小程序矩阵 (原生小程序)
├── 📁 docs/ # 项目文档
├── 📁 scripts/ # 工具脚本
├── 📁 test/ # 测试文件目录
└── 📄 README.md # 项目说明 (当前文件)
```
## 🚀 快速开始
### 环境要求
- Node.js 16.x+
- MySQL 8.0+
- npm 8.x+
### 安装依赖
```bash
# 安装后端依赖
cd backend && npm install
# 安装后台管理依赖
cd admin-system && npm install
# 安装官网依赖
cd website && npm install
# 安装小程序依赖
cd mini-program && npm install
```
### 启动开发环境
```bash
# 启动后端服务
cd backend && npm run dev
# 启动后台管理 (新终端)
cd admin-system && npm run dev
# 启动官方网站 (新终端)
cd website && npm run dev
```
## 📖 项目文档
所有详细文档位于 `docs/` 目录:
- 📄 [架构设计](docs/architecture.md) - 系统架构和技术栈
- 📄 [API文档](docs/API_DOCS.md) - 完整的API接口说明
- 📄 [部署指南](docs/DEPLOYMENT.md) - 开发、测试、生产环境部署
- 📄 [数据库设计](docs/database-design.md) - 数据库表结构和关系
- 📄 [需求文档](docs/requirements.md) - 业务需求和功能说明
- 📄 [详细设计](docs/detailed_design.md) - 系统详细设计方案
- 📄 [开发计划](docs/development_plan.md) - 项目开发进度计划
## 🛠️ 开发工具
### 脚本工具
项目提供了一些有用的开发脚本:
```bash
# 数据库连接测试
cd backend && npm run test-db
# API接口测试
cd backend && npm run test-api
# 数据库初始化
cd backend && npm run db:reset
```
### 环境配置
复制环境变量模板并配置:
```bash
# 后端环境配置
cp backend/.env.example backend/.env
# 后台管理环境配置
cp admin-system/.env.example admin-system/.env
```
## 🌐 访问地址
- **后端API**: http://localhost:3000
- **后台管理**: http://localhost:3001
- **官方网站**: http://localhost:3002
- **小程序**: 使用微信开发者工具打开 `mini-program/` 目录
## 📦 依赖管理
### 主要技术栈
**后端**:
- Node.js + Express.js
- Sequelize ORM
- JWT 认证
- MySQL 数据库
**前端**:
- 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
---
*最后更新: 2024年* 📅

View File

@@ -1,61 +0,0 @@
const bcrypt = require('bcryptjs');
const { query } = require('./backend/src/config/database');
// 数据库配置
const dbConfig = {
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!',
database: 'jiebandata'
};
async function addTestAdmin() {
try {
// 加密密码
const saltRounds = 10;
const plainPassword = 'admin123';
const hashedPassword = await bcrypt.hash(plainPassword, saltRounds);
console.log('加密后的密码:', hashedPassword);
// 插入测试管理员账户
const insertSQL = `
INSERT INTO admins (username, password, email, nickname, role)
VALUES (?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
password = VALUES(password),
email = VALUES(email),
nickname = VALUES(nickname),
role = VALUES(role)
`;
const params = [
'testadmin',
hashedPassword,
'testadmin@example.com',
'测试管理员',
'admin'
];
// 注意这里我们需要直接使用mysql2连接数据库因为backend/src/config/database可能依赖环境变量
const mysql = require('mysql2/promise');
const connection = await mysql.createConnection(dbConfig);
const [result] = await connection.execute(insertSQL, params);
console.log('✅ 测试管理员账户创建/更新成功');
console.log('受影响的行数:', result.affectedRows);
// 验证插入的数据
const [rows] = await connection.execute('SELECT * FROM admins WHERE username = ?', ['testadmin']);
console.log('\n插入的管理员信息:');
console.log(rows[0]);
await connection.end();
} catch (error) {
console.error('❌ 创建测试管理员账户失败:', error.message);
console.error(error.stack);
}
}
addTestAdmin();

View File

@@ -1,264 +0,0 @@
# 🏗️ 系统架构文档
## 📋 项目概述
杰邦科项目是一个综合性的管理系统,包含后台管理、微信小程序和官网三个主要模块。
## 🎯 技术栈
### 后端技术栈
- **运行时**: Node.js + Express.js
- **数据库**: MySQL 8.0
- **ORM**: Sequelize
- **认证**: JWT + bcrypt
- **缓存**: Redis (可选)
- **消息队列**: RabbitMQ (可选)
### 前端技术栈
- **后台管理系统**: Vue 3 + Element Plus
- **微信小程序**: 原生小程序 + Vant Weapp
- **官方网站**: Vue 3 + Vue Router
### 开发工具
- **包管理**: npm
- **容器化**: Docker + Docker Compose
- **代码质量**: ESLint + Prettier
- **测试**: Jest + Supertest
## 🏢 系统架构
```mermaid
graph TB
subgraph "前端应用"
A[后台管理系统]
B[微信小程序]
C[官方网站]
end
subgraph "后端服务"
D[API Gateway]
E[用户服务]
F[业务服务]
G[文件服务]
end
subgraph "数据层"
H[MySQL]
I[Redis]
J[MinIO]
end
A --> D
B --> D
C --> D
D --> E
D --> F
D --> G
E --> H
F --> H
G --> J
E --> I
```
## 🗄️ 数据库设计
### 核心表结构
```mermaid
erDiagram
users ||--o{ orders : places
users ||--o{ addresses : has
users {
bigint id PK
varchar username
varchar password_hash
varchar email
varchar phone
datetime created_at
datetime updated_at
}
orders ||--o{ order_items : contains
orders {
bigint id PK
bigint user_id FK
decimal total_amount
varchar status
datetime created_at
}
products ||--o{ order_items : included_in
products {
bigint id PK
varchar name
decimal price
text description
}
```
## 🌐 环境配置
### 开发环境 (Development)
```env
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=rootpassword
DB_DATABASE=jiebanke_dev
NODE_ENV=development
```
### 测试环境 (Test)
```env
DB_HOST=192.168.0.240
DB_PORT=3306
DB_USER=root
DB_PASSWORD=aiotAiot123!
DB_DATABASE=jiebandata_test
NODE_ENV=test
```
### 生产环境 (Production)
```env
DB_HOST=129.211.213.226
DB_PORT=9527
DB_USER=root
DB_PASSWORD=Aiot123
DB_DATABASE=jiebandata
NODE_ENV=production
```
## 🔌 API 设计
### 用户模块 API
| 方法 | 路径 | 描述 | 认证 |
|------|------|------|------|
| POST | `/api/v1/users/register` | 用户注册 | 否 |
| POST | `/api/v1/users/login` | 用户登录 | 否 |
| GET | `/api/v1/users/profile` | 获取用户信息 | JWT |
| PUT | `/api/v1/users/profile` | 更新用户信息 | JWT |
### 示例请求
```javascript
// 用户登录
POST /api/v1/users/login
Content-Type: application/json
{
"username": "testuser",
"password": "password123"
}
```
## 🚀 部署架构
### 开发部署
```mermaid
graph LR
A[本地开发机] --> B[Docker Compose]
B --> C[MySQL容器]
B --> D[Node.js应用]
B --> E[Redis容器]
```
### 生产部署
```mermaid
graph TB
subgraph "云服务器"
A[Nginx]
B[Node.js集群]
C[MySQL主从]
D[Redis哨兵]
end
A --> B
B --> C
B --> D
```
## 📊 监控与日志
- **应用监控**: PM2 + Keymetrics
- **日志管理**: Winston + ELK Stack
- **性能监控**: New Relic / Datadog
- **错误追踪**: Sentry
## 🔒 安全架构
### 认证授权
- JWT Token 认证
- RBAC (基于角色的访问控制)
- API 速率限制
### 数据安全
- HTTPS 加密传输
- 密码加盐哈希存储
- SQL 注入防护
- XSS 攻击防护
### 网络安全
- 防火墙规则
- IP 白名单
- DDoS 防护
## 📈 性能优化
### 数据库优化
- 索引优化
- 查询缓存
- 读写分离
### 应用优化
- 响应压缩
- 静态资源CDN
- 内存缓存
### 前端优化
- 代码分割
- 懒加载
- 图片优化
## 🛠️ 开发规范
### 代码规范
- ESLint + Prettier 统一代码风格
- Git Commit 消息规范
- 代码审查流程
### 分支策略
- Git Flow 工作流
- 功能分支开发
- 发布分支管理
### 测试策略
- 单元测试覆盖核心逻辑
- 集成测试API接口
- E2E测试用户流程
## 📝 文档体系
1. **ARCHITECTURE.md** - 系统架构文档 (当前文件)
2. **README.md** - 项目说明文档
3. **API_DOCS.md** - API接口文档
4. **DEPLOYMENT.md** - 部署指南
5. **DEVELOPMENT.md** - 开发指南
## 🎯 后续规划
### 短期目标
- [ ] 完善用户管理系统
- [ ] 实现订单业务流程
- [ ] 部署测试环境
### 中期目标
- [ ] 微服务架构改造
- [ ] 容器化部署
- [ ] 自动化测试覆盖
### 长期目标
- [ ] 大数据分析平台
- [ ] AI智能推荐
- [ ] 多语言国际化
---
*最后更新: 2024年* 📅

View File

@@ -1,60 +0,0 @@
const mysql = require('mysql2');
// 数据库连接配置
const dbConfig = {
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!',
database: 'jiebandata'
};
// 创建连接
const connection = mysql.createConnection(dbConfig);
// 连接数据库
connection.connect((err) => {
if (err) {
console.error('数据库连接失败: ' + err.stack);
return;
}
console.log('数据库连接成功连接ID: ' + connection.threadId);
// 检查animals表结构
connection.query('DESCRIBE animals', (error, results) => {
if (error) {
console.error('查询animals表结构失败: ' + error.stack);
connection.end();
return;
}
console.log('\n=== animals表结构 ===');
console.table(results);
// 检查merchants表结构
connection.query('DESCRIBE merchants', (error, results) => {
if (error) {
console.error('查询merchants表结构失败: ' + error.stack);
connection.end();
return;
}
console.log('\n=== merchants表结构 ===');
console.table(results);
// 检查users表结构
connection.query('DESCRIBE users', (error, results) => {
if (error) {
console.error('查询users表结构失败: ' + error.stack);
connection.end();
return;
}
console.log('\n=== users表结构 ===');
console.table(results);
connection.end();
});
});
});
});

View File

@@ -1,103 +0,0 @@
const mysql = require('mysql2');
// 数据库配置
const configs = [
{
name: '测试环境',
host: '192.168.0.240',
port: 3306,
user: 'root',
password: 'aiot$Aiot123'
},
{
name: '生产环境',
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!'
}
];
// 简单的SQL语句避免编码问题
const sqlStatements = [
"CREATE DATABASE IF NOT EXISTS jiebandata CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
"USE jiebandata",
`CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
openid VARCHAR(64) UNIQUE NOT NULL,
nickname VARCHAR(50) NOT NULL,
avatar VARCHAR(255),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB`
];
function executeSQL(connection, sql, description) {
return new Promise((resolve, reject) => {
console.log(description);
connection.query(sql, (err, results) => {
if (err) {
console.error('失败:', err.message);
reject(err);
} else {
console.log('成功');
resolve(results);
}
});
});
}
async function setupDatabase(config) {
console.log(`\n开始设置 ${config.name} 数据库...`);
const connection = mysql.createConnection({
host: config.host,
port: config.port,
user: config.user,
password: config.password
});
try {
await new Promise((resolve, reject) => {
connection.connect((err) => {
if (err) reject(err);
else resolve();
});
});
for (let i = 0; i < sqlStatements.length; i++) {
await executeSQL(connection, sqlStatements[i], `执行SQL ${i + 1}/${sqlStatements.length}`);
}
console.log('✅ 数据库设置完成');
return true;
} catch (error) {
console.error('❌ 数据库设置失败:', error.message);
return false;
} finally {
connection.end();
}
}
async function main() {
console.log('🎯 结伴客数据库初始化');
console.log('='.repeat(50));
let successCount = 0;
for (const config of configs) {
const success = await setupDatabase(config);
if (success) successCount++;
console.log('\n' + '='.repeat(50));
}
console.log(`📊 完成: ${successCount}/${configs.length} 个环境成功`);
if (successCount > 0) {
console.log('\n🎉 数据库初始化完成!');
console.log('现在可以运行测试脚本来验证数据库结构。');
}
}
main().catch(console.error);

View File

@@ -1,137 +0,0 @@
const mysql = require('mysql2');
// 数据库配置
const dbConfig = {
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!',
database: 'jiebandata'
};
// 创建连接
const connection = mysql.createConnection(dbConfig);
// 连接数据库
connection.connect((err) => {
if (err) {
console.error('数据库连接失败: ' + err.stack);
return;
}
console.log('数据库连接成功连接ID: ' + connection.threadId);
// 查询所有表
connection.query('SHOW TABLES', (error, results) => {
if (error) {
console.error('查询表失败: ' + error.stack);
connection.end();
return;
}
console.log('数据库中的所有表:');
const tables = results.map(row => {
const tableName = Object.values(row)[0];
console.log('- ' + tableName);
return tableName;
});
// 检查是否存在管理员表
const adminTableExists = tables.some(table =>
table.includes('admin') || table.includes('Admin') || table.includes('ADMIN')
);
if (adminTableExists) {
console.log('\n✅ 找到可能的管理员相关表');
// 显示管理员相关表结构
const adminTables = tables.filter(table =>
table.includes('admin') || table.includes('Admin') || table.includes('ADMIN')
);
showTableStructure(adminTables, 0);
} else {
console.log('\n❌ 未找到管理员相关表');
// 显示所有表的简要信息
showAllTablesInfo(tables, 0);
}
});
// 显示表结构的递归函数
function showTableStructure(tables, index) {
if (index >= tables.length) {
connection.end();
return;
}
const tableName = tables[index];
console.log(`\n${tableName} 表结构:`);
connection.query(`DESCRIBE ${tableName}`, (error, results) => {
if (error) {
console.error(`查询 ${tableName} 表结构失败: ` + error.stack);
} else {
console.table(results.map(row => ({
字段: row.Field,
类型: row.Type,
: row.Null,
: row.Key,
默认值: row.Default,
额外: row.Extra
})));
}
showTableStructure(tables, index + 1);
});
}
// 显示所有表信息的递归函数
function showAllTablesInfo(tables, index) {
if (index >= tables.length) {
// 创建管理员表的SQL
console.log('\n=== 建议创建的管理员表结构 ===');
const createAdminTableSQL = `
CREATE TABLE admins (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
email VARCHAR(100) UNIQUE,
nickname VARCHAR(100),
avatar VARCHAR(255),
role ENUM('super_admin', 'admin', 'operator') DEFAULT 'admin',
status TINYINT DEFAULT 1,
last_login TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);`;
console.log(createAdminTableSQL);
// 插入测试数据的SQL
console.log('\n=== 插入测试数据 ===');
const insertTestDataSQL = `
INSERT INTO admins (username, password, email, nickname, role) VALUES
('admin', '$2b$10$rVuz/q97ocR1Zb07DzW5F.9Qx6B6HnV7JFzQb5nR1W3v7Z2mH4n6O', 'admin@example.com', '超级管理员', 'super_admin'),
('operator', '$2b$10$rVuz/q97ocR1Zb07DzW5F.9Qx6B6HnV7JFzQb5nR1W3v7Z2mH4n6O', 'operator@example.com', '操作员', 'operator');
`;
console.log(insertTestDataSQL);
connection.end();
return;
}
const tableName = tables[index];
console.log(`\n${tableName} 表信息:`);
connection.query(`SELECT COUNT(*) as count FROM ${tableName}`, (error, results) => {
if (error) {
console.error(`查询 ${tableName} 表数据量失败: ` + error.stack);
} else {
console.log(`数据量: ${results[0].count}`);
}
showAllTablesInfo(tables, index + 1);
});
}
});

View File

@@ -1,85 +0,0 @@
const mysql = require('mysql2');
// 数据库配置
const dbConfig = {
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!',
database: 'jiebandata'
};
// 创建连接
const connection = mysql.createConnection(dbConfig);
// 连接数据库
connection.connect((err) => {
if (err) {
console.error('数据库连接失败: ' + err.stack);
return;
}
console.log('数据库连接成功连接ID: ' + connection.threadId);
// 创建管理员表
const createAdminTableSQL = `
CREATE TABLE IF NOT EXISTS admins (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
email VARCHAR(100) UNIQUE,
nickname VARCHAR(100),
avatar VARCHAR(255),
role ENUM('super_admin', 'admin', 'operator') DEFAULT 'admin',
status TINYINT DEFAULT 1,
last_login TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_username (username),
INDEX idx_email (email),
INDEX idx_role (role)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`;
connection.query(createAdminTableSQL, (error, results) => {
if (error) {
console.error('创建管理员表失败: ' + error.stack);
connection.end();
return;
}
console.log('✅ 管理员表创建成功');
// 检查是否已存在测试数据
connection.query('SELECT COUNT(*) as count FROM admins', (error, results) => {
if (error) {
console.error('查询管理员表数据量失败: ' + error.stack);
connection.end();
return;
}
if (results[0].count > 0) {
console.log('✅ 管理员表中已有数据,跳过插入测试数据');
connection.end();
return;
}
// 插入测试数据
const insertTestDataSQL = `
INSERT INTO admins (username, password, email, nickname, role) VALUES
('admin', '$2b$10$rVuz/q97ocR1Zb07DzW5F.9Qx6B6HnV7JFzQb5nR1W3v7Z2mH4n6O', 'admin@example.com', '超级管理员', 'super_admin'),
('operator', '$2b$10$rVuz/q97ocR1Zb07DzW5F.9Qx6B6HnV7JFzQb5nR1W3v7Z2mH4n6O', 'operator@example.com', '操作员', 'operator');
`;
connection.query(insertTestDataSQL, (error, results) => {
if (error) {
console.error('插入测试数据失败: ' + error.stack);
connection.end();
return;
}
console.log('✅ 测试数据插入成功,插入 ' + results.affectedRows + ' 条记录');
connection.end();
});
});
});
});

View File

@@ -1,65 +0,0 @@
const mysql = require('mysql2');
// 数据库配置
const dbConfig = {
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!',
database: 'jiebandata'
};
// 创建连接
const connection = mysql.createConnection(dbConfig);
// 连接数据库
connection.connect((err) => {
if (err) {
console.error('数据库连接失败: ' + err.stack);
return;
}
console.log('数据库连接成功连接ID: ' + connection.threadId);
// 查询管理员表结构
connection.query('DESCRIBE admins', (error, results) => {
if (error) {
console.error('查询管理员表结构失败: ' + error.stack);
connection.end();
return;
}
console.log('\n=== 管理员表结构 ===');
console.table(results.map(row => ({
字段: row.Field,
类型: row.Type,
: row.Null,
: row.Key,
默认值: row.Default,
额外: row.Extra
})));
// 查询管理员数据
connection.query('SELECT * FROM admins', (error, results) => {
if (error) {
console.error('查询管理员数据失败: ' + error.stack);
connection.end();
return;
}
console.log('\n=== 管理员数据 ===');
console.table(results.map(row => ({
ID: row.id,
用户名: row.username,
邮箱: row.email,
昵称: row.nickname,
角色: row.role,
状态: row.status,
创建时间: row.created_at,
最后登录: row.last_login
})));
console.log('\n✅ 数据库验证完成');
connection.end();
});
});
});

531
docs/API_DOCS.md Normal file
View File

@@ -0,0 +1,531 @@
# 📚 结伴客API接口文档
## 📋 文档说明
本文档详细描述了结伴客项目的所有API接口包括请求参数、响应格式和错误代码。结伴客是一个专注于结伴旅行和动物认领的社交平台。
## 🔐 认证方式
### JWT Token 认证
所有需要认证的API必须在请求头中携带Token
```
Authorization: Bearer <your_jwt_token>
```
### Token 获取
通过微信登录接口获取TokenToken有效期为7天。
## 👥 用户模块
### 微信用户登录
**Endpoint:** `POST /api/v1/auth/wechat-login`
**请求参数:**
```json
{
"code": "string, required, 微信登录code",
"userInfo": {
"nickName": "string, required, 用户昵称",
"avatarUrl": "string, required, 用户头像",
"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"
}
}
}
```
**错误代码:**
- `400`: 参数验证失败
- `401`: 登录失败
- `500`: 服务器内部错误
### 获取用户信息
**Endpoint:** `GET /api/v1/users/profile`
**请求头:**
```
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": "test@example.com",
"travelCount": 5,
"animalClaimCount": 2,
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
}
```
**错误代码:**
- `401`: 未授权访问
- `404`: 用户不存在
- `500`: 服务器内部错误
## 🧳 旅行结伴模块
### 发布旅行计划
**Endpoint:** `POST /api/v1/travel/plans`
**请求头:**
```
Authorization: Bearer <token>
```
**请求参数:**
```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)"
}
```
**响应示例:**
```json
{
"code": 200,
"message": "旅行计划发布成功",
"data": {
"id": 1001,
"userId": 1,
"destination": "云南大理",
"startDate": "2024-06-01",
"endDate": "2024-06-07",
"budget": 2000,
"interests": "美食,摄影,文化",
"status": "active",
"createdAt": "2024-01-01T00:00:00.000Z"
}
}
```
### 获取旅行计划列表
**Endpoint:** `GET /api/v1/travel/plans`
**请求头:**
```
Authorization: Bearer <token>
```
**查询参数:**
```
?page=1&limit=10&destination=大理&startDate=2024-06-01&endDate=2024-06-30
```
| 参数 | 类型 | 说明 |
|------|------|------|
| page | number | 页码默认1 |
| limit | number | 每页数量默认10 |
| destination | string | 目的地过滤 |
| startDate | string | 开始日期过滤 |
| endDate | string | 结束日期过滤 |
| budgetMin | number | 最低预算 |
| budgetMax | number | 最高预算 |
**响应示例:**
```json
{
"code": 200,
"message": "获取成功",
"data": {
"items": [
{
"id": 1001,
"userId": 1,
"userInfo": {
"nickname": "旅行达人",
"avatar": "https://avatar.url"
},
"destination": "云南大理",
"startDate": "2024-06-01",
"endDate": "2024-06-07",
"budget": 2000,
"interests": "美食,摄影,文化",
"matchScore": 85,
"createdAt": "2024-01-01T00:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 100,
"pages": 10
}
}
}
```
### 发起结伴邀请
**Endpoint:** `POST /api/v1/travel/invitations`
**请求头:**
```
Authorization: Bearer <token>
```
**请求参数:**
```json
{
"travelPlanId": "number, required, 旅行计划ID",
"inviteeId": "number, required, 被邀请用户ID",
"message": "string, optional, 邀请消息"
}
```
**响应示例:**
```json
{
"code": 200,
"message": "邀请发送成功",
"data": {
"id": 5001,
"travelPlanId": 1001,
"inviterId": 1,
"inviteeId": 2,
"status": "pending",
"message": "一起结伴去大理吧!",
"createdAt": "2024-01-01T00:00:00.000Z"
}
}
```
## 🐄 动物认领模块
### 获取可认领动物列表
**Endpoint:** `GET /api/v1/animals/available`
**查询参数:**
```
?page=1&limit=10&species=牛&farmLocation=云南
```
| 参数 | 类型 | 说明 |
|------|------|------|
| page | number | 页码默认1 |
| limit | number | 每页数量默认10 |
| species | string | 动物种类过滤 |
| breed | string | 品种过滤 |
| farmLocation | string | 农场位置过滤 |
| priceMin | number | 最低价格 |
| priceMax | number | 最高价格 |
**响应示例:**
```json
{
"code": 200,
"message": "获取成功",
"data": {
"items": [
{
"id": 2001,
"name": "小白",
"species": "牛",
"breed": "荷斯坦",
"birthDate": "2023-01-15",
"personality": "温顺亲人",
"farmLocation": "云南大理幸福农场",
"price": 2999,
"images": ["https://animal.image1.jpg", "https://animal.image2.jpg"],
"merchantInfo": {
"businessName": "幸福农场",
"contactPerson": "张老板"
},
"claimCount": 3,
"createdAt": "2024-01-01T00:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 50,
"pages": 5
}
}
}
```
### 认领动物
**Endpoint:** `POST /api/v1/animals/claim`
**请求头:**
```
Authorization: Bearer <token>
```
**请求参数:**
```json
{
"animalId": "number, required, 动物ID",
"duration": "number, required, 认领时长(月)",
"agreementAccepted": "boolean, required, 是否接受协议"
}
```
**响应示例:**
```json
{
"code": 200,
"message": "认领成功",
"data": {
"id": 3001,
"userId": 1,
"animalId": 2001,
"animalName": "小白",
"duration": 12,
"totalAmount": 35988,
"status": "paid",
"startDate": "2024-01-01",
"endDate": "2025-01-01",
"createdAt": "2024-01-01T00:00:00.000Z"
}
}
```
## 💐 送花服务模块
### 获取鲜花商品列表
**Endpoint:** `GET /api/v1/flower/products`
**查询参数:**
```
?page=1&limit=10&category=情人节&merchantId=1
```
| 参数 | 类型 | 说明 |
|------|------|------|
| page | number | 页码默认1 |
| limit | number | 每页数量默认10 |
| category | string | 商品分类过滤 |
| merchantId | number | 商家ID过滤 |
| priceMin | number | 最低价格 |
| priceMax | number | 最高价格 |
**响应示例:**
```json
{
"code": 200,
"message": "获取成功",
"data": {
"items": [
{
"id": 4001,
"name": "红玫瑰礼盒",
"description": "11朵红玫瑰精美礼盒",
"price": 199,
"originalPrice": 259,
"images": ["https://flower.image1.jpg"],
"category": "情人节",
"merchantInfo": {
"businessName": "爱之花店",
"contactPhone": "13800138000"
},
"salesCount": 150,
"rating": 4.8,
"status": "active",
"createdAt": "2024-01-01T00:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 100,
"pages": 10
}
}
}
```
### 下单送花
**Endpoint:** `POST /api/v1/flower/orders`
**请求头:**
```
Authorization: Bearer <token>
```
**请求参数:**
```json
{
"productId": "number, required, 商品ID",
"quantity": "number, required, 数量",
"recipientInfo": {
"name": "string, required, 收花人姓名",
"phone": "string, required, 收花人电话",
"address": "string, required, 配送地址"
},
"deliveryDate": "string, required, 配送日期(YYYY-MM-DD)",
"message": "string, optional, 祝福语"
}
```
**响应示例:**
```json
{
"code": 200,
"message": "下单成功",
"data": {
"id": 5001,
"orderNo": "FLOWER202401010001",
"productId": 4001,
"productName": "红玫瑰礼盒",
"quantity": 1,
"totalAmount": 199,
"recipientName": "李小姐",
"recipientPhone": "13800138001",
"deliveryAddress": "北京市朝阳区xxx路xxx号",
"deliveryDate": "2024-02-14",
"status": "pending",
"createdAt": "2024-01-01T00:00:00.000Z"
}
}
```
## 📊 数据字典
### 旅行计划状态
| 状态值 | 描述 |
|--------|------|
| active | 活跃中 |
| completed | 已完成 |
| cancelled | 已取消 |
### 结伴邀请状态
| 状态值 | 描述 |
|--------|------|
| pending | 待接受 |
| accepted | 已接受 |
| rejected | 已拒绝 |
| cancelled | 已取消 |
### 动物认领状态
| 状态值 | 描述 |
|--------|------|
| pending | 待支付 |
| paid | 已支付 |
| active | 认领中 |
| completed | 已完成 |
| cancelled | 已取消 |
### 送花订单状态
| 状态值 | 描述 |
|--------|------|
| pending | 待支付 |
| paid | 已支付 |
| confirmed | 商家已确认 |
| delivering | 配送中 |
| completed | 已完成 |
| cancelled | 已取消 |
### 错误代码
| 代码 | 描述 |
|------|------|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 401 | 未授权访问 |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 409 | 资源冲突 |
| 429 | 请求过于频繁 |
| 500 | 服务器内部错误 |
| 503 | 服务不可用 |
## 🔗 API 版本控制
当前API版本为v1所有接口前缀为`/api/v1/`
版本更新策略:
- 向后兼容的修改直接更新
- 不兼容的修改创建新版本v2
- 旧版本API保持维护至少6个月
## 📡 接口限流
### 限流策略
- 匿名用户: 60请求/分钟
- 认证用户: 120请求/分钟
- VIP用户: 300请求/分钟
### 限流响应
当超过限流阈值时返回:
```json
{
"code": 429,
"message": "请求过于频繁,请稍后再试",
"retryAfter": 60
}
```
## 🧪 接口测试
### 使用curl测试
```bash
# 微信用户登录
curl -X POST http://localhost:3000/api/v1/auth/wechat-login \
-H "Content-Type: application/json" \
-d '{"code":"wxlogincode123","userInfo":{"nickName":"测试用户","avatarUrl":"https://avatar.url","gender":1}}'
# 获取旅行计划列表
curl -X GET http://localhost:3000/api/v1/travel/plans \
-H "Authorization: Bearer <token>"
```
### 使用Postman测试
1. 导入Postman集合文件
2. 设置环境变量base_url, token等
3. 运行测试用例
## 📝 更新日志
### v1.0.0 (2024-01-01)
- 微信用户登录接口
- 旅行结伴管理接口
- 动物认领管理接口
- 送花服务接口
- 基础认证系统
---
*最后更新: 2024年* 📅

View File

@@ -1,41 +1,50 @@
# 结伴客系统架构文档
# 🏗️ 系统架构文档
## 1. 系统架构概览
## 📋 项目概述
杰邦科项目是一个综合性的管理系统,包含后台管理、微信小程序和官网三个主要模块。
### 1.1 架构图
## 🎯 技术栈
### 后端技术栈
- **运行时**: Node.js + Express.js
- **数据库**: MySQL 8.0
- **ORM**: Sequelize
- **认证**: JWT + bcrypt
- **缓存**: Redis (可选)
- **消息队列**: RabbitMQ (可选)
### 前端技术栈
- **后台管理系统**: Vue 3 + Element Plus
- **微信小程序**: 原生小程序 + Vant Weapp
- **官方网站**: Vue 3 + Vue Router
### 开发工具
- **包管理**: npm
- **容器化**: Docker + Docker Compose
- **代码质量**: ESLint + Prettier
- **测试**: Jest + Supertest
## 🏢 系统架构
```mermaid
graph TB
subgraph "客户端层"
A[微信小程序 uni-app]
B[后台管理系统 Vue 3 + Ant Design]
C[官网系统 HTML5 + Bootstrap]
subgraph "前端应用"
A[后台管理系统]
B[微信小程序]
C[官方网站]
end
subgraph "接入层"
D[Express API Gateway]
subgraph "后端服务"
D[API Gateway]
E[用户服务]
F[业务服务]
G[文件服务]
end
subgraph "应用服务层"
E[认证服务]
F[用户服务]
G[旅行服务]
H[动物服务]
I[订单服务]
J[管理员服务]
end
subgraph "基础设施层"
K[MySQL 数据库]
L[Redis 缓存]
M[RabbitMQ 消息队列]
N[文件存储]
end
subgraph "监控运维层"
O[Swagger API 文档]
P[Winston 日志系统]
Q[健康检查监控]
subgraph "数据层"
H[MySQL]
I[Redis]
J[MinIO]
end
A --> D
@@ -44,527 +53,351 @@ graph TB
D --> E
D --> F
D --> G
D --> H
D --> I
D --> J
E --> K
F --> K
G --> K
H --> K
I --> K
J --> K
E --> L
F --> L
G --> L
I --> M
E --> N
F --> N
H --> N
D --> O
D --> P
D --> Q
E --> H
F --> H
G --> J
E --> I
```
**系统架构层次说明:**
## 🗄️ 数据库设计
**1. 客户端层**
- **微信小程序**: 基于uni-app开发提供用户端功能
- **后台管理系统**: 基于Vue.js 3 + TypeScript + Ant Design Vue + Pinia开发提供管理功能
- **官网系统**: 基于HTML5 + Bootstrap开发提供企业宣传功能
### 核心表结构设计
**2. 接入层**
- **API网关**: 基于Express.js框架提供统一的API接入、路由分发、安全防护和请求处理所有API路径前缀为`/api/v1`
**3. 应用服务层**
- **认证服务**: 用户身份认证、JWT令牌管理和权限控制
- **用户服务**: 用户信息管理、个人中心功能和用户统计
- **旅行服务**: 旅行计划创建、查询、匹配和管理功能
- **动物服务**: 动物信息管理、认领流程和动物统计
- **订单服务**: 订单创建、支付处理和交易管理
- **管理员服务**: 管理员权限管理和系统配置
**4. 基础设施层**
- **MySQL数据库**: 单实例架构,存储核心业务数据,使用连接池优化性能(测试环境: 192.168.0.240:3306生产环境: 129.211.213.226:9527
- **Redis缓存**: 单实例模式,提供会话管理和数据缓存服务
- **RabbitMQ消息队列**: 异步消息处理和解耦(待实现)
- **文件存储**: 本地文件系统,存储用户上传的图片和文件资源
**5. 监控运维层**
- **Swagger API文档**: 自动生成的API接口文档
- **Winston日志系统**: 结构化日志记录和分析
- **健康检查监控**: 系统状态监控和性能统计
**架构连接关系:**
- 所有客户端通过API网关访问后端服务
- 应用服务层各服务独立部署通过API网关统一暴露接口
- 认证服务、用户服务、旅行服务、动物服务、商家服务连接MySQL数据库和Redis缓存
- 支付服务和推广服务连接MySQL数据库和RabbitMQ消息队列
- 认证服务、用户服务、动物服务、商家服务连接对象存储
- 监控系统、日志系统、CI/CD系统监控所有应用服务
## 2. 项目结构
```
结伴客项目 (根目录)
├── mini-program // 微信小程序 (uni-app)
├── pages
├── user // 用户相关页面
├── login // 登录页面
├── register // 注册页面
├── profile // 个人主页
└── settings // 设置页面
│ │ ├── merchant // 商家相关页面
│ │ │ ├── register // 商家注册
│ │ ├── profile // 商家主页
└── dashboard // 商家控制台
├── travel // 旅行结伴页面
├── plan // 旅行计划
├── search // 搜索结伴
└── activities // 其他活动
│ │ ├── animal // 动物认领页面
├── list // 动物列表
├── detail // 动物详情
│ │ │ └── claim // 认领流程
│ │ ├── social // 社交互动页面
│ │ │ ├── messages // 消息聊天
└── feed // 动态分享
├── flower // 送花服务页面
├── products // 鲜花产品
└── orders // 订单管理
└── promotion // 推广奖励页面
│ │ ├── invite // 邀请推广
└── rewards // 奖励中心
│ ├── components // 可复用组件
├── common // 通用组件
│ │ ├── user // 用户相关组件
│ │ ├── travel // 旅行相关组件
├── animal // 动物相关组件
│ │ ├── social // 社交相关组件
│ │ ├── merchant // 商家相关组件
│ │ └── flower // 鲜花相关组件
│ ├── utils // 工具函数
│ │ ├── request // 网络请求封装
│ ├── auth // 认证相关工具
├── storage // 存储相关工具
└── helpers // 辅助函数
├── static // 静态资源
├── images // 图片资源
└── styles // 样式文件
│ └── store // 状态管理
├── modules // 模块化状态
│ ├── user // 用户状态
│ ├── travel // 旅行状态
│ ├── animal // 动物状态
│ │ ├── social // 社交状态
│ ├── merchant // 商家状态
│ ├── flower // 鲜花状态
│ └── promotion // 推广状态
└── index.js // 状态管理入口
├── admin-system // 后台管理系统 (Vue.js 3 + TypeScript + Ant Design Vue + Pinia)
├── public // 静态资源
├── src
├── api // API接口 (TypeScript类型定义)
├── user // 用户相关接口
│ │ ├── merchant // 商家相关接口
│ │ │ ├── travel // 旅行相关接口
│ │ │ ├── animal // 动物相关接口
├── order // 订单相关接口
├── promotion // 推广相关接口
└── system // 系统管理接口
├── assets // 静态资源
│ │ ├── components // 公共组件 (Vue 3 Composition API)
├── layout // 布局组件
├── common // 通用组件
├── user // 用户相关组件
├── merchant // 商家相关组件
├── travel // 旅行相关组件
├── animal // 动物相关组件
├── order // 订单相关组件
├── promotion // 推广相关组件
│ │ └── dashboard // 仪表板组件
│ │ ├── composables // 组合式函数 (Vue 3 Composition API)
│ ├── directives // 自定义指令
│ │ ├── layouts // 页面布局
├── default.vue // 默认布局
├── auth.vue // 认证布局
└── empty.vue // 空白布局
│ │ ├── locales // 国际化资源
├── zh-CN.json // 中文语言包
└── en-US.json // 英文语言包
├── pages // 页面视图 (Vue 3 + TypeScript)
├── dashboard // 仪表板页面
├── user // 用户管理页面
├── merchant // 商家管理页面
├── travel // 旅行管理页面
│ │ │ ├── animal // 动物管理页面
│ │ │ ├── order // 订单管理页面
│ │ │ ├── promotion // 推广管理页面
│ │ │ ├── system // 系统管理页面
│ │ │ ├── login.vue // 登录页面
│ │ │ └── register.vue // 注册页面
│ │ ├── plugins // 插件
│ │ ├── router // 路由配置 (Vue Router 4 + TypeScript)
│ │ │ ├── modules // 模块路由
│ │ │ │ ├── user.ts // 用户路由
│ │ │ │ ├── merchant.ts // 商家路由
│ │ │ │ ├── travel.ts // 旅行路由
│ │ │ │ ├── animal.ts // 动物路由
│ │ │ │ ├── order.ts // 订单路由
│ │ │ │ ├── promotion.ts // 推广路由
│ │ │ │ └── system.ts // 系统路由
│ │ │ └── index.ts // 路由入口
│ │ ├── stores // 状态管理 (Pinia 2 + TypeScript)
│ │ │ ├── modules // 模块状态
│ │ │ │ ├── user.ts // 用户状态
│ │ │ │ ├── merchant.ts // 商家状态
│ │ │ │ ├── travel.ts // 旅行状态
│ │ │ │ ├── animal.ts // 动物状态
│ │ │ │ ├── order.ts // 订单状态
│ │ │ │ ├── promotion.ts // 推广状态
│ │ │ │ └── system.ts // 系统状态
│ │ │ └── index.ts // 状态管理入口
│ │ ├── styles // 样式文件
│ │ ├── types // TypeScript类型定义
│ │ ├── utils // 工具函数 (TypeScript)
│ │ │ ├── request.ts // 请求封装 (Axios + TypeScript)
│ │ │ ├── auth.ts // 认证工具
│ │ │ ├── storage.ts // 存储工具
│ │ │ ├── format.ts // 格式化工具
│ │ │ └── validate.ts // 验证工具
│ │ └── App.vue // 根组件 (Vue 3 + TypeScript)
│ │ └── main.ts // 入口文件 (Vue 3 + TypeScript + Pinia + Ant Design Vue)
│ ├── tests // 测试目录 (Vitest + Vue Test Utils)
│ ├── .env // 环境配置
│ ├── .env.development // 开发环境配置
│ ├── .env.production // 生产环境配置
│ ├── index.html // HTML模板
│ ├── tsconfig.json // TypeScript配置 (严格模式)
│ ├── vite.config.ts // 构建配置 (Vite 4 + TypeScript)
│ └── package.json // 依赖配置 (Vue 3 + TypeScript + Ant Design Vue + Pinia)
├── website // 官网系统 (HTML5 + Bootstrap)
│ ├── index.html // 首页
│ ├── about.html // 关于我们
│ ├── contact.html // 联系我们
│ ├── merchant // 商家合作页面
│ │ ├── index.html // 商家合作首页
│ │ ├── policy.html // 合作政策
│ │ └── apply.html // 入驻申请
│ ├── case.html // 案例展示
│ ├── css // 样式文件
│ │ ├── bootstrap.min.css // Bootstrap样式
│ │ └── custom.css // 自定义样式
│ ├── js // JavaScript文件
│ │ ├── bootstrap.min.js // Bootstrap脚本
│ │ └── custom.js // 自定义脚本
│ ├── images // 图片资源
│ └── vendor // 第三方库
├── backend // 后端接口服务 (Node.js + Express)
│ ├── src
│ │ ├── controllers // 控制器层
│ │ │ ├── user // 用户控制器
│ │ │ ├── merchant // 商家控制器
│ │ │ ├── travel // 旅行控制器
│ │ │ ├── animal // 动物控制器
│ │ │ ├── social // 社交控制器
│ │ │ ├── flower // 鲜花控制器
│ │ │ ├── promotion // 推广控制器
│ │ │ └── auth // 认证控制器
│ │ ├── services // 业务逻辑层
│ │ │ ├── user // 用户服务
│ │ │ ├── merchant // 商家服务
│ │ │ ├── travel // 旅行服务
│ │ │ ├── animal // 动物服务
│ │ │ ├── social // 社交服务
│ │ │ ├── flower // 鲜花服务
│ │ │ ├── promotion // 推广服务
│ │ │ └── auth // 认证服务
│ │ ├── models // 数据模型层
│ │ │ ├── user.js // 用户模型
│ │ │ ├── merchant.js // 商家模型
│ │ │ ├── travelPlan.js // 旅行计划模型
│ │ │ ├── animal.js // 动物模型
│ │ │ ├── claim.js // 认领模型
│ │ │ ├── message.js // 消息模型
│ │ │ ├── activity.js // 活动模型
│ │ │ ├── product.js // 商品模型
│ │ │ ├── order.js // 订单模型
│ │ │ ├── review.js // 评价模型
│ │ │ └── reward.js // 奖励模型
│ │ ├── routes // 路由定义
│ │ │ ├── api // API路由
│ │ │ │ ├── v1 // v1版本API
│ │ │ │ │ ├── user.js // 用户相关API
│ │ │ │ │ ├── merchant.js // 商家相关API
│ │ │ │ │ ├── travel.js // 旅行相关API
│ │ │ │ │ ├── animal.js // 动物相关API
│ │ │ │ │ ├── social.js // 社交相关API
│ │ │ │ │ ├── flower.js // 鲜花相关API
│ │ │ │ │ └── promotion.js // 推广相关API
│ │ │ │ └── index.js // API路由入口
│ │ │ └── web // Web路由(管理后台)
│ │ ├── middleware // 中间件
│ │ │ ├── auth // 认证中间件
│ │ │ ├── validation // 验证中间件
│ │ │ ├── rateLimit // 限流中间件
│ │ │ └── error // 错误处理中间件
│ │ ├── utils // 工具函数
│ │ │ ├── database // 数据库工具
│ │ │ ├── logger // 日志工具
│ │ │ ├── helpers // 辅助函数
│ │ │ └── constants // 常量定义
│ │ ├── config // 配置文件
│ │ │ ├── database.js // 数据库配置
│ │ │ ├── redis.js // Redis配置
│ │ │ ├── rabbitmq.js // RabbitMQ配置
│ │ │ └── app.js // 应用配置
│ │ └── app.js // 应用入口
│ ├── tests // 测试目录
│ │ ├── unit // 单元测试
│ │ └── integration // 集成测试
│ ├── docs // 文档目录
│ └── package.json // 依赖配置
└── docs // 项目文档
├── requirements.md // 需求文档
├── architecture.md // 架构文档
├── detailed_design.md // 详细设计文档
└── development_plan.md // 开发计划文档
```mermaid
erDiagram
USERS ||--o{ TRAVEL_PLANS : creates
USERS ||--o{ TRAVEL_INVITATIONS : sends
USERS ||--o{ TRAVEL_INVITATIONS : receives
USERS ||--o{ ANIMAL_CLAIMS : claims
USERS ||--o{ FLOWER_ORDERS : places
MERCHANTS ||--o{ ANIMALS : owns
MERCHANTS ||--o{ FLOWER_PRODUCTS : sells
ANIMALS ||--o{ ANIMAL_CLAIMS : claimed_by
FLOWER_PRODUCTS ||--o{ FLOWER_ORDERS : ordered
TRAVEL_PLANS ||--o{ TRAVEL_INVITATIONS : has
USERS {
int id PK
string openid
string nickname
string avatar
string gender
date birthday
string phone
string email
int travel_count
int animal_claim_count
datetime created_at
datetime updated_at
}
TRAVEL_PLANS {
int id PK
int user_id FK
string destination
date start_date
date end_date
decimal budget
string interests
string description
string visibility
string status
datetime created_at
datetime updated_at
}
TRAVEL_INVITATIONS {
int id PK
int travel_plan_id FK
int inviter_id FK
int invitee_id FK
string message
string status
datetime created_at
datetime updated_at
}
ANIMALS {
int id PK
int merchant_id FK
string name
string species
string breed
date birth_date
string personality
string farm_location
decimal price
json images
int claim_count
datetime created_at
datetime updated_at
}
ANIMAL_CLAIMS {
int id PK
int user_id FK
int animal_id FK
int duration
decimal total_amount
string status
date start_date
date end_date
datetime created_at
datetime updated_at
}
MERCHANTS {
int id PK
string business_name
string contact_person
string contact_phone
string business_license
string address
string status
datetime created_at
datetime updated_at
}
FLOWER_PRODUCTS {
int id PK
int merchant_id FK
string name
string description
decimal price
decimal original_price
json images
string category
int sales_count
decimal rating
string status
datetime created_at
datetime updated_at
}
FLOWER_ORDERS {
int id PK
int user_id FK
int product_id FK
string order_number
int quantity
decimal total_amount
json recipient_info
date delivery_date
string message
string status
datetime created_at
datetime updated_at
}
```
## 🌐 环境配置
## 2. 技术栈选型
### 2.1 后端技术栈
| 技术组件 | 版本 | 用途 | 选型理由 |
|---------|------|------|----------|
| Node.js | >=16.0.0 | 运行时环境 | 高性能、异步I/O、丰富的生态系统 |
| Express.js | ^4.18.2 | Web框架 | 轻量级、灵活、中间件生态丰富 |
| MySQL2 | ^3.14.3 | 数据库驱动 | 支持Promise、连接池、性能优化 |
| JWT | ^9.0.2 | 身份认证 | 无状态、安全、易于分布式部署 |
| bcryptjs | ^2.4.3 | 密码加密 | 安全性高、性能适中 |
| Redis | ^5.8.2 | 缓存/会话 | 内存存储、高性能、支持数据结构 |
| RabbitMQ | ^0.10.9 | 消息队列 | 异步处理、系统解耦(待实现) |
| Swagger | ^6.2.8 | API文档 | 自动化文档、接口测试 |
| Winston | ^3.11.0 | 日志系统 | 结构化日志、多传输方式 |
### 2.2 安全防护
| 安全组件 | 版本 | 防护类型 |
|----------|------|----------|
| Helmet | ^7.1.0 | 安全头部 |
| express-rate-limit | ^7.1.5 | 请求限流 |
| xss-clean | ^0.1.4 | XSS防护 |
| hpp | ^0.2.3 | 参数污染防护 |
| express-mongo-sanitize | ^2.2.0 | NoSQL注入防护 |
### 2.3 前端技术栈
| 项目 | 技术栈 | 状态 |
|------|--------|------|
| 微信小程序 | uni-app + Vue 2 | 开发中 |
| 后台管理系统 | Vue 3 + TypeScript + Ant Design Vue + Pinia | 开发中 |
| 官网系统 | HTML5 + Bootstrap + JavaScript | 待开发 |
### 2.6 选型理由与对比分析
#### 后端技术栈选型理由
**Node.js (TypeScript) + Express.js**
- **优势**
- 高性能Node.js基于事件驱动和非阻塞I/O模型适合高并发场景
- 生态丰富npm生态系统庞大可快速集成各种第三方库
- 全栈统一前后端均可使用JavaScript/TypeScript降低开发成本
- 轻量级Express.js是一个轻量级的Web框架灵活性高
- RBAC支持完善的权限管理中间件生态支持JWT和RBAC权限控制
- **劣势**
- CPU密集型任务处理能力较弱
- 回调地狱问题TypeScript可有效缓解
#### 前端技术栈选型理由
**uni-app**
- **优势**
- 一套代码多端运行可同时发布到iOS、Android、H5、以及各种小程序平台
- 开发生态基于Vue.js学习成本低社区活跃
- 性能优化:接近原生应用的性能体验
- **劣势**
- 平台限制:某些平台特定功能需要特殊处理
- 复杂度:多端兼容可能带来额外的复杂性
**后台管理系统 (Vue.js 3 + TypeScript + Ant Design Vue + Pinia)**
- **优势**
- **类型安全**: TypeScript提供编译时类型检查减少运行时错误
- **开发体验**: Vue 3 Composition API + `<script setup>`语法提供更好的代码组织和复用
- **企业级UI**: Ant Design Vue提供专业的企业级UI组件和设计规范
- **状态管理**: Pinia提供轻量级、类型安全的状态管理方案替代Vuex
- **构建性能**: Vite构建工具提供极快的开发服务器启动和热重载
- **代码质量**: ESLint + Prettier确保代码风格统一和质量
- **测试覆盖**: Vitest + Vue Test Utils支持完整的单元测试和组件测试
- **劣势**
- 学习曲线: TypeScript和新的Composition API需要一定的学习成本
- 包体积: 类型系统和完整工具链会增加最终的包体积
#### 官网技术栈选型理由
**HTML5 + Bootstrap**
- **优势**
- 简单易用:技术门槛低,开发效率高
- 兼容性好Bootstrap提供了良好的浏览器兼容性
- 响应式设计Bootstrap内置响应式布局适配各种设备
- 社区活跃Bootstrap拥有庞大的社区和丰富的组件
- **劣势**
- 定制性相对较弱:需要额外工作来实现独特的设计效果
- 文件体积Bootstrap框架本身会增加页面加载体积
#### 数据库选型理由
**MySQL 5.7**
- **优势**
- 成熟稳定:关系型数据库,事务支持完善
- 生态丰富:社区活跃,文档齐全
- 广泛兼容MySQL 5.7在生产环境中广泛使用,兼容性好
- **劣势**
- 水平扩展性相对较弱
- 复杂查询性能可能不如专门的分析型数据库
- 缺少MySQL 8.0的一些新特性
#### 缓存选型理由
**Redis Cluster**
- **优势**
- 高性能:内存数据库,读写速度极快
- 分布式支持Redis Cluster提供高可用和水平扩展能力
- 丰富数据结构:支持字符串、哈希、列表、集合等多种数据结构
- **劣势**
- 内存成本:数据存储在内存中,成本较高
- 持久化性能:持久化操作可能影响性能
#### 消息队列选型理由
**RabbitMQ**
- **优势**
- 成熟稳定:经过多年发展,稳定性好
- 协议支持:支持多种消息协议
- 灵活路由:支持多种消息路由模式
- **劣势**
- 吞吐量相比Kafka等大数据消息队列吞吐量较低
- Erlang语言维护和调优需要掌握Erlang语言
**WebSocket**
- **优势**
- 实时性:全双工通信,实时性好
- 节省资源:相比轮询,节省网络资源
- **劣势**
- 连接管理:需要处理连接断开重连等问题
- 浏览器兼容性:老旧浏览器支持不好
## 3. 部署视图
```
外网:
├── uni-app前端用户 --- HTTPS --> API网关
├── 官网用户 --- HTTPS --> Nginx反向代理 --> 官网系统
├── 后台管理系统用户 --- HTTPS --> API网关 (Vue 3 + TypeScript + Ant Design Vue + Pinia)
└── 第三方支付平台 <-- 支付回调 --- 后端服务
腾讯云服务器:
├── Nginx反向代理 --> 官网系统
│ ├── 静态资源服务
│ └── SSR渲染服务 (Nuxt.js)
├── API网关 --> 后端服务
│ ├── 用户端API服务 (小程序接口)
│ ├── 管理端API服务 (后台管理接口 - Vue 3 + TypeScript + Ant Design Vue + Pinia)
│ └── 公共服务 (认证、权限等)
├── 后端服务 --> MySQL数据库 (包含RBAC权限表)
├── 后端服务 --> Redis缓存 (会话和权限缓存)
├── 后端服务 --> RabbitMQ消息队列
└── 后端服务 --监控--> Prometheus监控 --> Grafana
|--> ELK Stack
### 开发环境 (Development)
```env
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=rootpassword
DB_DATABASE=jiebanke_dev
NODE_ENV=development
```
### 3.1 部署环境
- 云服务提供商:腾讯云
- 服务器配置4台4核8GB服务器组成Kubernetes集群
- 负载均衡腾讯云负载均衡CLB
- SSL证书腾讯云SSL证书服务
- 域名解析腾讯云DNS解析
- 对象存储腾讯云COS用于存储图片、视频等静态资源
- CDN加速腾讯云CDN用于加速静态资源访问
- 反向代理Nginx
- 静态资源服务器Nginx
### 测试环境 (Test)
```env
DB_HOST=192.168.0.240
DB_PORT=3306
DB_USER=root
DB_PASSWORD=aiotAiot123!
DB_DATABASE=jiebandata_test
NODE_ENV=test
```
### 3.2 部署流程
1. 代码提交到Git仓库触发CI/CD流水线
2. 通过Docker构建服务镜像并推送到镜像仓库
3. Kubernetes从镜像仓库拉取镜像并部署服务
4. 配置健康检查和自动扩缩容策略
5. 配置监控和日志收集系统
6. 配置域名解析和SSL证书
7. 配置Nginx反向代理和静态资源服务器
### 生产环境 (Production)
```env
DB_HOST=129.211.213.226
DB_PORT=9527
DB_USER=root
DB_PASSWORD=Aiot123
DB_DATABASE=jiebandata
NODE_ENV=production
```
### 3.3 备份与灾备
- 数据库每日自动备份到COS
- 关键服务配置文件版本化管理
- 多可用区部署实现高可用
## 🔌 API 设计
## 4. 风险分析与应对策略
### 用户模块接口
### 4.1 技术风险
#### 微信用户登录
- **Endpoint:** `POST /api/v1/auth/wechat-login`
- **Method:** POST
- **Description:** 微信用户登录获取Token
- **Request Body:**
```json
{
"code": "string, required",
"userInfo": {
"nickName": "string, required",
"avatarUrl": "string, required",
"gender": "number, optional",
"province": "string, optional",
"city": "string, optional"
}
}
```
- **Response:**
```json
{
"code": 200,
"message": "登录成功",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"openid": "wx1234567890",
"nickname": "旅行达人",
"avatar": "https://avatar.url",
"gender": "male",
"phone": "13800138000"
}
}
}
```
#### 系统性能瓶颈
- **风险描述**:随着用户量增长,系统可能面临性能瓶颈,特别是在高并发场景下。
- **应对策略**
- 使用Redis缓存热点数据减少数据库访问压力
- 对数据库进行读写分离和分库分表
- 使用CDN加速静态资源访问
- 实施自动扩缩容策略,根据负载动态调整服务实例数量
#### 获取用户信息
- **Endpoint:** `GET /api/v1/users/profile`
- **Method:** GET
- **Description:** 获取当前登录用户详细信息
- **Headers:** `Authorization: Bearer <token>`
- **Response:**
```json
{
"code": 200,
"message": "获取成功",
"data": {
"id": 1,
"openid": "wx1234567890",
"nickname": "旅行达人",
"avatar": "https://avatar.url",
"gender": "male",
"birthday": "1990-01-01",
"phone": "13800138000",
"email": "test@example.com",
"travelCount": 5,
"animalClaimCount": 2,
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
}
```
#### 数据安全风险
- **风险描述**: 系统涉及用户个人信息、支付信息等敏感数据,存在数据泄露风险。管理员后台权限控制不当可能导致数据泄露。
- **应对策略**:
- 对敏感数据进行加密存储AES/RSA算法
- 实施严格的访问控制和身份认证机制
- 采用RBAC权限模型严格控制管理员操作权限
- 定期进行安全审计和渗透测试
- 遵循GDPR等数据保护法规要求
- 管理员操作日志记录和审计
## 🚀 部署架构
### 4.2 业务风险
### 开发部署
```mermaid
graph LR
A[本地开发机] --> B[Docker Compose]
B --> C[MySQL容器]
B --> D[Node.js应用]
B --> E[Redis容器]
```
#### 用户增长压力
- **风险描述**:产品上线后可能面临用户快速增长的压力,对系统稳定性提出挑战。
- **应对策略**
- 提前进行压力测试,评估系统承载能力
- 设计可水平扩展的架构,支持快速扩容
- 制定限流和降级策略,保证核心功能稳定运行
### 生产部署
```mermaid
graph TB
subgraph "云服务器"
A[Nginx]
B[Node.js集群]
C[MySQL主从]
D[Redis哨兵]
end
A --> B
B --> C
B --> D
```
#### 商家服务质量风险
- **风险描述**: 商家用户提供的服务质量和用户体验直接影响平台声誉。管理员审核不严可能导致低质量商家入驻。
- **应对策略**:
- 建立商家资质审核机制
- 实施用户评价体系,公开服务评价
- 建立投诉处理机制,及时处理用户反馈
- 对低质量商家实施警告、限流或清退措施
- 管理员审核流程标准化和权限分级
## 📊 监控与日志
### 4.3 运维风险
- **应用监控**: PM2 + Keymetrics
- **日志管理**: Winston + ELK Stack
- **性能监控**: New Relic / Datadog
- **错误追踪**: Sentry
#### 系统监控不足
- **风险描述**:缺乏有效的监控可能导致问题发现不及时,影响用户体验。
- **应对策略**
- 建立全方位监控体系,包括基础设施、应用性能、业务指标等
- 设置合理的告警阈值和通知机制
- 定期审查和优化监控策略
## 🔒 安全架构
#### 故障恢复能力
- **风险描述**:系统故障可能导致服务中断,影响业务连续性。
- **应对策略**
- 制定详细的应急预案和故障恢复流程
- 定期进行故障演练,验证恢复能力
- 实施多可用区部署,提高容灾能力
- 建立数据库备份和恢复机制
### 认证授权
- JWT Token 认证
- RBAC (基于角色的访问控制)
- API 速率限制
### 数据安全
- HTTPS 加密传输
- 密码加盐哈希存储
- SQL 注入防护
- XSS 攻击防护
### 网络安全
- 防火墙规则
- IP 白名单
- DDoS 防护
## 📈 性能优化
### 数据库优化
- 索引优化
- 查询缓存
- 读写分离
### 应用优化
- 响应压缩
- 静态资源CDN
- 内存缓存
### 前端优化
- 代码分割
- 懒加载
- 图片优化
## 🛠️ 开发规范
### 代码规范
- ESLint + Prettier 统一代码风格
- Git Commit 消息规范
- 代码审查流程
### 分支策略
- Git Flow 工作流
- 功能分支开发
- 发布分支管理
### 测试策略
- 单元测试覆盖核心逻辑
- 集成测试API接口
- E2E测试用户流程
## 📝 文档体系
1. **ARCHITECTURE.md** - 系统架构文档 (当前文件)
2. **README.md** - 项目说明文档
3. **API_DOCS.md** - API接口文档
4. **DEPLOYMENT.md** - 部署指南
5. **DEVELOPMENT.md** - 开发指南
## 🎯 后续规划
### 短期目标
- [ ] 完善用户管理系统
- [ ] 实现订单业务流程
- [ ] 部署测试环境
### 中期目标
- [ ] 微服务架构改造
- [ ] 容器化部署
- [ ] 自动化测试覆盖
### 长期目标
- [ ] 大数据分析平台
- [ ] AI智能推荐
- [ ] 多语言国际化
---
*最后更新: 2024年* 📅

View File

@@ -1,183 +0,0 @@
const mysql = require('mysql2');
// 数据库配置
const configs = [
{
name: '测试环境',
host: '192.168.0.240',
port: 3306,
user: 'root',
password: 'aiot$Aiot123'
},
{
name: '生产环境',
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!'
}
];
// 创建数据库的SQL语句
const createDatabaseSQL = `
CREATE DATABASE IF NOT EXISTS jiebandata
CHARACTER SET utf8mb4
COLLATE utf极4_unicode_ci;
`;
// 创建用户表的SQL语句
const createUsersTableSQL = `
CREATE TABLE IF NOT EXISTS jiebandata.users (
id INT AUTO_INCREMENT PRIMARY KEY,
openid VARCHAR(64) UNIQUE NOT NULL,
nickname VARCHAR(50) NOT NULL,
avatar VARCHAR(255),
gender ENUM('male', 'female', 'other'),
birthday DATE,
phone VARCHAR(20) UNIQUE,
email VARCHAR(100) UNIQUE,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_openid (openid),
INDEX idx_phone (phone),
INDEX idx_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`;
// 创建商家表的SQL语句
const createMerchantsTableSQL = `
CREATE TABLE IF NOT EXISTS jiebandata.merchants (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
merchant_type ENUM('flower_shop', 'activity_organizer', 'farm_owner') NOT NULL,
business_name VARCHAR(100) NOT NULL,
business_license VARCHAR(255),
contact_person VARCHAR(50) NOT NULL,
contact_phone VARCHAR(20) NOT NULL,
address VARCHAR(255),
description TEXT,
status ENUM('pending', 'approved', 'rejected', 'suspended') NOT NULL DEFAULT 'pending',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_user_id (user_id),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`;
// 创建旅行计划表的SQL语句
const createTravelPlansTableSQL = `
CREATE TABLE IF NOT EXISTS jiebandata.travel_plans (
id极INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
destination VARCHAR(100) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
budget DECIMAL(10,2) NOT NULL,
interests TEXT,
visibility ENUM('public', 'friends', 'private') NOT NULL DEFAULT 'public',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_user_id (user_id),
INDEX idx_destination (destination),
INDEX idx_dates (start_date, end_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`;
function executeSQL(connection, sql, description) {
return new Promise((resolve, reject) => {
console.log(`🛠️ ${description}...`);
connection.query(sql, (err, results) => {
if (err) {
console.error(`${description}失败:`, err.message);
reject(err);
} else {
console.log(`${description}成功`);
resolve(results);
}
});
});
}
async function initializeDatabase(config) {
console.log(`\n🚀 开始初始化 ${config.name} 数据库...`);
console.log('='.repeat(60));
const connection = mysql.createConnection({
host: config.host,
port: config.port,
user: config.user,
password: config.password,
multipleStatements: true
});
try {
// 连接数据库
await new Promise((resolve, reject) => {
connection.connect((err) => {
if (err) reject(err);
else resolve();
});
});
// 创建数据库
await executeSQL(connection, createDatabaseSQL, '创建数据库 jiebandata');
// 使用新创建的数据库
await executeSQL(connection, 'USE jiebandata', '切换到 jiebandata 数据库');
// 创建用户表
await executeSQL(connection, createUsersTableSQL, '创建用户表');
// 创建商家表
await executeSQL(connection, createMerchantsTableSQL, '创建商家表');
// 创建旅行计划表
await executeSQL(connection, createTravelPlansTableSQL, '创建旅行计划表');
console.log('✅ 数据库初始化完成!');
return { success: true, message: '数据库初始化成功' };
} catch (error) {
console.error('❌ 数据库初始化失败:', error.message);
return { success: false, error: error.message };
} finally {
// 关闭极接
connection.end();
console.log('✅ 数据库连接已关闭');
}
}
async function main() {
console.log('🎯 结伴客系统数据库初始化工具');
console.log('='.repeat(60));
const results = [];
for (const config of configs) {
const result = await initializeDatabase(config);
results.push({
environment: config.name,
success: result.success,
message: result.message || result.error
});
console.log('\n' + '='.repeat(60));
}
// 输出汇总结果
console.log('📋 初始化结果汇总:');
results.forEach(result => {
console.log(`${result.environment}: ${result.success ? '✅ 成功' : '❌ 失败'} - ${result.message}`);
});
if (results.some(r => r.success)) {
console.log('\n🎉 数据库初始化完成!现在可以运行测试验证数据库结构。');
} else {
console.log('\n⚠ 所有环境初始化失败,请检查网络连接和数据库权限');
}
}
// 运行初始化
main().catch(console.error);

View File

@@ -1,188 +0,0 @@
const mysql = require('mysql2');
// 数据库配置
const configs = [
{
name: '测试环境',
host: '192.168.0.240',
port: 3306,
user: '极',
password: 'aiot$Aiot123'
},
{
name: '生产环境',
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!'
}
];
// 创建数据库的SQL语句
const createDatabaseSQL = `
CREATE DATABASE IF NOT EXISTS jiebandata
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
`;
// 创建用户表的SQL语句
const createUsersTableSQL = `
CREATE TABLE IF NOT EXISTS jiebandata.users (
id INT AUTO_INCREMENT PRIMARY KEY,
openid VARCHAR(64) UNIQUE NOT NULL,
nickname VARCHAR(50) NOT NULL,
avatar VARCHAR(255),
gender ENUM('male', 'female', 'other'),
birthday DATE,
phone VARCHAR(20) UNIQUE,
email VARCHAR(100) UNIQUE,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_openid (openid),
INDEX idx_phone (phone),
INDEX idx_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf极4 COLLATE=utf8mb4_unicode_ci;
`;
// 创建商家表的SQL语句
const createMerchantsTableSQL = `
CREATE TABLE IF NOT EXISTS jiebandata.merchants (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
merchant_type ENUM('flower_shop', 'activity_organizer', 'farm_owner') NOT NULL,
business_name VARCHAR(100) NOT NULL,
business_license VARCHAR(255),
contact_person VARCHAR极50) NOT NULL,
contact_phone VARCHAR(20) NOT NULL,
address VARCHAR(255),
description TEXT,
status ENUM('pending', 'approved', 'rejected', 'suspended') NOT NULL DEFAULT 'pending',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_user_id (user_id),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`;
// 创建旅行计划表的SQL语句
const createTravelPlansTableSQL = `
CREATE TABLE IF NOT EXISTS jiebandata.travel_plans (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
destination VARCHAR(100) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
budget DECIMAL(10,2) NOT NULL,
interests TEXT,
visibility ENUM('public', 'friends', 'private') NOT NULL DEFAULT 'public',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_user_id (user_id),
INDEX idx_destination (destination),
INDEX idx_dates (start_date, end_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`;
// 所有表创建语句
const tableCreationSQLs = [
createUsersTableSQL,
createMerchantsTableSQL,
createTravelPlansTableSQL
];
function executeSQL(connection, sql, description) {
return new Promise((resolve, reject) => {
console.log(`🛠️ ${description}...`);
connection.query(sql, (err, results) => {
if (err) {
console.error(`${description}失败:`, err.message);
reject(err);
} else {
console.log(`${description}成功`);
resolve(results);
}
});
});
}
async function initializeDatabase(config) {
console.log(`\n🚀 开始初始化 ${config.name} 数据库...`);
console.log('='.repeat(60));
const connection = mysql.createConnection({
host: config.host,
port: config.port,
user: config.user,
password: config.password,
multipleStatements: true
});
try {
// 连接数据库
await new Promise((resolve, reject) => {
connection.connect((err) => {
if (err) reject(err);
else resolve();
});
});
// 创建数据库
await executeSQL(connection, createDatabaseSQL, '创建数据库 jiebandata');
// 使用新创建的数据库
await executeSQL(connection, 'USE jiebandata', '切换到 jiebandata 数据库');
// 创建所有表
for (let i = 0; i < tableCreationSQLs.length; i++) {
await executeSQL(connection, tableCreationSQLs[i], `创建表 ${i + 1}/${tableCreationSQLs.length}`);
}
console.log('✅ 数据库初始化完成!');
return { success: true, message: '数据库初始化成功' };
} catch (error) {
console.error('❌ 数据库初始化失败:', error.message);
return { success: false, error: error.message };
} finally {
// 关闭连接
connection.end();
console.log('✅ 数据库连接已关闭');
}
}
async function main() {
console.log('🎯 结伴客系统数据库初始化工具');
console.log('='.repeat(60));
const results = [];
for (const config of configs) {
const result = await initializeDatabase(config);
results.push({
environment: config.name,
success: result.success,
message: result.message || result.error
});
console.log('\n' + '='.repeat(60));
}
// 输出汇总结果
console.log('📋 初始化结果汇总:');
results.forEach(result => {
console.log(`${result.environment}: ${result.success ? '✅ 成功' : '❌ 失败'} - ${result.message}`);
});
// 检查是否所有环境都成功
const allSuccess = results.every(result => result.success);
if (allSuccess) {
console.log('\n🎉 所有环境数据库初始化成功!');
} else {
console.log('\n⚠ 部分环境初始化失败,请检查网络连接和数据库权限');
}
}
// 运行初始化
main().catch(console.error);

View File

@@ -1,221 +0,0 @@
const mysql = require('mysql2');
// 数据库配置
const configs = [
{
name: '测试环境',
host: '192.168.0.240',
port: 3306,
user: 'root',
password: 'aiot$Aiot123'
},
{
name: '生产环境',
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!'
}
];
// 创建数据库的SQL语句
const createDatabaseSQL = `
CREATE DATABASE IF NOT EXISTS jiebandata
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
`;
// 创建用户表的SQL语句
const createUsersTableSQL = `
CREATE TABLE IF NOT EXISTS jiebandata.users (
id INT AUTO_INCREMENT PRIMARY KEY,
openid VARCHAR(64) UNIQUE NOT NULL,
nickname VARCHAR(50) NOT NULL,
avatar VARCHAR(255),
gender ENUM('male', 'female', 'other'),
birthday DATE,
phone VARCHAR(20) UNIQUE,
email VARCHAR(100) UNIQUE,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_openid (openid),
INDEX idx_phone (phone),
INDEX idx_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`;
// 创建商家表的SQL语句
const createMerchantsTableSQL = `
CREATE TABLE IF NOT EXISTS jiebandata.merchants (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
merchant_type ENUM('flower_shop', 'activity_organizer', 'farm_owner') NOT NULL,
business_name VARCHAR(100) NOT NULL,
business_license VARCHAR(255),
contact_person VARCHAR(50) NOT NULL,
contact_phone VARCHAR(20) NOT NULL,
address VARCHAR(255),
description TEXT,
status ENUM('pending', 'approved', 'rejected', 'suspended') NOT NULL DEFAULT 'pending',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_user_id (user_id),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`;
// 创建旅行计划表的SQL语句
const createTravelPlansTableSQL = `
CREATE TABLE IF NOT EXISTS jiebandata.travel_plans (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
destination VARCHAR(100) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
budget DECIMAL(10,2) NOT NULL,
interests TEXT,
visibility ENUM('public', 'friends', 'private') NOT NULL DEFAULT 'public',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_user_id (user_id),
INDEX idx_destination (destination),
INDEX idx_dates (start_date, end_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`;
// 创建管理员表的SQL语句
const createAdminsTableSQL = `
CREATE TABLE IF NOT EXISTS jiebandata.admins (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
email VARCHAR(100),
nickname VARCHAR(50),
avatar VARCHAR(255),
role VARCHAR(20) NOT NULL DEFAULT 'admin',
status TINYINT(1) NOT NULL DEFAULT 1,
last_login DATETIME,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_username (username),
INDEX idx_role (role),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`;
// 所有表创建语句
const tableCreationSQLs = [
createUsersTableSQL,
createMerchantsTableSQL,
createTravelPlansTableSQL,
createAdminsTableSQL
];
function executeSQL(connection, sql, description) {
return new Promise((resolve, reject) => {
console.log(`🛠️ ${description}...`);
connection.query(sql, (err, results) => {
if (err) {
console.error(`${description}失败:`, err.message);
reject(err);
} else {
console.log(`${description}成功`);
resolve(results);
}
});
});
}
async function initializeDatabase(config) {
console.log(`\n🚀 开始初始化 ${config.name} 数据库...`);
console.log('='.repeat(60));
const connection = mysql.createConnection({
host: config.host,
port: config.port,
user: config.user,
password: config.password,
multipleStatements: true // 允许执行多条SQL语句
});
try {
// 连接数据库
await new Promise((resolve, reject) => {
connection.connect((err) => {
if (err) reject(err);
else resolve();
});
});
// 创建数据库
await executeSQL(connection, createDatabaseSQL, '创建数据库 jiebandata');
// 使用新创建的数据库
await executeSQL(connection, 'USE jiebandata', '切换到 jiebandata 数据库');
// 创建所有表
for (let i = 0; i < tableCreationSQLs.length; i++) {
await executeSQL(connection, tableCreationSQLs[i], `创建表 ${i + 1}/${tableCreationSQLs.length}`);
}
// 插入示例数据
console.log('📝 插入示例数据...');
// 插入示例用户
await executeSQL(connection, `
INSERT IGNORE INTO users (openid, nickname, avatar, gender, phone, email) VALUES
('test_openid_1', '测试用户1', 'https://example.com/avatar1.jpg', 'male', '13800138001', 'user1@example.com'),
('test_openid_2', '测试用户2', 'https://example.com/avatar2.jpg', 'female', '13800138002', 'user2@example.com')
`, '插入示例用户数据');
// 插入示例管理员
await executeSQL(connection, `
INSERT IGNORE INTO admins (username, password, email, nickname, role) VALUES
('admin', '$2a$10$rZ.r/.H0he7d.9T3.1E3qOeP.UZvF0.U6BQ35ENcQbLQzvEuh3dOq', 'admin@example.com', '超级管理员', 'admin')
`, '插入示例管理员数据');
// 验证数据插入
const usersResult = await new Promise((resolve, reject) => {
connection.query('SELECT COUNT(*) as count FROM users', (err, results) => {
if (err) reject(err);
else resolve(results);
});
});
console.log(`✅ 数据库初始化完成!用户表中有 ${usersResult[0].count} 条记录`);
return { success: true, message: '数据库初始化成功' };
} catch (error) {
console.error('❌ 数据库初始化失败:', error.message);
return { success: false, error: error.message };
} finally {
// 关闭连接
connection.end();
console.log('✅ 数据库连接已关闭');
}
}
async function main() {
console.log('🎯 结伴客系统数据库初始化工具');
console.log('='.repeat(60));
// 直接使用生产环境配置
const config = configs[1]; // 生产环境配置
const result = await initializeDatabase(config);
if (result.success) {
console.log('\n🎉 数据库初始化成功!');
process.exit(0);
}
console.log('\n' + '='.repeat(60));
console.log('❌ 数据库初始化失败,请检查网络连接和数据库配置');
process.exit(1);
}
// 运行初始化
main().catch(console.error);
module.exports = { initializeDatabase };

19712
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,43 @@
{
"name": "jiebanke",
"version": "1.0.0",
"description": "杰邦科项目 - 综合性管理系统",
"private": true,
"workspaces": [
"backend",
"admin-system",
"website",
"mini-program",
"scripts"
],
"scripts": {
"dev": "concurrently \"npm run dev:backend\" \"npm run dev:admin\" \"npm run dev:website\"",
"dev:backend": "cd backend && npm run dev",
"dev:admin": "cd admin-system && npm run dev",
"dev:website": "cd website && npm run dev",
"build": "concurrently \"npm run build:backend\" \"npm run build:admin\" \"npm run build:website\"",
"build:backend": "cd backend && npm run build",
"build:admin": "cd admin-system && npm run build",
"build:website": "cd website && npm run build",
"test": "concurrently \"npm run test:backend\" \"npm run test:admin\" \"npm run test:website\"",
"test:backend": "cd backend && npm run test",
"test:admin": "cd admin-system && npm run test",
"test:website": "cd website && npm run test",
"install:all": "npm install && cd backend && npm install && cd ../admin-system && npm install && cd ../website && npm install && cd ../mini-program && npm install",
"clean": "rimraf backend/node_modules admin-system/node_modules website/node_modules mini-program/node_modules"
},
"devDependencies": {
"concurrently": "^8.2.2",
"rimraf": "^5.0.5",
"less": "^4.4.1"
},
"dependencies": {
"axios": "^1.11.0",
"bcryptjs": "^3.0.2",
"mysql2": "^3.14.3"
},
"devDependencies": {
"less": "^4.4.1"
"engines": {
"node": ">=16.0.0",
"npm": ">=8.0.0"
}
}

View File

@@ -1,33 +0,0 @@
const bcrypt = require('bcryptjs');
// 重置管理员密码为 'admin123'
async function resetAdminPassword() {
try {
const plainPassword = 'admin123';
const hashedPassword = await bcrypt.hash(plainPassword, 10);
console.log('🔐 重置管理员密码');
console.log('='.repeat(50));
console.log('原密码:', plainPassword);
console.log('加密后:', hashedPassword);
console.log('');
// 生成SQL更新语句
const updateSQL = `UPDATE jiebandata.admins SET password = '${hashedPassword}' WHERE username = 'admin';`;
console.log('📋 SQL更新语句:');
console.log(updateSQL);
console.log('');
console.log('💡 使用方法:');
console.log('1. 使用MySQL客户端执行以上SQL语句');
console.log('2. 或者使用MCP工具执行SQL更新');
console.log('3. 然后使用用户名: admin, 密码: admin123 登录');
} catch (error) {
console.error('❌ 生成密码失败:', error.message);
}
}
// 运行重置
resetAdminPassword();

View File

@@ -1,72 +0,0 @@
const mysql = require('mysql2');
// 测试环境配置
const testConfig = {
host: '192.168.0.240',
port: 3306,
user: 'root',
password: 'aiot$Aiot123'
};
// 生产环境配置
const prodConfig = {
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!'
};
function testConnection(config, environment) {
return new Promise((resolve) => {
console.log(`\n🔗 测试 ${environment} 连接...`);
const connection = mysql.createConnection(config);
connection.connect((err) => {
if (err) {
console.error('❌ 连接失败:', err.message);
connection.end();
resolve({ success: false, error: err.message });
return;
}
console.log('✅ 连接成功');
// 测试简单查询
connection.query('SELECT VERSION() as version', (err, results) => {
if (err) {
console.error('❌ 查询失败:', err.message);
} else {
console.log('📋 MySQL版本:', results[0].version);
}
connection.end();
resolve({ success: true });
});
});
});
}
async function main() {
console.log('🚀 MySQL连接测试');
console.log('='.repeat(40));
// 测试测试环境
const testResult = await testConnection(testConfig, '测试环境');
console.log('\n' + '='.repeat(40));
// 测试生产环境
const prodResult = await testConnection(prodConfig, '生产环境');
console.log('\n' + '='.repeat(40));
console.log('📋 测试结果:');
console.log('测试环境:', testResult.success ? '✅ 成功' : '❌ 失败');
console.log('生产环境:', prodResult.success ? '✅ 成功' : '❌ 失败');
if (testResult.success && prodResult.success) {
console.log('\n🎉 两个环境连接都成功!');
}
}
main().catch(console.error);

View File

@@ -1,105 +0,0 @@
const axios = require('axios');
// API基础配置
const BASE_URL = 'http://localhost:3100';
// 测试管理员登录
async function testAdminLogin() {
try {
console.log('🔐 测试管理员登录接口...');
const response = await axios.post(`${BASE_URL}/api/v1/admin/login`, {
username: 'admin',
password: 'admin123' // 默认密码
});
console.log('✅ 登录成功:', response.data);
return response.data.data.token;
} catch (error) {
console.error('❌ 登录失败:', error.response?.data || error.message);
return null;
}
}
// 测试获取管理员信息
async function testGetAdminProfile(token) {
if (!token) return;
try {
console.log('\n👤 测试获取管理员信息接口...');
const response = await axios.get(`${BASE_URL}/api/v1/admin/profile`, {
headers: { Authorization: `Bearer ${token}` }
});
console.log('✅ 获取管理员信息成功:', response.data);
} catch (error) {
console.error('❌ 获取管理员信息失败:', error.response?.data || error.message);
}
}
// 测试获取用户列表
async function testGetUsers(token) {
if (!token) return;
try {
console.log('\n👥 测试获取用户列表接口...');
const response = await axios.get(`${BASE_URL}/api/v1/users`, {
headers: { Authorization: `Bearer ${token}` },
params: { page: 1, limit: 10 }
});
console.log('✅ 获取用户列表成功:');
console.log(' 总用户数:', response.data.data.total);
console.log(' 当前页用户数:', response.data.data.items.length);
} catch (error) {
console.error('❌ 获取用户列表失败:', error.response?.data || error.message);
}
}
// 测试获取系统信息
async function testGetSystemInfo(token) {
if (!token) return;
try {
console.log('\n💻 测试获取系统信息接口...');
const response = await axios.get(`${BASE_URL}/api/v1/admin/system/info`, {
headers: { Authorization: `Bearer ${token}` }
});
console.log('✅ 获取系统信息成功:');
console.log(' 系统版本:', response.data.data.version);
console.log(' 运行环境:', response.data.data.environment);
} catch (error) {
console.error('❌ 获取系统信息失败:', error.response?.data || error.message);
}
}
// 主测试函数
async function main() {
console.log('🎯 结伴客系统管理员API测试工具');
console.log('='.repeat(60));
// 检查后端服务是否运行
try {
await axios.get(`${BASE_URL}/health`);
console.log('✅ 后端服务正常运行');
} catch (error) {
console.log('⚠️ 后端服务未启动,请先启动后端服务');
console.log(' 运行命令: cd backend && npm start');
return;
}
const token = await testAdminLogin();
await testGetAdminProfile(token);
await testGetUsers(token);
await testGetSystemInfo(token);
console.log('\n' + '='.repeat(60));
console.log('🎉 API测试完成');
}
// 运行测试
main().catch(console.error);

View File

@@ -1,86 +0,0 @@
const mysql = require('mysql2');
// 生产环境数据库配置(先不指定数据库)
const prodConfig = {
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!'
};
function testConnection(config, environment) {
return new Promise((resolve) => {
console.log(`\n🔗 正在测试 ${environment} 数据库连接...`);
console.log(`主机: ${config.host}`);
console.log(`端口: ${config.port}`);
// 创建连接
const connection = mysql.createConnection(config);
connection.connect((err) => {
if (err) {
console.error('❌ 数据库连接失败:', err.message);
connection.end();
return resolve({ success: false, error: err.message });
}
console.log('✅ 数据库连接成功!');
// 测试查询
console.log('📊 执行测试查询...');
connection.query('SELECT 1 as test_result', (err, rows) => {
if (err) {
console.error('❌ 测试查询失败:', err.message);
connection.end();
return resolve({ success: false, error: err.message });
}
console.log('✅ 测试查询成功:', rows[0]);
// 获取数据库版本
connection.query('SELECT VERSION() as version', (err, versionRows) => {
if (err) {
console.error('❌ 获取版本失败:', err.message);
} else {
console.log('📋 数据库版本:', versionRows[0].version);
}
// 列出所有数据库
connection.query('SHOW DATABASES', (err, dbRows) => {
if (err) {
console.error('❌ 获取数据库列表失败:', err.message);
} else {
console.log('📚 可用数据库:');
dbRows.forEach(row => {
console.log(`${row.Database}`);
});
}
connection.end();
resolve({ success: true });
});
});
});
});
});
}
async function main() {
console.log('🚀 开始测试结伴客系统数据库连接');
console.log('============================================================');
// 测试生产环境数据库
const prodResult = await testConnection(prodConfig, '生产环境');
console.log('\n============================================================');
console.log('🏁 数据库连接测试完成');
if (prodResult.success) {
console.log('🎉 所有测试通过!');
} else {
console.log('💥 部分测试失败');
}
}
// 执行测试
main().catch(console.error);

View File

@@ -1,77 +0,0 @@
const axios = require('axios');
// 创建axios实例
const api = axios.create({
baseURL: 'http://localhost:3100/api/v1',
timeout: 10000
});
async function testAdminAPI() {
console.log('🚀 开始测试管理员API接口...\n');
let token = null;
try {
// 1. 测试管理员登录(使用新创建的测试账户)
console.log('1. 测试管理员登录...');
const loginResponse = await api.post('/admin/login', {
username: 'testadmin',
password: 'admin123'
});
console.log('✅ 登录成功');
console.log('登录响应:', loginResponse.data);
// 保存token用于后续测试
token = loginResponse.data.data.token;
api.defaults.headers.common['Authorization'] = `Bearer ${token}`;
} catch (error) {
if (error.response) {
console.log('❌ 登录失败:', error.response.data);
} else {
console.error('❌ 请求失败:', error.message);
}
return;
}
try {
// 2. 测试获取当前管理员信息
console.log('\n2. 测试获取当前管理员信息...');
const profileResponse = await api.get('/admin/profile');
console.log('✅ 获取管理员信息成功');
console.log('管理员信息:', profileResponse.data);
} catch (error) {
if (error.response) {
console.log('❌ 获取管理员信息失败:', error.response.data);
} else {
console.error('❌ 请求失败:', error.message);
}
}
try {
// 3. 测试获取管理员列表
console.log('\n3. 测试获取管理员列表...');
const listResponse = await api.get('/admin');
console.log('✅ 获取管理员列表成功');
console.log('管理员列表:');
listResponse.data.data.admins.forEach((admin, index) => {
console.log(`${index + 1}. ID: ${admin.id}, 用户名: ${admin.username}, 角色: ${admin.role}, 状态: ${admin.status}`);
});
} catch (error) {
if (error.response) {
console.log('❌ 获取管理员列表失败:', error.response.data);
} else {
console.error('❌ 请求失败:', error.message);
}
}
console.log('\n✅ 管理员API测试完成');
}
// 运行测试
testAdminAPI().catch(console.error);

View File

@@ -1,60 +0,0 @@
const mysql = require('mysql2/promise');
// 数据库配置
const dbConfig = {
host: '129.211.213.226',
port: 9527,
user: 'root',
password: 'aiotAiot123!',
database: 'jiebandata',
connectionLimit: 10,
charset: 'utf8mb4',
timezone: '+08:00',
waitForConnections: true,
queueLimit: 0,
// 添加连接超时配置
connectTimeout: 10000, // 10秒连接超时
acquireTimeout: 10000, // 10秒获取连接超时
timeout: 10000 // 10秒查询超时
};
async function testConnection() {
let connection;
try {
console.log('尝试连接数据库...');
connection = await mysql.createConnection(dbConfig);
console.log('✅ 数据库连接成功');
// 测试查询
const [rows] = await connection.execute('SELECT 1 as test');
console.log('✅ 数据库查询测试成功:', rows);
// 查询管理员表
const [admins] = await connection.execute('SELECT id, username, role FROM admins LIMIT 3');
console.log('✅ 管理员表查询成功:');
console.table(admins);
await connection.end();
console.log('✅ 数据库连接已关闭');
} catch (error) {
console.error('❌ 数据库连接失败:', error.message);
if (error.code) {
console.error('错误代码:', error.code);
}
if (error.errno) {
console.error('错误编号:', error.errno);
}
if (error.syscall) {
console.error('系统调用:', error.syscall);
}
if (connection) {
try {
await connection.end();
} catch (closeError) {
console.error('关闭连接时出错:', closeError.message);
}
}
}
}
testConnection();