# 公司财务系统 - 客户管理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 ✅ 包含数据验证和错误处理 ✅ 提供完整的测试方法和文档