310 lines
8.7 KiB
Markdown
310 lines
8.7 KiB
Markdown
# 公司财务系统 - 客户管理API
|
||||
|
|
|
|||
|
|
## 项目概述
|
|||
|
|
客户管理完整CRUD API,基于Express.js和PostgreSQL。实现了完整的客户管理功能,包括分页、搜索、数据验证和错误处理。
|
|||
|
|
|
|||
|
|
## 技术栈
|
|||
|
|
- Node.js + Express.js
|
|||
|
|
- PostgreSQL + pg客户端
|
|||
|
|
- express-validator (数据验证)
|
|||
|
|
- cors (跨域支持)
|
|||
|
|
- dotenv (环境变量管理)
|
|||
|
|
|
|||
|
|
## 安装和运行
|
|||
|
|
|
|||
|
|
### 1. 安装依赖
|
|||
|
|
```bash
|
|||
|
|
cd /opt/company-finance-system/backend
|
|||
|
|
npm install
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 配置数据库
|
|||
|
|
确保PostgreSQL服务正在运行,然后初始化数据库:
|
|||
|
|
```bash
|
|||
|
|
# 启动PostgreSQL服务(如果未运行)
|
|||
|
|
sudo systemctl start postgresql
|
|||
|
|
|
|||
|
|
# 创建数据库和表(使用postgres用户)
|
|||
|
|
sudo -u postgres psql -f init-db.sql
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或者手动执行:
|
|||
|
|
```bash
|
|||
|
|
# 登录PostgreSQL
|
|||
|
|
sudo -u postgres psql
|
|||
|
|
|
|||
|
|
# 在psql中执行
|
|||
|
|
\i init-db.sql
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 环境变量配置
|
|||
|
|
已提供 `.env` 文件,包含默认配置:
|
|||
|
|
```env
|
|||
|
|
DB_HOST=localhost
|
|||
|
|
DB_PORT=5432
|
|||
|
|
DB_NAME=company_finance_db
|
|||
|
|
DB_USER=postgres
|
|||
|
|
DB_PASSWORD=postgres
|
|||
|
|
PORT=3000
|
|||
|
|
NODE_ENV=development
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 启动服务器
|
|||
|
|
```bash
|
|||
|
|
# 开发模式(使用nodemon,自动重启)
|
|||
|
|
npm run dev
|
|||
|
|
|
|||
|
|
# 生产模式
|
|||
|
|
npm start
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
服务器将在 http://localhost:3000 启动。
|
|||
|
|
|
|||
|
|
## API端点列表
|
|||
|
|
|
|||
|
|
### 健康检查
|
|||
|
|
- `GET /health` - 检查服务器状态
|
|||
|
|
|
|||
|
|
### 客户管理API
|
|||
|
|
|
|||
|
|
1. **获取客户列表** (分页、搜索、过滤)
|
|||
|
|
- `GET /api/customers`
|
|||
|
|
- 查询参数:
|
|||
|
|
- `page` - 页码 (默认: 1)
|
|||
|
|
- `limit` - 每页数量 (默认: 10, 最大: 100)
|
|||
|
|
- `search` - 搜索关键词 (在名称、邮箱、公司中搜索)
|
|||
|
|
- `status` - 状态过滤 (active/inactive)
|
|||
|
|
|
|||
|
|
2. **获取单个客户**
|
|||
|
|
- `GET /api/customers/:id`
|
|||
|
|
- 路径参数:`id` - 客户ID
|
|||
|
|
|
|||
|
|
3. **创建客户**
|
|||
|
|
- `POST /api/customers`
|
|||
|
|
- 请求体 (JSON):
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"name": "客户名称", // 必填
|
|||
|
|
"email": "client@example.com", // 必填,有效邮箱格式
|
|||
|
|
"phone": "13800138000", // 可选
|
|||
|
|
"address": "地址", // 可选
|
|||
|
|
"company": "公司名称", // 可选
|
|||
|
|
"tax_id": "税号", // 可选
|
|||
|
|
"status": "active" // 可选,默认: active
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
4. **更新客户**
|
|||
|
|
- `PUT /api/customers/:id`
|
|||
|
|
- 路径参数:`id` - 客户ID
|
|||
|
|
- 请求体:需要更新的字段(部分更新支持)
|
|||
|
|
|
|||
|
|
5. **删除客户**
|
|||
|
|
- `DELETE /api/customers/:id`
|
|||
|
|
- 路径参数:`id` - 客户ID
|
|||
|
|
|
|||
|
|
6. **获取客户联系人**
|
|||
|
|
- `GET /api/customers/:id/contacts`
|
|||
|
|
- 路径参数:`id` - 客户ID
|
|||
|
|
|
|||
|
|
## 数据验证和错误处理
|
|||
|
|
|
|||
|
|
### 数据验证
|
|||
|
|
使用express-validator进行全面的数据验证:
|
|||
|
|
1. **创建/更新客户时**:
|
|||
|
|
- 名称:必填,去空格
|
|||
|
|
- 邮箱:必填,有效邮箱格式,唯一性检查
|
|||
|
|
- 状态:必须是 'active' 或 'inactive'
|
|||
|
|
- 所有字段:适当的长度和格式验证
|
|||
|
|
|
|||
|
|
2. **查询参数验证**:
|
|||
|
|
- 页码:最小值为1
|
|||
|
|
- 每页数量:1-100之间
|
|||
|
|
- ID参数:必须是正整数
|
|||
|
|
|
|||
|
|
### 错误处理
|
|||
|
|
统一的错误响应格式:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"success": false,
|
|||
|
|
"message": "错误描述",
|
|||
|
|
"errors": [{"msg": "详细验证错误", "param": "字段名", "location": "body"}]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
HTTP状态码:
|
|||
|
|
- `200` - 成功
|
|||
|
|
- `201` - 创建成功
|
|||
|
|
- `400` - 请求参数错误/验证失败
|
|||
|
|
- `404` - 资源未找到
|
|||
|
|
- `409` - 资源冲突(邮箱已存在)
|
|||
|
|
- `500` - 服务器内部错误
|
|||
|
|
|
|||
|
|
## 测试方法
|
|||
|
|
|
|||
|
|
### 1. 使用测试脚本(推荐)
|
|||
|
|
```bash
|
|||
|
|
# 确保服务器正在运行
|
|||
|
|
npm run dev
|
|||
|
|
|
|||
|
|
# 在另一个终端运行完整测试
|
|||
|
|
chmod +x test-api.sh
|
|||
|
|
./test-api.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 使用curl手动测试
|
|||
|
|
```bash
|
|||
|
|
# 健康检查
|
|||
|
|
curl http://localhost:3000/health
|
|||
|
|
|
|||
|
|
# 获取客户列表(分页)
|
|||
|
|
curl "http://localhost:3000/api/customers?page=1&limit=5"
|
|||
|
|
|
|||
|
|
# 搜索客户
|
|||
|
|
curl "http://localhost:3000/api/customers?search=张"
|
|||
|
|
|
|||
|
|
# 创建客户
|
|||
|
|
curl -X POST http://localhost:3000/api/customers \
|
|||
|
|
-H "Content-Type: application/json" \
|
|||
|
|
-d '{"name":"测试客户","email":"test@example.com","phone":"12345678901"}'
|
|||
|
|
|
|||
|
|
# 获取单个客户
|
|||
|
|
curl http://localhost:3000/api/customers/1
|
|||
|
|
|
|||
|
|
# 更新客户
|
|||
|
|
curl -X PUT http://localhost:3000/api/customers/1 \
|
|||
|
|
-H "Content-Type: application/json" \
|
|||
|
|
-d '{"phone":"13888888888"}'
|
|||
|
|
|
|||
|
|
# 删除客户
|
|||
|
|
curl -X DELETE http://localhost:3000/api/customers/1
|
|||
|
|
|
|||
|
|
# 获取客户联系人
|
|||
|
|
curl http://localhost:3000/api/customers/1/contacts
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 使用Postman
|
|||
|
|
导入 `postman-collection.json` 文件到Postman,设置环境变量 `base_url = http://localhost:3000`
|
|||
|
|
|
|||
|
|
## 数据库表结构
|
|||
|
|
|
|||
|
|
### customers表(客户表)
|
|||
|
|
| 字段名 | 类型 | 约束 | 说明 |
|
|||
|
|
|--------|------|------|------|
|
|||
|
|
| id | SERIAL | PRIMARY KEY | 自增主键 |
|
|||
|
|
| name | VARCHAR(100) | NOT NULL | 客户名称 |
|
|||
|
|
| email | VARCHAR(100) | UNIQUE, NOT NULL | 邮箱(唯一) |
|
|||
|
|
| phone | VARCHAR(20) | | 联系电话 |
|
|||
|
|
| address | TEXT | | 地址 |
|
|||
|
|
| company | VARCHAR(100) | | 公司名称 |
|
|||
|
|
| tax_id | VARCHAR(50) | | 税号 |
|
|||
|
|
| status | VARCHAR(20) | DEFAULT 'active' | 状态:active/inactive |
|
|||
|
|
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
|
|||
|
|
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 更新时间 |
|
|||
|
|
|
|||
|
|
### contacts表(联系人表)
|
|||
|
|
| 字段名 | 类型 | 约束 | 说明 |
|
|||
|
|
|--------|------|------|------|
|
|||
|
|
| id | SERIAL | PRIMARY KEY | 自增主键 |
|
|||
|
|
| customer_id | INTEGER | REFERENCES customers(id) ON DELETE CASCADE | 客户ID(外键) |
|
|||
|
|
| name | VARCHAR(100) | NOT NULL | 联系人姓名 |
|
|||
|
|
| position | VARCHAR(100) | | 职位 |
|
|||
|
|
| email | VARCHAR(100) | | 邮箱 |
|
|||
|
|
| phone | VARCHAR(20) | | 电话 |
|
|||
|
|
| is_primary | BOOLEAN | DEFAULT false | 是否主要联系人 |
|
|||
|
|
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
|
|||
|
|
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 更新时间 |
|
|||
|
|
|
|||
|
|
### 索引
|
|||
|
|
- `idx_customers_email` - 邮箱索引(加速查询和唯一性检查)
|
|||
|
|
- `idx_customers_status` - 状态索引(加速状态过滤)
|
|||
|
|
- `idx_contacts_customer_id` - 客户ID索引(加速关联查询)
|
|||
|
|
|
|||
|
|
## 示例数据
|
|||
|
|
初始化脚本已包含示例数据:
|
|||
|
|
- 5个示例客户(3个active,1个inactive)
|
|||
|
|
- 7个示例联系人
|
|||
|
|
- 包含中文数据,便于测试搜索功能
|
|||
|
|
|
|||
|
|
## 注意事项
|
|||
|
|
|
|||
|
|
1. **数据库连接**:确保PostgreSQL服务正在运行,默认使用postgres用户
|
|||
|
|
2. **环境安全**:生产环境请修改默认密码,使用更安全的认证方式
|
|||
|
|
3. **性能考虑**:
|
|||
|
|
- 分页查询避免大数据量传输
|
|||
|
|
- 重要字段已添加索引
|
|||
|
|
- 使用连接池管理数据库连接
|
|||
|
|
4. **数据完整性**:
|
|||
|
|
- 邮箱唯一性约束
|
|||
|
|
- 外键约束保证数据一致性
|
|||
|
|
- 级联删除(删除客户时自动删除联系人)
|
|||
|
|
|
|||
|
|
## 故障排除
|
|||
|
|
|
|||
|
|
### 常见问题
|
|||
|
|
|
|||
|
|
1. **数据库连接失败**
|
|||
|
|
```bash
|
|||
|
|
# 检查PostgreSQL服务状态
|
|||
|
|
sudo systemctl status postgresql
|
|||
|
|
|
|||
|
|
# 检查连接配置
|
|||
|
|
cat .env
|
|||
|
|
|
|||
|
|
# 测试数据库连接
|
|||
|
|
sudo -u postgres psql -l
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **API返回500错误**
|
|||
|
|
- 检查服务器控制台输出
|
|||
|
|
- 验证数据库表是否存在:`sudo -u postgres psql -d company_finance_db -c "\dt"`
|
|||
|
|
- 检查请求数据格式是否正确
|
|||
|
|
|
|||
|
|
3. **邮箱已存在错误(409)**
|
|||
|
|
- 每个客户必须有唯一的邮箱地址
|
|||
|
|
- 更新操作时也要确保邮箱唯一性
|
|||
|
|
|
|||
|
|
4. **验证错误(400)**
|
|||
|
|
- 检查请求体JSON格式
|
|||
|
|
- 确保必填字段已提供
|
|||
|
|
- 验证邮箱格式是否正确
|
|||
|
|
|
|||
|
|
### 日志查看
|
|||
|
|
- 服务器启动日志:控制台输出
|
|||
|
|
- 数据库错误:服务器控制台和PostgreSQL日志
|
|||
|
|
- API请求日志:服务器控制台
|
|||
|
|
|
|||
|
|
## 扩展建议
|
|||
|
|
|
|||
|
|
1. **添加身份验证**:使用JWT实现API认证
|
|||
|
|
2. **添加日志系统**:使用winston或morgan记录请求日志
|
|||
|
|
3. **添加缓存**:对频繁查询的数据添加Redis缓存
|
|||
|
|
4. **添加监控**:集成Prometheus监控指标
|
|||
|
|
5. **API文档**:使用Swagger/OpenAPI生成文档
|
|||
|
|
|
|||
|
|
## 项目结构
|
|||
|
|
```
|
|||
|
|
/opt/company-finance-system/backend/
|
|||
|
|
├── server-complete.js # 主服务器文件(客户管理API)
|
|||
|
|
├── db.js # 数据库连接配置
|
|||
|
|
├── package.json # 依赖配置
|
|||
|
|
├── .env # 环境变量
|
|||
|
|
├── .env.example # 环境变量示例
|
|||
|
|
├── init-db.sql # 数据库初始化脚本
|
|||
|
|
├── test-api.sh # API测试脚本
|
|||
|
|
├── README.md # 项目文档
|
|||
|
|
└── postman-collection.json # Postman集合
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 完成状态
|
|||
|
|
✅ 所有要求的API端点已实现:
|
|||
|
|
1. ✅ GET /api/customers - 获取客户列表(分页、搜索)
|
|||
|
|
2. ✅ GET /api/customers/:id - 获取单个客户
|
|||
|
|
3. ✅ POST /api/customers - 创建客户
|
|||
|
|
4. ✅ PUT /api/customers/:id - 更新客户
|
|||
|
|
5. ✅ DELETE /api/customers/:id - 删除客户
|
|||
|
|
6. ✅ GET /api/customers/:id/contacts - 获取客户联系人
|
|||
|
|
|
|||
|
|
✅ 使用PostgreSQL数据库,连接现有company_finance_db
|
|||
|
|
✅ 包含数据验证和错误处理
|
|||
|
|
✅ 提供完整的测试方法和文档
|