diff --git a/docs/API接口文档.md b/docs/API接口文档.md new file mode 100644 index 0000000..7a5615c --- /dev/null +++ b/docs/API接口文档.md @@ -0,0 +1,1644 @@ +# 活牛采购智能数字化系统 - API接口文档 + +## 版本历史 +| 版本 | 日期 | 作者 | 变更说明 | +|------|------|------|----------| +| v1.0 | 2024-12-20 | API架构师 | 初版API接口文档 | + +## 1. API概览 + +### 1.1 基础信息 + +- **Base URL**: `https://api.niumall.com/v1` +- **协议**: HTTPS +- **数据格式**: JSON +- **字符编码**: UTF-8 +- **API版本**: v1 + +### 1.2 认证方式 + +#### JWT Token认证 +```http +Authorization: Bearer +``` + +#### 认证流程 +1. 用户登录获取access_token和refresh_token +2. 请求头携带access_token +3. token过期时使用refresh_token刷新 +4. refresh_token过期需重新登录 + +### 1.3 通用响应格式 + +#### 成功响应 +```json +{ + "code": 200, + "message": "success", + "data": { + // 具体数据 + }, + "timestamp": "2024-12-20T10:30:00Z", + "request_id": "req_1234567890" +} +``` + +#### 错误响应 +```json +{ + "code": 400, + "message": "参数错误", + "error": { + "type": "VALIDATION_ERROR", + "details": [ + { + "field": "phone", + "message": "手机号格式不正确" + } + ] + }, + "timestamp": "2024-12-20T10:30:00Z", + "request_id": "req_1234567890" +} +``` + +### 1.4 状态码说明 + +| 状态码 | 说明 | 描述 | +|--------|------|------| +| 200 | OK | 请求成功 | +| 201 | Created | 资源创建成功 | +| 400 | Bad Request | 请求参数错误 | +| 401 | Unauthorized | 未授权,需要登录 | +| 403 | Forbidden | 禁止访问,权限不足 | +| 404 | Not Found | 资源不存在 | +| 409 | Conflict | 资源冲突 | +| 422 | Unprocessable Entity | 请求格式正确,但语义错误 | +| 429 | Too Many Requests | 请求过于频繁 | +| 500 | Internal Server Error | 服务器内部错误 | + +## 2. 用户认证模块 + +### 2.1 用户注册 + +#### 接口信息 +- **URL**: `/auth/register` +- **Method**: `POST` +- **描述**: 用户注册接口 + +#### 请求参数 +```json +{ + "phone": "13800138000", + "password": "password123", + "name": "张三", + "role": "client", + "verification_code": "123456" +} +``` + +#### 参数说明 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| phone | string | 是 | 手机号,11位数字 | +| password | string | 是 | 密码,6-20位字符 | +| name | string | 是 | 姓名,2-50个字符 | +| role | string | 是 | 用户角色:client/supplier/driver/trader | +| verification_code | string | 是 | 短信验证码 | + +#### 响应示例 +```json +{ + "code": 201, + "message": "注册成功", + "data": { + "user_id": 12345, + "phone": "13800138000", + "name": "张三", + "role": "client", + "status": "active" + } +} +``` + +### 2.2 用户登录 + +#### 接口信息 +- **URL**: `/auth/login` +- **Method**: `POST` +- **描述**: 用户登录接口 + +#### 请求参数 +```json +{ + "phone": "13800138000", + "password": "password123", + "device_info": { + "device_id": "device_123", + "device_type": "mobile", + "app_version": "1.0.0" + } +} +``` + +#### 响应示例 +```json +{ + "code": 200, + "message": "登录成功", + "data": { + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "expires_in": 7200, + "user": { + "id": 12345, + "phone": "13800138000", + "name": "张三", + "role": "client", + "avatar": "https://cdn.niumall.com/avatars/12345.jpg" + } + } +} +``` + +### 2.3 刷新Token + +#### 接口信息 +- **URL**: `/auth/refresh` +- **Method**: `POST` +- **描述**: 刷新访问令牌 + +#### 请求参数 +```json +{ + "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." +} +``` + +#### 响应示例 +```json +{ + "code": 200, + "message": "Token刷新成功", + "data": { + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "expires_in": 7200 + } +} +``` + +### 2.4 发送验证码 + +#### 接口信息 +- **URL**: `/auth/send-code` +- **Method**: `POST` +- **描述**: 发送短信验证码 + +#### 请求参数 +```json +{ + "phone": "13800138000", + "type": "register" +} +``` + +#### 参数说明 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| phone | string | 是 | 手机号 | +| type | string | 是 | 验证码类型:register/login/reset_password | + +#### 响应示例 +```json +{ + "code": 200, + "message": "验证码发送成功", + "data": { + "expires_in": 300 + } +} +``` + +## 3. 用户管理模块 + +### 3.1 获取用户信息 + +#### 接口信息 +- **URL**: `/users/profile` +- **Method**: `GET` +- **描述**: 获取当前用户详细信息 +- **认证**: 需要 + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "id": 12345, + "phone": "13800138000", + "name": "张三", + "role": "client", + "status": "active", + "avatar": "https://cdn.niumall.com/avatars/12345.jpg", + "profile": { + "company_name": "北京牛肉贸易有限公司", + "business_license": "https://cdn.niumall.com/licenses/12345.jpg", + "license_number": "91110000123456789X", + "legal_person": "张三", + "contact_address": "北京市朝阳区xxx街道xxx号", + "bank_account": "6222021234567890", + "bank_name": "中国工商银行北京分行" + }, + "created_at": "2024-01-01T00:00:00Z", + "last_login_at": "2024-12-20T10:00:00Z" + } +} +``` + +### 3.2 更新用户信息 + +#### 接口信息 +- **URL**: `/users/profile` +- **Method**: `PUT` +- **描述**: 更新用户信息 +- **认证**: 需要 + +#### 请求参数 +```json +{ + "name": "张三丰", + "avatar": "https://cdn.niumall.com/avatars/new_12345.jpg", + "profile": { + "company_name": "北京优质牛肉贸易有限公司", + "contact_address": "北京市朝阳区新地址xxx号", + "emergency_contact": "李四", + "emergency_phone": "13900139000" + } +} +``` + +#### 响应示例 +```json +{ + "code": 200, + "message": "更新成功", + "data": { + "updated_fields": ["name", "avatar", "profile.company_name", "profile.contact_address"] + } +} +``` + +### 3.3 修改密码 + +#### 接口信息 +- **URL**: `/users/change-password` +- **Method**: `POST` +- **描述**: 修改用户密码 +- **认证**: 需要 + +#### 请求参数 +```json +{ + "old_password": "old_password123", + "new_password": "new_password456", + "confirm_password": "new_password456" +} +``` + +#### 响应示例 +```json +{ + "code": 200, + "message": "密码修改成功", + "data": {} +} +``` + +## 4. 订单管理模块 + +### 4.1 创建订单 + +#### 接口信息 +- **URL**: `/orders` +- **Method**: `POST` +- **描述**: 创建新订单 +- **认证**: 需要 +- **权限**: client, trader + +#### 请求参数 +```json +{ + "cattle_type": "西门塔尔牛", + "quantity": 50, + "weight_range": "400-500kg", + "unit_price": 28.50, + "price_type": "per_kg", + "delivery_address": "河北省石家庄市xxx屠宰场", + "delivery_time": "2024-12-25T08:00:00Z", + "special_requirements": "要求健康证明齐全,无疫病", + "quality_standards": { + "min_weight": 400, + "max_weight": 500, + "health_certificate": true, + "quarantine_certificate": true + } +} +``` + +#### 参数说明 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| cattle_type | string | 是 | 牛只品种 | +| quantity | integer | 是 | 数量(头) | +| weight_range | string | 否 | 重量范围 | +| unit_price | decimal | 是 | 单价(元/kg或元/头) | +| price_type | string | 是 | 计价方式:per_kg/per_head | +| delivery_address | string | 是 | 交货地址 | +| delivery_time | datetime | 是 | 要求交货时间 | +| special_requirements | string | 否 | 特殊要求 | +| quality_standards | object | 否 | 质量标准 | + +#### 响应示例 +```json +{ + "code": 201, + "message": "订单创建成功", + "data": { + "id": 67890, + "order_no": "ORD202412200001", + "status": "draft", + "cattle_type": "西门塔尔牛", + "quantity": 50, + "unit_price": 28.50, + "total_amount": 712500.00, + "delivery_time": "2024-12-25T08:00:00Z", + "created_at": "2024-12-20T10:30:00Z" + } +} +``` + +### 4.2 获取订单列表 + +#### 接口信息 +- **URL**: `/orders` +- **Method**: `GET` +- **描述**: 获取订单列表 +- **认证**: 需要 + +#### 查询参数 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| page | integer | 否 | 页码,默认1 | +| limit | integer | 否 | 每页数量,默认20,最大100 | +| status | string | 否 | 订单状态筛选 | +| cattle_type | string | 否 | 牛只品种筛选 | +| start_date | date | 否 | 开始日期 | +| end_date | date | 否 | 结束日期 | +| keyword | string | 否 | 关键词搜索(订单号、供应商名称等) | + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "orders": [ + { + "id": 67890, + "order_no": "ORD202412200001", + "status": "confirmed", + "cattle_type": "西门塔尔牛", + "quantity": 50, + "unit_price": 28.50, + "total_amount": 712500.00, + "client": { + "id": 12345, + "name": "张三", + "company_name": "北京牛肉贸易有限公司" + }, + "supplier": { + "id": 54321, + "name": "李四", + "company_name": "内蒙古优质牧场" + }, + "delivery_time": "2024-12-25T08:00:00Z", + "created_at": "2024-12-20T10:30:00Z" + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 156, + "pages": 8 + } + } +} +``` + +### 4.3 获取订单详情 + +#### 接口信息 +- **URL**: `/orders/{order_id}` +- **Method**: `GET` +- **描述**: 获取订单详细信息 +- **认证**: 需要 + +#### 路径参数 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| order_id | integer | 是 | 订单ID | + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "id": 67890, + "order_no": "ORD202412200001", + "status": "transporting", + "cattle_type": "西门塔尔牛", + "quantity": 50, + "weight_range": "400-500kg", + "estimated_weight": 22500.00, + "actual_weight": 22800.00, + "unit_price": 28.50, + "price_type": "per_kg", + "total_amount": 712500.00, + "final_amount": 649800.00, + "client": { + "id": 12345, + "name": "张三", + "phone": "138****8000", + "company_name": "北京牛肉贸易有限公司" + }, + "supplier": { + "id": 54321, + "name": "李四", + "phone": "139****9000", + "company_name": "内蒙古优质牧场" + }, + "trader": { + "id": 11111, + "name": "王五", + "phone": "137****7000", + "company_name": "中原牛肉贸易公司" + }, + "pickup_address": "内蒙古呼和浩特市xxx牧场", + "delivery_address": "河北省石家庄市xxx屠宰场", + "pickup_time": "2024-12-23T06:00:00Z", + "delivery_time": "2024-12-25T08:00:00Z", + "actual_delivery_time": null, + "special_requirements": "要求健康证明齐全,无疫病", + "quality_standards": { + "min_weight": 400, + "max_weight": 500, + "health_certificate": true, + "quarantine_certificate": true + }, + "transport_task": { + "id": 98765, + "task_no": "TRK202412200001", + "status": "transporting", + "driver": { + "id": 33333, + "name": "赵六", + "phone": "136****6000" + }, + "vehicle_no": "京A12345", + "current_location": { + "latitude": 39.9042, + "longitude": 116.4074, + "address": "北京市朝阳区xxx路段", + "updated_at": "2024-12-20T10:25:00Z" + } + }, + "attachments": [ + { + "id": 1001, + "file_name": "合同.pdf", + "file_url": "https://cdn.niumall.com/contracts/1001.pdf", + "attachment_type": "contract", + "created_at": "2024-12-20T10:35:00Z" + } + ], + "status_logs": [ + { + "from_status": "draft", + "to_status": "pending", + "operator": "张三", + "remark": "提交订单", + "created_at": "2024-12-20T10:30:00Z" + }, + { + "from_status": "pending", + "to_status": "confirmed", + "operator": "李四", + "remark": "确认接单", + "created_at": "2024-12-20T11:00:00Z" + } + ], + "created_at": "2024-12-20T10:30:00Z", + "updated_at": "2024-12-20T11:00:00Z" + } +} +``` + +### 4.4 更新订单状态 + +#### 接口信息 +- **URL**: `/orders/{order_id}/status` +- **Method**: `PUT` +- **描述**: 更新订单状态 +- **认证**: 需要 + +#### 请求参数 +```json +{ + "status": "confirmed", + "remark": "确认接单,预计3天内发货" +} +``` + +#### 响应示例 +```json +{ + "code": 200, + "message": "订单状态更新成功", + "data": { + "order_id": 67890, + "old_status": "pending", + "new_status": "confirmed", + "updated_at": "2024-12-20T11:00:00Z" + } +} +``` + +### 4.5 取消订单 + +#### 接口信息 +- **URL**: `/orders/{order_id}/cancel` +- **Method**: `POST` +- **描述**: 取消订单 +- **认证**: 需要 + +#### 请求参数 +```json +{ + "cancel_reason": "客户需求变更,暂时不需要采购" +} +``` + +#### 响应示例 +```json +{ + "code": 200, + "message": "订单取消成功", + "data": { + "order_id": 67890, + "status": "cancelled", + "cancel_reason": "客户需求变更,暂时不需要采购", + "cancelled_at": "2024-12-20T11:30:00Z" + } +} +``` + +## 5. 运输管理模块 + +### 5.1 创建运输任务 + +#### 接口信息 +- **URL**: `/transport/tasks` +- **Method**: `POST` +- **描述**: 创建运输任务 +- **认证**: 需要 +- **权限**: supplier, trader, admin + +#### 请求参数 +```json +{ + "order_id": 67890, + "driver_id": 33333, + "vehicle_no": "京A12345", + "vehicle_type": "厢式货车", + "vehicle_capacity": 25.0, + "planned_start_time": "2024-12-23T06:00:00Z", + "planned_end_time": "2024-12-25T08:00:00Z", + "transport_fee": 8000.00, + "notes": "注意保持车厢通风,定时检查牛只状态" +} +``` + +#### 响应示例 +```json +{ + "code": 201, + "message": "运输任务创建成功", + "data": { + "id": 98765, + "task_no": "TRK202412200001", + "order_id": 67890, + "status": "assigned", + "driver": { + "id": 33333, + "name": "赵六", + "phone": "136****6000" + }, + "vehicle_no": "京A12345", + "planned_start_time": "2024-12-23T06:00:00Z", + "planned_end_time": "2024-12-25T08:00:00Z", + "transport_fee": 8000.00, + "created_at": "2024-12-20T11:45:00Z" + } +} +``` + +### 5.2 获取运输任务列表 + +#### 接口信息 +- **URL**: `/transport/tasks` +- **Method**: `GET` +- **描述**: 获取运输任务列表 +- **认证**: 需要 + +#### 查询参数 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| page | integer | 否 | 页码,默认1 | +| limit | integer | 否 | 每页数量,默认20 | +| status | string | 否 | 任务状态筛选 | +| driver_id | integer | 否 | 司机ID筛选 | +| start_date | date | 否 | 开始日期 | +| end_date | date | 否 | 结束日期 | + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "tasks": [ + { + "id": 98765, + "task_no": "TRK202412200001", + "order_no": "ORD202412200001", + "status": "transporting", + "driver": { + "id": 33333, + "name": "赵六", + "phone": "136****6000" + }, + "vehicle_no": "京A12345", + "start_location": "内蒙古呼和浩特市xxx牧场", + "end_location": "河北省石家庄市xxx屠宰场", + "planned_start_time": "2024-12-23T06:00:00Z", + "actual_start_time": "2024-12-23T06:15:00Z", + "estimated_arrival_time": "2024-12-25T07:30:00Z", + "progress": 65.5, + "current_location": { + "latitude": 39.9042, + "longitude": 116.4074, + "address": "北京市朝阳区xxx路段" + } + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 45, + "pages": 3 + } + } +} +``` + +### 5.3 获取运输任务详情 + +#### 接口信息 +- **URL**: `/transport/tasks/{task_id}` +- **Method**: `GET` +- **描述**: 获取运输任务详细信息 +- **认证**: 需要 + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "id": 98765, + "task_no": "TRK202412200001", + "order": { + "id": 67890, + "order_no": "ORD202412200001", + "cattle_type": "西门塔尔牛", + "quantity": 50 + }, + "status": "transporting", + "driver": { + "id": 33333, + "name": "赵六", + "phone": "136****6000", + "driver_license": "1101051234567890" + }, + "vehicle_no": "京A12345", + "vehicle_type": "厢式货车", + "vehicle_capacity": 25.0, + "start_location": "内蒙古呼和浩特市xxx牧场", + "end_location": "河北省石家庄市xxx屠宰场", + "start_coordinates": { + "latitude": 40.8414, + "longitude": 111.7519 + }, + "end_coordinates": { + "latitude": 38.0428, + "longitude": 114.5149 + }, + "planned_distance": 580.5, + "actual_distance": 592.3, + "planned_start_time": "2024-12-23T06:00:00Z", + "actual_start_time": "2024-12-23T06:15:00Z", + "planned_end_time": "2024-12-25T08:00:00Z", + "estimated_arrival_time": "2024-12-25T07:30:00Z", + "transport_fee": 8000.00, + "fuel_cost": 1200.00, + "toll_cost": 350.00, + "current_location": { + "latitude": 39.9042, + "longitude": 116.4074, + "address": "北京市朝阳区xxx路段", + "speed": 65.5, + "direction": 135.2, + "updated_at": "2024-12-20T10:25:00Z" + }, + "cattle_status": { + "normal_count": 49, + "stressed_count": 1, + "sick_count": 0, + "dead_count": 0, + "temperature": 18.5, + "humidity": 65.2 + }, + "route_progress": 65.5, + "events": [ + { + "id": 2001, + "event_type": "departure", + "event_title": "车辆出发", + "event_description": "装车完成,开始运输", + "occurred_at": "2024-12-23T06:15:00Z", + "location": { + "latitude": 40.8414, + "longitude": 111.7519, + "address": "内蒙古呼和浩特市xxx牧场" + } + }, + { + "id": 2002, + "event_type": "rest_stop", + "event_title": "休息停车", + "event_description": "司机休息,检查牛只状态", + "occurred_at": "2024-12-23T12:30:00Z", + "location": { + "latitude": 40.1436, + "longitude": 113.9854, + "address": "山西省大同市服务区" + } + } + ], + "created_at": "2024-12-20T11:45:00Z", + "updated_at": "2024-12-20T10:25:00Z" + } +} +``` + +### 5.4 更新位置信息 + +#### 接口信息 +- **URL**: `/transport/tasks/{task_id}/location` +- **Method**: `POST` +- **描述**: 更新运输任务位置信息 +- **认证**: 需要 +- **权限**: driver + +#### 请求参数 +```json +{ + "latitude": 39.9042, + "longitude": 116.4074, + "altitude": 45.2, + "accuracy": 5.0, + "speed": 65.5, + "direction": 135.2, + "cattle_status": "normal", + "temperature": 18.5, + "humidity": 65.2, + "recorded_at": "2024-12-20T10:25:00Z" +} +``` + +#### 响应示例 +```json +{ + "code": 200, + "message": "位置信息更新成功", + "data": { + "task_id": 98765, + "location": { + "latitude": 39.9042, + "longitude": 116.4074, + "address": "北京市朝阳区xxx路段", + "updated_at": "2024-12-20T10:25:00Z" + }, + "progress": 65.5, + "estimated_arrival_time": "2024-12-25T07:30:00Z" + } +} +``` + +### 5.5 上报运输事件 + +#### 接口信息 +- **URL**: `/transport/tasks/{task_id}/events` +- **Method**: `POST` +- **描述**: 上报运输过程中的事件 +- **认证**: 需要 + +#### 请求参数 +```json +{ + "event_type": "emergency", + "event_title": "牛只异常", + "event_description": "发现一头牛只出现应激反应,已进行处理", + "severity": "medium", + "latitude": 39.9042, + "longitude": 116.4074, + "photos": [ + "https://cdn.niumall.com/events/photo1.jpg", + "https://cdn.niumall.com/events/photo2.jpg" + ], + "occurred_at": "2024-12-20T10:30:00Z" +} +``` + +#### 响应示例 +```json +{ + "code": 201, + "message": "事件上报成功", + "data": { + "id": 2003, + "task_id": 98765, + "event_type": "emergency", + "event_title": "牛只异常", + "severity": "medium", + "is_resolved": false, + "occurred_at": "2024-12-20T10:30:00Z", + "created_at": "2024-12-20T10:32:00Z" + } +} +``` + +## 6. 质量管理模块 + +### 6.1 创建质量检验记录 + +#### 接口信息 +- **URL**: `/quality/inspections` +- **Method**: `POST` +- **描述**: 创建质量检验记录 +- **认证**: 需要 +- **权限**: client, supplier, admin + +#### 请求参数 +```json +{ + "order_id": 67890, + "inspection_type": "post_delivery", + "total_count": 50, + "qualified_count": 48, + "unqualified_count": 2, + "dead_count": 0, + "sick_count": 1, + "total_weight": 22800.00, + "average_weight": 456.0, + "overall_grade": "B", + "quality_score": 85.5, + "health_score": 90.0, + "appearance_score": 82.0, + "inspection_items": { + "weight_check": { + "passed": true, + "notes": "重量符合要求" + }, + "health_check": { + "passed": true, + "notes": "整体健康状况良好,1头轻微应激" + }, + "appearance_check": { + "passed": true, + "notes": "外观良好,毛色正常" + } + }, + "defect_details": [ + { + "cattle_no": "C001", + "defect_type": "应激反应", + "description": "轻微应激,建议休息观察" + } + ], + "photos": [ + "https://cdn.niumall.com/inspections/photo1.jpg", + "https://cdn.niumall.com/inspections/photo2.jpg" + ], + "is_passed": true, + "recommendations": "整体质量良好,建议加强运输过程中的应激管理", + "inspection_date": "2024-12-25T09:00:00Z" +} +``` + +#### 响应示例 +```json +{ + "code": 201, + "message": "质量检验记录创建成功", + "data": { + "id": 5001, + "order_id": 67890, + "inspection_type": "post_delivery", + "overall_grade": "B", + "quality_score": 85.5, + "is_passed": true, + "inspector": { + "id": 12345, + "name": "张三" + }, + "inspection_date": "2024-12-25T09:00:00Z", + "created_at": "2024-12-25T09:30:00Z" + } +} +``` + +### 6.2 获取质量检验记录 + +#### 接口信息 +- **URL**: `/quality/inspections` +- **Method**: `GET` +- **描述**: 获取质量检验记录列表 +- **认证**: 需要 + +#### 查询参数 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| order_id | integer | 否 | 订单ID筛选 | +| inspection_type | string | 否 | 检验类型筛选 | +| is_passed | boolean | 否 | 是否通过筛选 | +| start_date | date | 否 | 开始日期 | +| end_date | date | 否 | 结束日期 | + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "inspections": [ + { + "id": 5001, + "order": { + "id": 67890, + "order_no": "ORD202412200001", + "cattle_type": "西门塔尔牛" + }, + "inspection_type": "post_delivery", + "total_count": 50, + "qualified_count": 48, + "overall_grade": "B", + "quality_score": 85.5, + "is_passed": true, + "inspector": { + "id": 12345, + "name": "张三" + }, + "inspection_date": "2024-12-25T09:00:00Z" + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 25, + "pages": 2 + } + } +} +``` + +## 7. 财务管理模块 + +### 7.1 创建财务结算 + +#### 接口信息 +- **URL**: `/finance/settlements` +- **Method**: `POST` +- **描述**: 创建财务结算单 +- **认证**: 需要 +- **权限**: client, trader, admin + +#### 请求参数 +```json +{ + "order_id": 67890, + "order_amount": 649800.00, + "prepaid_amount": 100000.00, + "transport_fee": 8000.00, + "insurance_fee": 2000.00, + "service_fee": 5000.00, + "penalty_amount": 0.00, + "discount_amount": 10000.00, + "tax_amount": 32490.00, + "settlement_type": "full_payment", + "payment_terms": "货到付款,验收合格后3日内付清", + "settlement_date": "2024-12-25", + "due_date": "2024-12-28" +} +``` + +#### 响应示例 +```json +{ + "code": 201, + "message": "财务结算单创建成功", + "data": { + "id": 8001, + "settlement_no": "STL202412250001", + "order_id": 67890, + "final_amount": 687290.00, + "status": "draft", + "settlement_date": "2024-12-25", + "due_date": "2024-12-28", + "created_at": "2024-12-25T10:00:00Z" + } +} +``` + +### 7.2 创建支付记录 + +#### 接口信息 +- **URL**: `/finance/payments` +- **Method**: `POST` +- **描述**: 创建支付记录 +- **认证**: 需要 + +#### 请求参数 +```json +{ + "settlement_id": 8001, + "order_id": 67890, + "payee_id": 54321, + "payment_amount": 687290.00, + "payment_method": "bank_transfer", + "payer_bank_account": "6222021234567890", + "payer_bank_name": "中国工商银行北京分行", + "payee_bank_account": "6228481234567890", + "payee_bank_name": "中国农业银行呼和浩特分行", + "notes": "订单ORD202412200001货款结算", + "receipt_url": "https://cdn.niumall.com/receipts/receipt_8001.jpg" +} +``` + +#### 响应示例 +```json +{ + "code": 201, + "message": "支付记录创建成功", + "data": { + "id": 9001, + "payment_no": "PAY202412250001", + "settlement_id": 8001, + "payment_amount": 687290.00, + "payment_method": "bank_transfer", + "status": "pending", + "created_at": "2024-12-25T11:00:00Z" + } +} +``` + +### 7.3 获取财务统计 + +#### 接口信息 +- **URL**: `/finance/statistics` +- **Method**: `GET` +- **描述**: 获取财务统计数据 +- **认证**: 需要 + +#### 查询参数 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| start_date | date | 是 | 开始日期 | +| end_date | date | 是 | 结束日期 | +| type | string | 否 | 统计类型:daily/monthly/yearly | + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "summary": { + "total_orders": 156, + "total_amount": 12580000.00, + "paid_amount": 10250000.00, + "pending_amount": 2330000.00, + "average_order_amount": 80641.03 + }, + "by_status": { + "completed": { + "count": 120, + "amount": 10250000.00 + }, + "pending": { + "count": 25, + "amount": 2100000.00 + }, + "cancelled": { + "count": 11, + "amount": 230000.00 + } + }, + "by_cattle_type": { + "西门塔尔牛": { + "count": 85, + "amount": 7200000.00 + }, + "安格斯牛": { + "count": 45, + "amount": 3800000.00 + }, + "夏洛莱牛": { + "count": 26, + "amount": 1580000.00 + } + }, + "monthly_trend": [ + { + "month": "2024-10", + "orders": 45, + "amount": 3800000.00 + }, + { + "month": "2024-11", + "orders": 52, + "amount": 4200000.00 + }, + { + "month": "2024-12", + "orders": 59, + "amount": 4580000.00 + } + ] + } +} +``` + +## 8. 文件上传模块 + +### 8.1 获取上传凭证 + +#### 接口信息 +- **URL**: `/upload/token` +- **Method**: `POST` +- **描述**: 获取文件上传凭证 +- **认证**: 需要 + +#### 请求参数 +```json +{ + "file_name": "contract.pdf", + "file_type": "application/pdf", + "file_size": 2048576, + "upload_type": "contract" +} +``` + +#### 参数说明 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| file_name | string | 是 | 文件名 | +| file_type | string | 是 | 文件MIME类型 | +| file_size | integer | 是 | 文件大小(字节) | +| upload_type | string | 是 | 上传类型:avatar/contract/certificate/photo/video | + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "upload_url": "https://upload.niumall.com/upload", + "file_url": "https://cdn.niumall.com/contracts/20241225/contract_12345.pdf", + "upload_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "expires_in": 3600, + "max_file_size": 10485760, + "allowed_types": ["application/pdf", "image/jpeg", "image/png"] + } +} +``` + +### 8.2 确认上传完成 + +#### 接口信息 +- **URL**: `/upload/confirm` +- **Method**: `POST` +- **描述**: 确认文件上传完成 +- **认证**: 需要 + +#### 请求参数 +```json +{ + "file_url": "https://cdn.niumall.com/contracts/20241225/contract_12345.pdf", + "file_name": "contract.pdf", + "file_size": 2048576, + "upload_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." +} +``` + +#### 响应示例 +```json +{ + "code": 200, + "message": "文件上传确认成功", + "data": { + "file_id": "file_12345", + "file_url": "https://cdn.niumall.com/contracts/20241225/contract_12345.pdf", + "status": "uploaded" + } +} +``` + +## 9. 消息通知模块 + +### 9.1 获取通知列表 + +#### 接口信息 +- **URL**: `/notifications` +- **Method**: `GET` +- **描述**: 获取用户通知列表 +- **认证**: 需要 + +#### 查询参数 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| page | integer | 否 | 页码,默认1 | +| limit | integer | 否 | 每页数量,默认20 | +| is_read | boolean | 否 | 是否已读筛选 | +| notification_type | string | 否 | 通知类型筛选 | + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "notifications": [ + { + "id": 10001, + "title": "订单状态更新", + "content": "您的订单ORD202412200001已确认,供应商正在准备货物", + "notification_type": "order", + "priority": "medium", + "is_read": false, + "related_type": "order", + "related_id": 67890, + "created_at": "2024-12-20T11:00:00Z" + }, + { + "id": 10002, + "title": "运输状态更新", + "content": "您的货物已开始运输,预计2024-12-25 07:30到达", + "notification_type": "transport", + "priority": "high", + "is_read": false, + "related_type": "transport_task", + "related_id": 98765, + "created_at": "2024-12-23T06:15:00Z" + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 45, + "pages": 3 + }, + "unread_count": 12 + } +} +``` + +### 9.2 标记通知已读 + +#### 接口信息 +- **URL**: `/notifications/{notification_id}/read` +- **Method**: `PUT` +- **描述**: 标记通知为已读 +- **认证**: 需要 + +#### 响应示例 +```json +{ + "code": 200, + "message": "通知已标记为已读", + "data": { + "notification_id": 10001, + "is_read": true, + "read_at": "2024-12-20T12:00:00Z" + } +} +``` + +### 9.3 批量标记已读 + +#### 接口信息 +- **URL**: `/notifications/read-all` +- **Method**: `PUT` +- **描述**: 批量标记通知为已读 +- **认证**: 需要 + +#### 请求参数 +```json +{ + "notification_ids": [10001, 10002, 10003] +} +``` + +#### 响应示例 +```json +{ + "code": 200, + "message": "批量标记成功", + "data": { + "updated_count": 3, + "updated_at": "2024-12-20T12:00:00Z" + } +} +``` + +## 10. 系统管理模块 + +### 10.1 获取系统配置 + +#### 接口信息 +- **URL**: `/system/configs` +- **Method**: `GET` +- **描述**: 获取系统配置信息 +- **认证**: 需要 + +#### 查询参数 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| category | string | 否 | 配置分类筛选 | +| is_public | boolean | 否 | 是否公开配置 | + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "configs": { + "app": { + "app_name": "活牛采购智能数字化系统", + "app_version": "1.0.0", + "api_version": "v1" + }, + "business": { + "max_order_quantity": 1000, + "min_order_amount": 10000, + "default_transport_fee_rate": 0.05, + "quality_grade_standards": { + "A": "优质", + "B": "良好", + "C": "一般", + "D": "较差" + } + }, + "payment": { + "supported_methods": ["bank_transfer", "alipay", "wechat_pay"], + "max_payment_amount": 10000000, + "payment_timeout": 1800 + } + } + } +} +``` + +### 10.2 获取操作日志 + +#### 接口信息 +- **URL**: `/system/logs` +- **Method**: `GET` +- **描述**: 获取系统操作日志 +- **认证**: 需要 +- **权限**: admin + +#### 查询参数 +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| page | integer | 否 | 页码,默认1 | +| limit | integer | 否 | 每页数量,默认50 | +| user_id | integer | 否 | 用户ID筛选 | +| operation_type | string | 否 | 操作类型筛选 | +| start_date | date | 否 | 开始日期 | +| end_date | date | 否 | 结束日期 | + +#### 响应示例 +```json +{ + "code": 200, + "message": "success", + "data": { + "logs": [ + { + "id": 50001, + "user": { + "id": 12345, + "name": "张三", + "role": "client" + }, + "operation_type": "CREATE_ORDER", + "operation_module": "order", + "operation_description": "创建订单ORD202412200001", + "request_method": "POST", + "request_url": "/api/v1/orders", + "response_status": 201, + "ip_address": "192.168.1.100", + "execution_time": 245, + "created_at": "2024-12-20T10:30:00Z" + } + ], + "pagination": { + "page": 1, + "limit": 50, + "total": 2580, + "pages": 52 + } + } +} +``` + +## 11. 错误码说明 + +### 11.1 通用错误码 + +| 错误码 | 错误类型 | 说明 | +|--------|----------|------| +| 10001 | INVALID_PARAMETER | 参数错误 | +| 10002 | MISSING_PARAMETER | 缺少必需参数 | +| 10003 | INVALID_FORMAT | 参数格式错误 | +| 10004 | PARAMETER_OUT_OF_RANGE | 参数超出范围 | + +### 11.2 认证相关错误码 + +| 错误码 | 错误类型 | 说明 | +|--------|----------|------| +| 20001 | INVALID_TOKEN | Token无效 | +| 20002 | TOKEN_EXPIRED | Token已过期 | +| 20003 | INSUFFICIENT_PERMISSIONS | 权限不足 | +| 20004 | ACCOUNT_LOCKED | 账户被锁定 | +| 20005 | INVALID_CREDENTIALS | 用户名或密码错误 | + +### 11.3 业务相关错误码 + +| 错误码 | 错误类型 | 说明 | +|--------|----------|------| +| 30001 | ORDER_NOT_FOUND | 订单不存在 | +| 30002 | ORDER_STATUS_INVALID | 订单状态无效 | +| 30003 | INSUFFICIENT_INVENTORY | 库存不足 | +| 30004 | PAYMENT_FAILED | 支付失败 | +| 30005 | TRANSPORT_TASK_NOT_FOUND | 运输任务不存在 | + +### 11.4 系统相关错误码 + +| 错误码 | 错误类型 | 说明 | +|--------|----------|------| +| 50001 | DATABASE_ERROR | 数据库错误 | +| 50002 | EXTERNAL_SERVICE_ERROR | 外部服务错误 | +| 50003 | FILE_UPLOAD_FAILED | 文件上传失败 | +| 50004 | RATE_LIMIT_EXCEEDED | 请求频率超限 | + +## 12. SDK和示例代码 + +### 12.1 JavaScript SDK示例 + +```javascript +// 初始化SDK +const NiumallAPI = require('@niumall/api-sdk'); +const client = new NiumallAPI({ + baseURL: 'https://api.niumall.com/v1', + accessToken: 'your_access_token' +}); + +// 创建订单 +async function createOrder() { + try { + const order = await client.orders.create({ + cattle_type: '西门塔尔牛', + quantity: 50, + unit_price: 28.50, + price_type: 'per_kg', + delivery_address: '河北省石家庄市xxx屠宰场', + delivery_time: '2024-12-25T08:00:00Z' + }); + console.log('订单创建成功:', order); + } catch (error) { + console.error('创建订单失败:', error); + } +} + +// 获取订单列表 +async function getOrders() { + try { + const orders = await client.orders.list({ + page: 1, + limit: 20, + status: 'confirmed' + }); + console.log('订单列表:', orders); + } catch (error) { + console.error('获取订单失败:', error); + } +} +``` + +### 12.2 Python SDK示例 + +```python +from niumall_api import NiumallClient +from datetime import datetime + +# 初始化客户端 +client = NiumallClient( + base_url='https://api.niumall.com/v1', + access_token='your_access_token' +) + +# 创建订单 +def create_order(): + try: + order = client.orders.create({ + 'cattle_type': '西门塔尔牛', + 'quantity': 50, + 'unit_price': 28.50, + 'price_type': 'per_kg', + 'delivery_address': '河北省石家庄市xxx屠宰场', + 'delivery_time': '2024-12-25T08:00:00Z' + }) + print(f'订单创建成功: {order}') + except Exception as e: + print(f'创建订单失败: {e}') + +# 获取运输任务详情 +def get_transport_task(task_id): + try: + task = client.transport.get_task(task_id) + print(f'运输任务详情: {task}') + return task + except Exception as e: + print(f'获取运输任务失败: {e}') + return None +``` + +## 13. 测试环境 + +### 13.1 测试环境信息 + +- **测试环境URL**: `https://api-test.niumall.com/v1` +- **测试账号**: + - 采购人: test_client / 123456 + - 供应商: test_supplier / 123456 + - 司机: test_driver / 123456 + - 管理员: test_admin / 123456 + +### 13.2 Postman集合 + +我们提供了完整的Postman集合,包含所有API接口的测试用例: + +- **集合下载**: [Niumall API Collection](https://api.niumall.com/docs/postman/collection.json) +- **环境配置**: [Niumall API Environment](https://api.niumall.com/docs/postman/environment.json) + +### 13.3 API测试工具 + +推荐使用以下工具进行API测试: + +1. **Postman**: 图形化接口测试工具 +2. **curl**: 命令行工具 +3. **Insomnia**: 轻量级REST客户端 +4. **Swagger UI**: 在线API文档和测试 + +--- + +**文档维护**:本文档由API团队负责维护,接口变更时及时更新。 + +**技术支持**:如有疑问,请联系技术支持团队 tech-support@niumall.com + +**最后更新时间**:2024年12月20日 \ No newline at end of file diff --git a/docs/产品需求文档.md b/docs/产品需求文档.md new file mode 100644 index 0000000..41c8010 --- /dev/null +++ b/docs/产品需求文档.md @@ -0,0 +1,469 @@ +# 活牛采购智能数字化系统 - 产品需求文档 (PRD) + +## 版本历史 +| 版本 | 日期 | 作者 | 变更说明 | +|------|------|------|----------| +| v1.0 | 2024-01-20 | 产品经理 | 初版PRD文档 | +| v1.1 | 2024-05-15 | 产品经理 | 更新小程序矩阵需求 | +| v2.0 | 2024-12-20 | 产品经理 | 重构文档结构,完善需求细节 | + +## 1. 项目概述 + +### 1.1 项目背景 + +活牛采购行业长期存在以下核心痛点: +- **信息不透明**:采购流程中各环节信息孤岛,缺乏统一的信息管理平台 +- **流程不规范**:缺乏标准化的操作流程,人为因素导致的错误率高 +- **风险控制难**:质量检验、运输监控、资金结算等环节风险控制能力不足 +- **效率低下**:大量手工操作,重复性工作多,整体效率有待提升 + +### 1.2 项目目标 + +**主要目标**: +- 建立标准化的活牛采购数字化管理平台 +- 实现采购全流程的信息化、透明化管理 +- 提升采购效率,降低操作风险 +- 确保牛只质量可追溯,交易过程安全可靠 + +**具体目标**: +- 采购流程处理时间减少30% +- 操作错误率降低至1%以下 +- 客户满意度提升至95%以上 +- 系统可用性达到99.9% + +### 1.3 成功标准 + +**业务指标**: +- 月活跃用户数 > 500人 +- 订单处理成功率 > 99% +- 平均订单处理时间 < 2小时 +- 用户满意度评分 > 4.5/5.0 + +**技术指标**: +- 系统响应时间 < 2秒 +- 系统可用性 > 99.9% +- 数据准确性 > 99.9% +- 安全事故 = 0 + +## 2. 用户角色与用例 + +### 2.1 用户角色定义 + +| 角色名称 | 角色描述 | 主要职责 | 使用场景 | +|---------|---------|---------|---------| +| **采购人** | 活牛采购需求方 | 发起采购需求、验收确认、支付审批 | 创建订单、跟踪运输、验收支付 | +| **贸易商** | 中间贸易服务商 | 订单转发、供应商管理、资金结算 | 订单管理、供应商协调、结算处理 | +| **供应商** | 活牛供应方 | 牛只准备、装车管理、单据提供 | 接收订单、准备牛只、上传证件 | +| **司机** | 运输服务提供方 | 运输执行、状态上报、单据交接 | 运输跟踪、状态更新、异常上报 | +| **系统管理员** | 平台运营管理 | 用户管理、系统配置、数据监控 | 后台管理、系统维护、数据分析 | + +### 2.2 用户权限矩阵 + +| 功能模块 | 采购人 | 贸易商 | 供应商 | 司机 | 管理员 | +|---------|-------|-------|-------|------|-------| +| 订单创建 | ✅ | ❌ | ❌ | ❌ | ✅ | +| 订单查看 | ✅ | ✅ | ✅ | ✅ | ✅ | +| 订单转发 | ❌ | ✅ | ❌ | ❌ | ✅ | +| 牛只管理 | ❌ | ❌ | ✅ | ❌ | ✅ | +| 运输跟踪 | ✅ | ✅ | ✅ | ✅ | ✅ | +| 验收确认 | ✅ | ❌ | ❌ | ❌ | ✅ | +| 支付处理 | ✅ | ✅ | ❌ | ❌ | ✅ | +| 用户管理 | ❌ | ❌ | ❌ | ❌ | ✅ | + +### 2.3 核心用例场景 + +**用例1:采购订单创建** +- **参与者**:采购人、贸易商 +- **前置条件**:采购人已登录系统 +- **主要流程**:采购人创建订单 → 贸易商审核确认 → 订单生效 +- **后置条件**:订单进入待处理状态 + +**用例2:运输全程跟踪** +- **参与者**:司机、采购人、贸易商 +- **前置条件**:订单已确认,司机已接单 +- **主要流程**:司机上报位置 → 系统记录轨迹 → 相关方实时查看 +- **后置条件**:运输状态实时更新 + +**用例3:到货验收支付** +- **参与者**:采购人、系统 +- **前置条件**:牛只已到达目的地 +- **主要流程**:采购人验收 → 系统计算金额 → 在线支付 +- **后置条件**:交易完成,订单结束 + +## 3. 功能需求 + +### 3.1 采购计划阶段 + +#### 3.1.1 订单创建功能 +**用户故事**:As a 采购人, I want to 创建采购订单, so that 明确采购需求并启动采购流程 + +**验收标准**: +```gherkin +Given 采购人已登录系统 +When 采购人填写采购订单信息 + And 包含牛只品种、重量范围、数量、单价、交货地点、交货时间 + And 上传相关采购文件 +Then 系统生成唯一订单号 + And 订单状态设置为"待确认" + And 发送通知给指定贸易商 +``` + +**详细需求**: +- 支持多种牛只品种选择(西门塔尔、安格斯、夏洛莱等) +- 重量范围可配置(如:300-400kg、400-500kg等) +- 支持批量订单创建 +- 订单模板功能,快速创建相似订单 +- 订单草稿保存功能 + +#### 3.1.2 供应商资质审核 +**用户故事**:As a 贸易商, I want to 审核供应商资质, so that 确保供应商具备合规供应能力 + +**验收标准**: +```gherkin +Given 贸易商查看供应商信息 +When 核实营业执照、动物防疫条件合格证等证件 + And 检查检疫证明开具能力 + And 评估供应商历史表现 +Then 系统记录审核结果 + And 更新供应商资质状态 + And 支持证件到期提醒功能 +``` + +### 3.2 装车前准备阶段 + +#### 3.2.1 车辆备案管理 +**用户故事**:As a 司机, I want to 完成车辆备案, so that 确保运输车辆符合运输要求 + +**验收标准**: +```gherkin +Given 司机准备装车 +When 上传空车过磅视频(时长≥30秒) + And 上传车辆消毒证明 + And 填写车辆基本信息(车牌号、载重等) +Then 系统验证视频完整性和清晰度 + And 驻场兽医在线确认消毒证明 + And 车辆状态更新为"已备案" +``` + +#### 3.2.2 牛只核验管理 +**用户故事**:As a 供应商, I want to 准备牛只核验, so that 确保牛只符合采购要求 + +**验收标准**: +```gherkin +Given 供应商准备装车 +When 提供《动物检疫合格证明》 + And 确保牛只空水空槽时间≥8小时 + And 上传牛只现场照片或视频 +Then 系统记录核验信息 + And 支持不同品种的重量区间验证 + And 生成装车准备清单 +``` + +### 3.3 运输交付阶段 + +#### 3.3.1 实时运输跟踪 +**用户故事**:As a 司机, I want to 实时上报运输状态, so that 让采购方及时了解运输进度 + +**验收标准**: +```gherkin +Given 司机在运输途中 +When 系统每10分钟自动获取GPS位置 + And 司机可手动上报牛只状态 + And 支持视频状态上报功能 +Then 系统记录完整运输轨迹 + And 计算预计到达时间 + And 异常情况自动告警 +``` + +#### 3.3.2 到货验收管理 +**用户故事**:As a 采购人, I want to 进行到货验收, so that 确保收到的牛只符合订单要求 + +**验收标准**: +```gherkin +Given 牛只到达目的地 +When 采购人在2小时内完成验收 + And 核对牛只数量、品种、重量 + And 检查牛只健康状况 +Then 系统记录验收结果 + And 支持异常情况记录(死亡、受伤、重量不符等) + And 生成验收报告 +``` + +### 3.4 结算支付阶段 + +#### 3.4.1 自动结算计算 +**用户故事**:As a 系统, I want to 自动计算结算金额, so that 减少人工计算错误 + +**验收标准**: +```gherkin +Given 验收完成 +When 系统获取实际上车重量和约定单价 +Then 自动计算:实际重量 × 单价 - 预付款 = 尾款 + And 生成详细结算清单 + And 支持多种计价方式(按头计价、按重量计价) +``` + +#### 3.4.2 在线支付处理 +**用户故事**:As a 采购人, I want to 在线支付尾款, so that 快速完成交易 + +**验收标准**: +```gherkin +Given 结算单已生成 +When 采购人确认结算金额 + And 选择支付方式(银行转账、支付宝、微信等) +Then 系统处理支付请求 + And 生成支付凭证 + And 更新订单状态为"已完成" +``` + +### 3.5 异常处理 + +#### 3.5.1 违约处理管理 +**用户故事**:As a 系统, I want to 自动处理违约情况, so that 规范化违约处理流程 + +**验收标准**: +```gherkin +Given 发生违约情况(延期交货、质量不符等) +When 系统识别违约类型和责任方 +Then 按合同约定计算违约金(每日合同金额0.5%) + And 生成违约处理单 + And 发送通知给相关方 +``` + +## 4. 非功能需求 + +### 4.1 性能要求 + +| 指标 | 要求 | 测试方法 | +|------|------|----------| +| 响应时间 | 页面加载 < 2秒,API响应 < 1秒 | 性能测试工具 | +| 并发用户 | 支持100+用户同时在线 | 压力测试 | +| 数据处理 | 支持10万+订单数据查询 | 数据库性能测试 | +| 文件上传 | 视频文件上传 < 30秒 | 文件上传测试 | + +### 4.2 安全要求 + +| 安全项 | 要求 | 实现方式 | +|--------|------|----------| +| 数据传输 | HTTPS加密传输 | SSL证书配置 | +| 身份认证 | 多因素认证 | 手机验证码 + 密码 | +| 权限控制 | 基于角色的访问控制 | RBAC权限模型 | +| 数据备份 | 每日自动备份 | 数据库定时备份 | +| 操作日志 | 关键操作全记录 | 审计日志系统 | + +### 4.3 可靠性要求 + +| 可靠性指标 | 要求 | 保障措施 | +|-----------|------|----------| +| 系统可用性 | 99.9% | 集群部署 + 负载均衡 | +| 故障恢复 | < 30分钟 | 自动故障切换 | +| 数据一致性 | 事务完整性保证 | 数据库事务控制 | +| 容灾备份 | 异地备份 | 云端数据备份 | + +### 4.4 兼容性要求 + +| 兼容性类型 | 要求 | 支持范围 | +|-----------|------|----------| +| 浏览器兼容 | 主流浏览器支持 | Chrome、Firefox、Safari、Edge | +| 移动端兼容 | 响应式设计 | iOS、Android | +| 小程序兼容 | 微信小程序平台 | 微信小程序最新版本 | + +## 5. 小程序矩阵需求 + +### 5.1 小程序架构设计 + +系统采用多小程序架构,为不同用户角色提供专属应用: + +``` +┌─────────────────────────────────────────────────┐ +│ 小程序矩阵 │ +├─────────────┬─────────────┬─────────────┬─────────────┤ +│ 采购人小程序 │ 供应商小程序 │ 司机小程序 │ 内部员工小程序 │ +│ (client-mp) │(supplier-mp)│ (driver-mp) │ (staff-mp) │ +└─────────────┴─────────────┴─────────────┴─────────────┘ +``` + +### 5.2 采购人小程序 (client-mp) + +**核心功能需求**: +- **订单管理**:创建订单、查看订单列表、订单详情查看 +- **运输跟踪**:实时查看运输位置、预计到达时间 +- **验收管理**:扫码验收、异常记录、验收确认 +- **支付管理**:查看结算单、在线支付、支付记录 +- **供应商评价**:对供应商服务进行评价 + +**界面设计要求**: +- 简洁直观的订单列表,支持状态筛选 +- 地图式运输轨迹展示,实时更新位置 +- 扫码验收功能,快速录入验收信息 +- 支付流程简化,支持多种支付方式 + +### 5.3 供应商小程序 (supplier-mp) + +**核心功能需求**: +- **订单处理**:接收订单、确认订单、订单状态更新 +- **牛只管理**:牛只信息录入、库存管理、质量记录 +- **证件管理**:检疫证明上传、证件到期提醒 +- **装车管理**:装车视频录制、装车清单确认 +- **财务查看**:结算记录查看、收款确认 + +**界面设计要求**: +- 订单状态可视化展示,清晰的流程指引 +- 证件上传便捷操作,支持拍照和相册选择 +- 视频录制功能,支持实时录制和本地上传 +- 财务数据清晰展示,支持历史记录查询 + +### 5.4 司机小程序 (driver-mp) + +**核心功能需求**: +- **任务管理**:接收运输任务、任务状态更新 +- **位置上报**:自动GPS定位、手动位置上报 +- **状态记录**:牛只状态视频记录、异常情况上报 +- **路线导航**:集成地图导航功能 +- **单据管理**:运输单据拍照上传、电子签名 + +**界面设计要求**: +- 简洁的任务列表,突出当前任务 +- 一键式状态上报,减少操作步骤 +- 离线操作支持,网络恢复后自动同步 +- 紧急情况快速处理,一键求助功能 + +### 5.5 内部员工小程序 (staff-mp) + +**核心功能需求**: +- **全流程监控**:订单全生命周期监控 +- **数据统计**:业务数据统计分析 +- **用户管理**:用户信息管理、权限设置 +- **系统配置**:业务参数配置、规则设置 +- **异常处理**:异常订单处理、客服支持 + +**界面设计要求**: +- 数据驾驶舱式展示,关键指标一目了然 +- 多维度统计分析,支持图表展示 +- 实时监控预警,异常情况及时提醒 +- 管理操作便捷,支持批量操作 + +## 6. 原型设计说明 + +### 6.1 界面设计原则 + +- **简洁性**:界面简洁明了,突出核心功能 +- **一致性**:统一的设计语言和交互模式 +- **易用性**:符合用户操作习惯,学习成本低 +- **响应性**:适配不同屏幕尺寸和设备 + +### 6.2 关键界面元素 + +**管理后台界面**: +- **导航栏**:左侧菜单导航,支持收缩展开 +- **数据驾驶舱**:关键业务指标可视化展示 +- **列表页面**:统一的列表样式,支持搜索、筛选、分页 +- **详情页面**:信息层次清晰,操作按钮明显 +- **表单页面**:表单验证友好,支持自动保存 + +**小程序界面**: +- **底部导航**:主要功能模块快速切换 +- **卡片式设计**:信息模块化展示 +- **浮动按钮**:常用操作快速访问 +- **状态指示**:清晰的状态标识和进度展示 + +### 6.3 交互流程设计 + +**订单创建流程**: +``` +采购人登录 → 选择创建订单 → 填写订单信息 → 确认提交 → +等待贸易商确认 → 订单生效 → 通知供应商 +``` + +**运输跟踪流程**: +``` +司机接单 → 车辆备案 → 开始运输 → 实时位置上报 → +异常情况处理 → 到达目的地 → 验收确认 +``` + +**支付结算流程**: +``` +验收完成 → 系统自动计算 → 生成结算单 → 采购人确认 → +选择支付方式 → 完成支付 → 生成凭证 +``` + +## 7. 范围界定 + +### 7.1 本版本包含功能 + +**核心业务功能**: +- ✅ 活牛采购全流程数字化管理 +- ✅ 四类用户角色完整功能支持 +- ✅ 双订单流程(采购人→贸易商→供应商) +- ✅ 运输实时跟踪和状态上报 +- ✅ 自动化结算和支付处理 +- ✅ 小程序矩阵(4个专业小程序) +- ✅ 管理后台系统 +- ✅ 企业官网展示 + +**技术功能**: +- ✅ 用户认证和权限管理 +- ✅ 文件上传和存储 +- ✅ 实时通信和消息推送 +- ✅ 数据统计和报表 +- ✅ 系统监控和日志 + +### 7.2 本版本不包含功能 + +**业务功能限制**: +- ❌ 牛只养殖管理功能 +- ❌ 销售端功能模块 +- ❌ 复杂的财务核算功能 +- ❌ 多语言支持 +- ❌ 第三方ERP系统集成 +- ❌ 高级数据分析和AI功能 + +**技术功能限制**: +- ❌ 移动端原生APP +- ❌ 区块链技术应用 +- ❌ 大数据分析平台 +- ❌ 人工智能算法 + +## 8. 风险评估与应对 + +### 8.1 技术风险 + +| 风险项 | 风险等级 | 影响 | 应对措施 | +|--------|---------|------|----------| +| 数据库性能瓶颈 | 中 | 系统响应慢 | 数据库优化、读写分离 | +| 第三方服务依赖 | 中 | 功能不可用 | 备用方案、服务降级 | +| 安全漏洞 | 高 | 数据泄露 | 安全审计、渗透测试 | + +### 8.2 业务风险 + +| 风险项 | 风险等级 | 影响 | 应对措施 | +|--------|---------|------|----------| +| 用户接受度低 | 中 | 推广困难 | 用户培训、功能优化 | +| 行业政策变化 | 高 | 合规问题 | 政策跟踪、快速调整 | +| 竞争对手压力 | 中 | 市场份额 | 差异化竞争、功能创新 | + +## 9. 项目里程碑 + +### 9.1 开发计划 + +| 阶段 | 时间 | 主要交付物 | 负责人 | +|------|------|-----------|--------| +| 需求分析 | Week 1-2 | PRD文档、原型设计 | 产品经理 | +| 技术设计 | Week 3-4 | 技术方案、数据库设计 | 架构师 | +| 后端开发 | Week 5-8 | API接口、核心功能 | 后端团队 | +| 前端开发 | Week 6-10 | 管理后台、小程序 | 前端团队 | +| 测试验收 | Week 11-12 | 测试报告、Bug修复 | 测试团队 | +| 部署上线 | Week 13-14 | 生产环境部署 | 运维团队 | + +### 9.2 版本发布计划 + +- **v1.0 MVP版本**:核心功能实现,支持基本业务流程 +- **v1.1 优化版本**:性能优化,用户体验改进 +- **v2.0 增强版本**:高级功能,数据分析能力 +- **v3.0 智能版本**:AI功能,智能推荐 + +--- + +**文档维护**:本文档由产品团队负责维护,每月更新一次,重大变更及时更新。 + +**最后更新时间**:2024年12月20日 \ No newline at end of file diff --git a/docs/小程序开发指南.md b/docs/小程序开发指南.md new file mode 100644 index 0000000..cf0eb81 --- /dev/null +++ b/docs/小程序开发指南.md @@ -0,0 +1,1046 @@ +# 小程序开发指南 + +## 版本历史 + +| 版本 | 日期 | 修改人 | 修改内容 | +|------|------|--------|----------| +| 1.0.0 | 2024-01-20 | 开发团队 | 初始版本 | + +## 1. 小程序矩阵概述 + +### 1.1 小程序架构 + +本项目采用多小程序架构,包含四个独立的小程序: + +- **员工小程序 (staff-mp)**: 内部员工使用,管理订单、质检、运输等 +- **司机小程序 (driver-mp)**: 运输司机使用,管理运输任务和状态更新 +- **供应商小程序 (supplier-mp)**: 供应商使用,管理订单接收和牛只信息 +- **客户小程序 (client-mp)**: 客户使用,下单、查看订单状态等 + +### 1.2 技术栈 + +- **框架**: uni-app (Vue3 + TypeScript) +- **UI组件**: uView Plus +- **状态管理**: Pinia +- **HTTP请求**: uni.request 封装 +- **构建工具**: Vite + +## 2. 开发环境搭建 + +### 2.1 工具安装 + +```bash +# 安装 HBuilderX (推荐) +# 下载地址: https://www.dcloud.io/hbuilderx.html + +# 或使用 VS Code + uni-app 插件 +# 安装 uni-app 插件 +``` + +### 2.2 微信开发者工具 + +```bash +# 下载微信开发者工具 +# 下载地址: https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html + +# 配置小程序 AppID +# 在各小程序的 manifest.json 中配置对应的 AppID +``` + +### 2.3 项目初始化 + +```bash +# 进入小程序目录 +cd mini_program/staff-mp + +# 安装依赖 +npm install + +# 启动开发服务器 +npm run dev:mp-weixin +``` + +## 3. 项目结构详解 + +### 3.1 员工小程序 (staff-mp) + +``` +staff-mp/ +├── src/ +│ ├── pages/ # 页面 +│ │ ├── index/ # 首页 +│ │ ├── order/ # 订单管理 +│ │ │ ├── list.vue # 订单列表 +│ │ │ ├── detail.vue # 订单详情 +│ │ │ └── create.vue # 创建订单 +│ │ ├── quality/ # 质检管理 +│ │ ├── transport/ # 运输管理 +│ │ └── profile/ # 个人中心 +│ ├── components/ # 组件 +│ │ ├── OrderCard.vue # 订单卡片 +│ │ ├── QualityForm.vue # 质检表单 +│ │ └── StatusBadge.vue # 状态标签 +│ ├── api/ # API接口 +│ │ ├── order.ts # 订单接口 +│ │ ├── quality.ts # 质检接口 +│ │ └── transport.ts # 运输接口 +│ ├── stores/ # 状态管理 +│ │ ├── user.ts # 用户状态 +│ │ ├── order.ts # 订单状态 +│ │ └── app.ts # 应用状态 +│ ├── utils/ # 工具函数 +│ │ ├── request.ts # 请求封装 +│ │ ├── auth.ts # 认证工具 +│ │ └── format.ts # 格式化工具 +│ ├── static/ # 静态资源 +│ ├── App.vue # 应用入口 +│ ├── main.ts # 主文件 +│ └── pages.json # 页面配置 +├── package.json +└── tsconfig.json +``` + +### 3.2 司机小程序 (driver-mp) + +``` +driver-mp/ +├── src/ +│ ├── pages/ +│ │ ├── index/ # 首页 +│ │ ├── task/ # 运输任务 +│ │ │ ├── list.vue # 任务列表 +│ │ │ ├── detail.vue # 任务详情 +│ │ │ └── track.vue # 运输跟踪 +│ │ ├── vehicle/ # 车辆管理 +│ │ └── profile/ # 个人中心 +│ └── ... +``` + +### 3.3 供应商小程序 (supplier-mp) + +``` +supplier-mp/ +├── src/ +│ ├── pages/ +│ │ ├── index/ # 首页 +│ │ ├── order/ # 订单管理 +│ │ ├── cattle/ # 牛只管理 +│ │ └── profile/ # 个人中心 +│ └── ... +``` + +### 3.4 客户小程序 (client-mp) + +``` +client-mp/ +├── src/ +│ ├── pages/ +│ │ ├── index/ # 首页 +│ │ ├── order/ # 订单管理 +│ │ ├── payment/ # 支付管理 +│ │ └── profile/ # 个人中心 +│ └── ... +``` + +## 4. 开发规范 + +### 4.1 页面开发规范 + +#### 4.1.1 页面结构 + +```vue + + + + + +``` + +#### 4.1.2 组件开发规范 + +```vue + + + +``` + +### 4.2 API 调用规范 + +#### 4.2.1 请求封装 + +```typescript +// utils/request.ts +import { useUserStore } from '@/stores/user' + +interface RequestOptions { + url: string + method?: 'GET' | 'POST' | 'PUT' | 'DELETE' + data?: any + header?: Record +} + +export function request(options: RequestOptions): Promise { + const userStore = useUserStore() + + return new Promise((resolve, reject) => { + uni.request({ + url: `${import.meta.env.VITE_API_BASE_URL}${options.url}`, + method: options.method || 'GET', + data: options.data, + header: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${userStore.token}`, + ...options.header + }, + success: (res) => { + if (res.statusCode === 200) { + resolve(res.data as T) + } else { + reject(new Error(`请求失败: ${res.statusCode}`)) + } + }, + fail: (err) => { + reject(err) + } + }) + }) +} +``` + +#### 4.2.2 API 接口定义 + +```typescript +// api/order.ts +import { request } from '@/utils/request' + +export interface OrderListParams { + page: number + pageSize: number + status?: string +} + +export interface OrderInfo { + id: string + customerName: string + status: string + createTime: string + // 其他字段... +} + +// 获取订单列表 +export function getOrderList(params: OrderListParams) { + return request<{ + list: OrderInfo[] + total: number + }>({ + url: '/orders', + method: 'GET', + data: params + }) +} + +// 获取订单详情 +export function getOrderDetail(id: string) { + return request({ + url: `/orders/${id}`, + method: 'GET' + }) +} +``` + +### 4.3 状态管理规范 + +```typescript +// stores/order.ts +import { defineStore } from 'pinia' +import { ref } from 'vue' +import type { OrderInfo } from '@/api/order' + +export const useOrderStore = defineStore('order', () => { + const orderList = ref([]) + const currentOrder = ref(null) + const loading = ref(false) + + // 获取订单列表 + async function fetchOrderList(params: any) { + loading.value = true + try { + const { getOrderList } = await import('@/api/order') + const result = await getOrderList(params) + orderList.value = result.list + return result + } finally { + loading.value = false + } + } + + // 设置当前订单 + function setCurrentOrder(order: OrderInfo) { + currentOrder.value = order + } + + return { + orderList, + currentOrder, + loading, + fetchOrderList, + setCurrentOrder + } +}) +``` + +## 5. 页面开发指南 + +### 5.1 员工小程序页面 + +#### 5.1.1 订单管理页面 + +```vue + + + + +``` + +#### 5.1.2 质检管理页面 + +```vue + + + + +``` + +### 5.2 司机小程序页面 + +#### 5.2.1 运输任务页面 + +```vue + + + + +``` + +## 6. 组件开发 + +### 6.1 通用组件 + +#### 6.1.1 状态标签组件 + +```vue + + + + + + +``` + +#### 6.1.2 订单卡片组件 + +```vue + + + + + + +``` + +## 7. 工具函数 + +### 7.1 认证工具 + +```typescript +// utils/auth.ts +import { useUserStore } from '@/stores/user' + +// 检查登录状态 +export function checkAuth(): boolean { + const userStore = useUserStore() + return !!userStore.token +} + +// 跳转到登录页 +export function redirectToLogin() { + uni.navigateTo({ + url: '/pages/auth/login' + }) +} + +// 登出 +export function logout() { + const userStore = useUserStore() + userStore.clearUserInfo() + + uni.reLaunch({ + url: '/pages/auth/login' + }) +} + +// 微信登录 +export function wxLogin(): Promise { + return new Promise((resolve, reject) => { + uni.login({ + provider: 'weixin', + success: (res) => { + resolve(res.code) + }, + fail: (err) => { + reject(err) + } + }) + }) +} +``` + +### 7.2 格式化工具 + +```typescript +// utils/format.ts +import dayjs from 'dayjs' + +// 格式化时间 +export function formatTime(time: string | Date, format = 'YYYY-MM-DD HH:mm:ss'): string { + return dayjs(time).format(format) +} + +// 格式化金额 +export function formatMoney(amount: number): string { + return `¥${amount.toFixed(2)}` +} + +// 格式化手机号 +export function formatPhone(phone: string): string { + return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') +} + +// 格式化文件大小 +export function formatFileSize(size: number): string { + if (size < 1024) { + return `${size}B` + } else if (size < 1024 * 1024) { + return `${(size / 1024).toFixed(1)}KB` + } else { + return `${(size / (1024 * 1024)).toFixed(1)}MB` + } +} +``` + +## 8. 调试与测试 + +### 8.1 真机调试 + +```bash +# 生成预览二维码 +npm run build:mp-weixin +# 在微信开发者工具中预览 +``` + +### 8.2 性能监控 + +```typescript +// utils/performance.ts +export function trackPagePerformance(pageName: string) { + const startTime = Date.now() + + return { + end: () => { + const endTime = Date.now() + const duration = endTime - startTime + + console.log(`页面 ${pageName} 加载耗时: ${duration}ms`) + + // 上报性能数据 + // reportPerformance(pageName, duration) + } + } +} +``` + +### 8.3 错误监控 + +```typescript +// utils/error.ts +export function setupErrorHandler() { + // 全局错误处理 + uni.onError((error) => { + console.error('小程序错误:', error) + + // 上报错误信息 + // reportError(error) + }) + + // 未处理的 Promise 错误 + uni.onUnhandledRejection((event) => { + console.error('未处理的 Promise 错误:', event.reason) + + // 上报错误信息 + // reportError(event.reason) + }) +} +``` + +## 9. 发布部署 + +### 9.1 构建配置 + +```json +// package.json +{ + "scripts": { + "dev:mp-weixin": "uni -p mp-weixin", + "build:mp-weixin": "uni build -p mp-weixin", + "dev:h5": "uni -p h5", + "build:h5": "uni build -p h5" + } +} +``` + +### 9.2 发布流程 + +1. **代码检查** +```bash +npm run lint +npm run type-check +``` + +2. **构建生产版本** +```bash +npm run build:mp-weixin +``` + +3. **上传代码** +- 使用微信开发者工具上传代码 +- 填写版本号和更新说明 + +4. **提交审核** +- 在微信公众平台提交审核 +- 等待审核通过后发布 + +## 10. 常见问题 + +### 10.1 开发问题 + +**Q: 小程序白屏问题** +- 检查页面路径配置 +- 查看控制台错误信息 +- 确认组件引入是否正确 + +**Q: 网络请求失败** +- 检查域名配置 +- 确认 HTTPS 证书 +- 查看请求参数格式 + +### 10.2 性能问题 + +**Q: 页面加载慢** +- 优化图片大小 +- 减少组件层级 +- 使用分包加载 + +**Q: 内存占用高** +- 及时清理定时器 +- 避免内存泄漏 +- 优化数据结构 + +## 11. 联系信息 + +- **小程序开发**: miniprogram-dev@company.com +- **技术支持**: tech-support@company.com +- **文档维护**: docs@company.com + +## 相关文档 + +- [开发指南](./开发指南.md) +- [产品需求文档](./产品需求文档.md) +- [API接口文档](./API接口文档.md) +- [测试指南](./测试指南.md) \ No newline at end of file diff --git a/docs/开发指南.md b/docs/开发指南.md new file mode 100644 index 0000000..b9f6bdd --- /dev/null +++ b/docs/开发指南.md @@ -0,0 +1,349 @@ +# 开发指南 + +## 版本历史 + +| 版本 | 日期 | 修改人 | 修改内容 | +|------|------|--------|----------| +| 1.0.0 | 2024-01-20 | 开发团队 | 初始版本 | + +## 1. 开发环境搭建 + +### 1.1 系统要求 + +- **操作系统**: macOS 10.15+, Ubuntu 18.04+, Windows 10+ +- **Node.js**: 16.x 或更高版本 +- **MySQL**: 8.0 或更高版本 +- **Redis**: 6.0 或更高版本 +- **Git**: 2.20 或更高版本 + +### 1.2 开发工具推荐 + +- **IDE**: VS Code, WebStorm +- **数据库管理**: Navicat, DBeaver +- **API测试**: Postman, Insomnia +- **版本控制**: Git, SourceTree + +### 1.3 环境安装 + +#### 1.3.1 Node.js 环境 + +```bash +# 使用 nvm 管理 Node.js 版本 +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash +nvm install 18 +nvm use 18 +``` + +#### 1.3.2 数据库安装 + +```bash +# MySQL 安装 (macOS) +brew install mysql +brew services start mysql + +# Redis 安装 (macOS) +brew install redis +brew services start redis +``` + +#### 1.3.3 项目克隆与依赖安装 + +```bash +# 克隆项目 +git clone https://github.com/your-org/niumall.git +cd niumall + +# 安装后端依赖 +cd backend +npm install + +# 安装前端管理系统依赖 +cd ../admin-system +npm install + +# 安装小程序依赖 +cd ../mini_program/staff-mp +npm install +``` + +## 2. 项目结构 + +``` +niumall/ +├── backend/ # 后端服务 (Node.js) +│ ├── src/ +│ │ ├── controllers/ # 控制器 +│ │ ├── models/ # 数据模型 +│ │ ├── services/ # 业务逻辑 +│ │ ├── middleware/ # 中间件 +│ │ ├── routes/ # 路由配置 +│ │ └── utils/ # 工具函数 +│ └── package.json +├── admin-system/ # 前端管理系统 (Vue3 + TypeScript) +│ ├── src/ +│ │ ├── views/ # 页面组件 +│ │ ├── api/ # API服务 +│ │ ├── utils/ # 工具函数 +│ │ └── stores/ # 状态管理 +│ └── package.json +├── mini_program/ # 小程序矩阵 +│ ├── staff-mp/ # 员工小程序 +│ ├── driver-mp/ # 司机小程序 +│ ├── supplier-mp/ # 供应商小程序 +│ └── client-mp/ # 客户小程序 +├── go-backend/ # Go后端服务 (备选) +├── fastapi-backend/ # FastAPI后端服务 (备选) +├── website/ # 官方网站 +└── docs/ # 项目文档 +``` + +## 3. 开发流程 + +### 3.1 分支管理 + +采用 Git Flow 工作流: + +- **main**: 生产环境分支 +- **develop**: 开发环境分支 +- **feature/***: 功能开发分支 +- **hotfix/***: 紧急修复分支 +- **release/***: 发布准备分支 + +### 3.2 开发步骤 + +1. **创建功能分支** +```bash +git checkout develop +git pull origin develop +git checkout -b feature/订单管理优化 +``` + +2. **开发与提交** +```bash +# 开发完成后提交 +git add . +git commit -m "feat: 添加订单状态自动更新功能" +``` + +3. **代码审查** +```bash +# 推送到远程分支 +git push origin feature/订单管理优化 +# 在 GitHub/GitLab 创建 Pull Request +``` + +### 3.3 提交规范 + +使用 Conventional Commits 规范: + +- `feat`: 新功能 +- `fix`: 修复bug +- `docs`: 文档更新 +- `style`: 代码格式调整 +- `refactor`: 代码重构 +- `test`: 测试相关 +- `chore`: 构建过程或辅助工具的变动 + +## 4. 本地开发 + +### 4.1 环境配置 + +#### 4.1.1 后端配置 + +创建 `backend/.env` 文件: + +```env +# 数据库配置 +DB_HOST=localhost +DB_PORT=3306 +DB_NAME=niumall +DB_USER=root +DB_PASSWORD=your_password + +# Redis配置 +REDIS_HOST=localhost +REDIS_PORT=6379 + +# JWT配置 +JWT_SECRET=your_jwt_secret +JWT_EXPIRES_IN=7d + +# 微信小程序配置 +WECHAT_APP_ID=your_app_id +WECHAT_APP_SECRET=your_app_secret +``` + +#### 4.1.2 前端配置 + +创建 `admin-system/.env.development` 文件: + +```env +# API基础URL +VITE_API_BASE_URL=http://localhost:3000/api +VITE_UPLOAD_URL=http://localhost:3000/uploads +``` + +### 4.2 启动服务 + +#### 4.2.1 启动后端服务 + +```bash +cd backend +npm run dev +# 服务启动在 http://localhost:3000 +``` + +#### 4.2.2 启动前端管理系统 + +```bash +cd admin-system +npm run dev +# 服务启动在 http://localhost:5173 +``` + +#### 4.2.3 启动小程序开发 + +```bash +cd mini_program/staff-mp +# 使用微信开发者工具打开项目目录 +``` + +### 4.3 数据库初始化 + +```bash +# 创建数据库 +mysql -u root -p +CREATE DATABASE niumall CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +# 运行初始化脚本 +cd backend +node init_database.js +``` + +## 5. 代码规范 + +### 5.1 JavaScript/TypeScript 规范 + +- 使用 ESLint + Prettier 进行代码格式化 +- 遵循 Airbnb JavaScript 风格指南 +- 使用 TypeScript 进行类型检查 + +### 5.2 Vue 组件规范 + +- 使用 Composition API +- 组件命名采用 PascalCase +- Props 定义使用 TypeScript 接口 + +### 5.3 API 接口规范 + +- 遵循 RESTful 设计原则 +- 统一的响应格式 +- 完善的错误处理 + +## 6. 测试指南 + +### 6.1 单元测试 + +```bash +# 运行后端单元测试 +cd backend +npm test + +# 运行前端单元测试 +cd admin-system +npm run test:unit +``` + +### 6.2 API测试 + +使用 Postman 或 Insomnia 进行 API 测试,测试文件位于 `docs/api/` 目录。 + +## 7. 调试技巧 + +### 7.1 后端调试 + +- 使用 VS Code 调试配置 +- 查看日志文件 +- 使用 Postman 测试 API + +### 7.2 前端调试 + +- 使用浏览器开发者工具 +- Vue DevTools 扩展 +- 网络请求监控 + +### 7.3 小程序调试 + +- 微信开发者工具调试器 +- 真机调试 +- 性能监控 + +## 8. 常见问题 + +### 8.1 环境问题 + +**Q: 数据库连接失败** +```bash +# 检查数据库服务状态 +brew services list | grep mysql +# 重启数据库服务 +brew services restart mysql +``` + +**Q: 端口被占用** +```bash +# 查看端口占用 +lsof -i :3000 +# 杀死进程 +kill -9 +``` + +### 8.2 开发问题 + +**Q: 热重载不生效** +```bash +# 清除缓存重启 +rm -rf node_modules/.cache +npm run dev +``` + +**Q: 小程序真机预览失败** +- 检查网络连接 +- 确认域名配置 +- 查看控制台错误信息 + +## 9. 性能优化 + +### 9.1 后端优化 + +- 数据库查询优化 +- Redis 缓存策略 +- 异步处理优化 + +### 9.2 前端优化 + +- 代码分割 +- 懒加载 +- 图片优化 + +### 9.3 小程序优化 + +- 分包加载 +- 图片压缩 +- 请求合并 + +## 10. 联系信息 + +- **技术支持**: tech-support@company.com +- **开发团队**: dev-team@company.com +- **文档维护**: docs@company.com + +## 相关文档 + +- [项目总览](./项目总览.md) +- [产品需求文档](./产品需求文档.md) +- [系统架构设计](./系统架构设计.md) +- [API接口文档](./API接口文档.md) +- [数据库设计](./数据库设计.md) +- [部署运维指南](./部署运维指南.md) +- [测试指南](./测试指南.md) \ No newline at end of file diff --git a/docs/数据库设计.md b/docs/数据库设计.md new file mode 100644 index 0000000..449b31c --- /dev/null +++ b/docs/数据库设计.md @@ -0,0 +1,1059 @@ +# 活牛采购智能数字化系统 - 数据库设计 + +## 版本历史 +| 版本 | 日期 | 作者 | 变更说明 | +|------|------|------|----------| +| v1.0 | 2024-12-20 | 数据库架构师 | 初版数据库设计文档 | + +## 1. 数据库概览 + +### 1.1 设计原则 + +- **规范化设计**:遵循第三范式,减少数据冗余 +- **性能优化**:合理设计索引,优化查询性能 +- **扩展性**:支持业务扩展和数据增长 +- **一致性**:保证数据完整性和事务一致性 +- **安全性**:敏感数据加密存储 + +### 1.2 数据库架构 + +```mermaid +graph TB + A[应用层] --> B[数据访问层
Sequelize ORM] + B --> C[主数据库
MySQL Master] + B --> D[从数据库
MySQL Slave] + B --> E[缓存层
Redis] + B --> F[文件存储
MinIO] + + C --> G[用户数据] + C --> H[订单数据] + C --> I[运输数据] + C --> J[财务数据] + + E --> K[会话缓存] + E --> L[查询缓存] + E --> M[计数器缓存] +``` + +### 1.3 数据库配置 + +| 配置项 | 值 | 说明 | +|--------|----|----- | +| 数据库版本 | MySQL 8.0+ | 支持JSON字段、窗口函数等新特性 | +| 字符集 | utf8mb4 | 支持完整的UTF-8字符集,包括emoji | +| 排序规则 | utf8mb4_unicode_ci | 支持多语言排序 | +| 存储引擎 | InnoDB | 支持事务、外键约束 | +| 时区 | UTC | 统一使用UTC时间 | + +## 2. 数据表设计 + +### 2.1 用户管理模块 + +#### 2.1.1 用户基础表 (users) + +```sql +CREATE TABLE users ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID', + phone VARCHAR(20) UNIQUE NOT NULL COMMENT '手机号', + password VARCHAR(255) NOT NULL COMMENT '密码哈希', + name VARCHAR(100) NOT NULL COMMENT '姓名', + role ENUM('client', 'supplier', 'driver', 'trader', 'admin') NOT NULL COMMENT '用户角色', + status ENUM('active', 'inactive', 'banned') DEFAULT 'active' COMMENT '用户状态', + avatar VARCHAR(500) COMMENT '头像URL', + last_login_at TIMESTAMP NULL COMMENT '最后登录时间', + login_count INT DEFAULT 0 COMMENT '登录次数', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + INDEX idx_phone (phone), + INDEX idx_role (role), + INDEX idx_status (status), + INDEX idx_created_at (created_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户基础表'; +``` + +**字段说明**: +- `role`:用户角色,支持采购人、供应商、司机、贸易商、管理员 +- `status`:用户状态,支持激活、未激活、禁用 +- `password`:使用bcrypt加密存储 + +#### 2.1.2 用户详情表 (user_profiles) + +```sql +CREATE TABLE user_profiles ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '详情ID', + user_id BIGINT NOT NULL COMMENT '用户ID', + company_name VARCHAR(200) COMMENT '公司名称', + business_license VARCHAR(500) COMMENT '营业执照URL', + license_number VARCHAR(100) COMMENT '营业执照号', + legal_person VARCHAR(100) COMMENT '法人代表', + contact_address TEXT COMMENT '联系地址', + emergency_contact VARCHAR(100) COMMENT '紧急联系人', + emergency_phone VARCHAR(20) COMMENT '紧急联系电话', + bank_account VARCHAR(50) COMMENT '银行账号', + bank_name VARCHAR(200) COMMENT '开户银行', + tax_number VARCHAR(50) COMMENT '税号', + qualification_docs JSON COMMENT '资质文件JSON', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, + UNIQUE KEY uk_user_id (user_id), + INDEX idx_company_name (company_name), + INDEX idx_license_number (license_number) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户详情表'; +``` + +#### 2.1.3 用户认证表 (user_tokens) + +```sql +CREATE TABLE user_tokens ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 'Token ID', + user_id BIGINT NOT NULL COMMENT '用户ID', + token_type ENUM('access', 'refresh', 'reset_password') NOT NULL COMMENT 'Token类型', + token_hash VARCHAR(255) NOT NULL COMMENT 'Token哈希值', + expires_at TIMESTAMP NOT NULL COMMENT '过期时间', + is_revoked BOOLEAN DEFAULT FALSE COMMENT '是否已撤销', + device_info JSON COMMENT '设备信息', + ip_address VARCHAR(45) COMMENT 'IP地址', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, + INDEX idx_user_id (user_id), + INDEX idx_token_hash (token_hash), + INDEX idx_expires_at (expires_at), + INDEX idx_token_type (token_type) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户认证Token表'; +``` + +### 2.2 订单管理模块 + +#### 2.2.1 订单主表 (orders) + +```sql +CREATE TABLE orders ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '订单ID', + order_no VARCHAR(50) UNIQUE NOT NULL COMMENT '订单号', + client_id BIGINT NOT NULL COMMENT '采购人ID', + trader_id BIGINT COMMENT '贸易商ID', + supplier_id BIGINT COMMENT '供应商ID', + + -- 牛只信息 + cattle_type VARCHAR(50) NOT NULL COMMENT '牛只品种', + quantity INT NOT NULL COMMENT '数量(头)', + weight_range VARCHAR(50) COMMENT '重量范围', + estimated_weight DECIMAL(8,2) COMMENT '预估总重量(kg)', + actual_weight DECIMAL(8,2) COMMENT '实际总重量(kg)', + + -- 价格信息 + unit_price DECIMAL(10,2) NOT NULL COMMENT '单价(元/kg或元/头)', + price_type ENUM('per_kg', 'per_head') DEFAULT 'per_kg' COMMENT '计价方式', + total_amount DECIMAL(12,2) NOT NULL COMMENT '订单总金额', + prepaid_amount DECIMAL(12,2) DEFAULT 0 COMMENT '预付金额', + final_amount DECIMAL(12,2) COMMENT '最终结算金额', + + -- 交付信息 + pickup_address TEXT COMMENT '取货地址', + delivery_address TEXT NOT NULL COMMENT '交货地址', + pickup_time DATETIME COMMENT '取货时间', + delivery_time DATETIME COMMENT '要求交货时间', + actual_delivery_time DATETIME COMMENT '实际交货时间', + + -- 状态信息 + status ENUM('draft', 'pending', 'confirmed', 'preparing', 'loading', 'transporting', 'arrived', 'inspecting', 'accepted', 'completed', 'cancelled') DEFAULT 'draft' COMMENT '订单状态', + cancel_reason TEXT COMMENT '取消原因', + + -- 特殊要求 + special_requirements TEXT COMMENT '特殊要求', + quality_standards JSON COMMENT '质量标准JSON', + + -- 时间戳 + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + confirmed_at TIMESTAMP NULL COMMENT '确认时间', + completed_at TIMESTAMP NULL COMMENT '完成时间', + + FOREIGN KEY (client_id) REFERENCES users(id), + FOREIGN KEY (trader_id) REFERENCES users(id), + FOREIGN KEY (supplier_id) REFERENCES users(id), + + INDEX idx_order_no (order_no), + INDEX idx_client_id (client_id), + INDEX idx_trader_id (trader_id), + INDEX idx_supplier_id (supplier_id), + INDEX idx_status (status), + INDEX idx_created_at (created_at), + INDEX idx_delivery_time (delivery_time), + INDEX idx_cattle_type (cattle_type) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单主表'; +``` + +#### 2.2.2 订单状态变更记录表 (order_status_logs) + +```sql +CREATE TABLE order_status_logs ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '记录ID', + order_id BIGINT NOT NULL COMMENT '订单ID', + from_status VARCHAR(50) COMMENT '原状态', + to_status VARCHAR(50) NOT NULL COMMENT '新状态', + operator_id BIGINT COMMENT '操作人ID', + operator_role VARCHAR(50) COMMENT '操作人角色', + remark TEXT COMMENT '备注说明', + extra_data JSON COMMENT '额外数据', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + + FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE, + FOREIGN KEY (operator_id) REFERENCES users(id), + + INDEX idx_order_id (order_id), + INDEX idx_operator_id (operator_id), + INDEX idx_created_at (created_at), + INDEX idx_to_status (to_status) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单状态变更记录表'; +``` + +#### 2.2.3 订单附件表 (order_attachments) + +```sql +CREATE TABLE order_attachments ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '附件ID', + order_id BIGINT NOT NULL COMMENT '订单ID', + file_name VARCHAR(255) NOT NULL COMMENT '文件名', + file_url VARCHAR(500) NOT NULL COMMENT '文件URL', + file_type VARCHAR(50) NOT NULL COMMENT '文件类型', + file_size BIGINT COMMENT '文件大小(字节)', + attachment_type ENUM('contract', 'certificate', 'photo', 'video', 'other') NOT NULL COMMENT '附件类型', + uploader_id BIGINT NOT NULL COMMENT '上传人ID', + description TEXT COMMENT '文件描述', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + + FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE, + FOREIGN KEY (uploader_id) REFERENCES users(id), + + INDEX idx_order_id (order_id), + INDEX idx_attachment_type (attachment_type), + INDEX idx_uploader_id (uploader_id), + INDEX idx_created_at (created_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单附件表'; +``` + +### 2.3 运输管理模块 + +#### 2.3.1 运输任务表 (transport_tasks) + +```sql +CREATE TABLE transport_tasks ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '任务ID', + task_no VARCHAR(50) UNIQUE NOT NULL COMMENT '任务编号', + order_id BIGINT NOT NULL COMMENT '订单ID', + driver_id BIGINT NOT NULL COMMENT '司机ID', + + -- 车辆信息 + vehicle_no VARCHAR(20) NOT NULL COMMENT '车牌号', + vehicle_type VARCHAR(50) COMMENT '车辆类型', + vehicle_capacity DECIMAL(8,2) COMMENT '载重量(吨)', + driver_license VARCHAR(50) COMMENT '驾驶证号', + + -- 路线信息 + start_location VARCHAR(200) COMMENT '起始地点', + end_location VARCHAR(200) COMMENT '目的地点', + start_latitude DECIMAL(10,6) COMMENT '起始纬度', + start_longitude DECIMAL(10,6) COMMENT '起始经度', + end_latitude DECIMAL(10,6) COMMENT '目的纬度', + end_longitude DECIMAL(10,6) COMMENT '目的经度', + planned_distance DECIMAL(8,2) COMMENT '计划距离(公里)', + actual_distance DECIMAL(8,2) COMMENT '实际距离(公里)', + + -- 时间信息 + planned_start_time DATETIME COMMENT '计划开始时间', + actual_start_time DATETIME COMMENT '实际开始时间', + planned_end_time DATETIME COMMENT '计划结束时间', + actual_end_time DATETIME COMMENT '实际结束时间', + estimated_arrival_time DATETIME COMMENT '预计到达时间', + + -- 状态信息 + status ENUM('assigned', 'preparing', 'loading', 'started', 'transporting', 'arrived', 'unloading', 'completed', 'cancelled') DEFAULT 'assigned' COMMENT '任务状态', + + -- 运输费用 + transport_fee DECIMAL(10,2) COMMENT '运输费用', + fuel_cost DECIMAL(10,2) COMMENT '燃油费用', + toll_cost DECIMAL(10,2) COMMENT '过路费', + other_cost DECIMAL(10,2) COMMENT '其他费用', + + -- 备注信息 + notes TEXT COMMENT '备注', + cancel_reason TEXT COMMENT '取消原因', + + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + FOREIGN KEY (order_id) REFERENCES orders(id), + FOREIGN KEY (driver_id) REFERENCES users(id), + + INDEX idx_task_no (task_no), + INDEX idx_order_id (order_id), + INDEX idx_driver_id (driver_id), + INDEX idx_vehicle_no (vehicle_no), + INDEX idx_status (status), + INDEX idx_planned_start_time (planned_start_time), + INDEX idx_created_at (created_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='运输任务表'; +``` + +#### 2.3.2 位置跟踪表 (location_tracks) + +```sql +CREATE TABLE location_tracks ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '跟踪ID', + task_id BIGINT NOT NULL COMMENT '任务ID', + latitude DECIMAL(10,6) NOT NULL COMMENT '纬度', + longitude DECIMAL(10,6) NOT NULL COMMENT '经度', + altitude DECIMAL(8,2) COMMENT '海拔(米)', + accuracy DECIMAL(8,2) COMMENT '精度(米)', + speed DECIMAL(5,2) COMMENT '速度(km/h)', + direction DECIMAL(5,2) COMMENT '方向角(度)', + address VARCHAR(500) COMMENT '地址描述', + + -- 状态信息 + cattle_status ENUM('normal', 'stressed', 'sick', 'dead') DEFAULT 'normal' COMMENT '牛只状态', + temperature DECIMAL(4,1) COMMENT '温度(摄氏度)', + humidity DECIMAL(5,2) COMMENT '湿度(%)', + + -- 时间信息 + recorded_at TIMESTAMP NOT NULL COMMENT '记录时间', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + + FOREIGN KEY (task_id) REFERENCES transport_tasks(id) ON DELETE CASCADE, + + INDEX idx_task_id (task_id), + INDEX idx_recorded_at (recorded_at), + INDEX idx_location (latitude, longitude), + INDEX idx_cattle_status (cattle_status) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='位置跟踪表' +PARTITION BY RANGE (YEAR(recorded_at)) ( + PARTITION p2024 VALUES LESS THAN (2025), + PARTITION p2025 VALUES LESS THAN (2026), + PARTITION p_future VALUES LESS THAN MAXVALUE +); +``` + +#### 2.3.3 运输事件表 (transport_events) + +```sql +CREATE TABLE transport_events ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '事件ID', + task_id BIGINT NOT NULL COMMENT '任务ID', + event_type ENUM('loading_start', 'loading_complete', 'departure', 'rest_stop', 'refuel', 'accident', 'breakdown', 'arrival', 'unloading_start', 'unloading_complete', 'emergency') NOT NULL COMMENT '事件类型', + event_title VARCHAR(200) NOT NULL COMMENT '事件标题', + event_description TEXT COMMENT '事件描述', + + -- 位置信息 + latitude DECIMAL(10,6) COMMENT '事件发生纬度', + longitude DECIMAL(10,6) COMMENT '事件发生经度', + address VARCHAR(500) COMMENT '事件发生地址', + + -- 附件信息 + photos JSON COMMENT '照片URLs', + videos JSON COMMENT '视频URLs', + documents JSON COMMENT '文档URLs', + + -- 处理信息 + severity ENUM('low', 'medium', 'high', 'critical') DEFAULT 'low' COMMENT '严重程度', + is_resolved BOOLEAN DEFAULT FALSE COMMENT '是否已解决', + resolution TEXT COMMENT '解决方案', + resolver_id BIGINT COMMENT '处理人ID', + resolved_at TIMESTAMP NULL COMMENT '解决时间', + + reporter_id BIGINT NOT NULL COMMENT '报告人ID', + occurred_at TIMESTAMP NOT NULL COMMENT '发生时间', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + FOREIGN KEY (task_id) REFERENCES transport_tasks(id) ON DELETE CASCADE, + FOREIGN KEY (reporter_id) REFERENCES users(id), + FOREIGN KEY (resolver_id) REFERENCES users(id), + + INDEX idx_task_id (task_id), + INDEX idx_event_type (event_type), + INDEX idx_severity (severity), + INDEX idx_is_resolved (is_resolved), + INDEX idx_occurred_at (occurred_at), + INDEX idx_reporter_id (reporter_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='运输事件表'; +``` + +### 2.4 质量管理模块 + +#### 2.4.1 牛只信息表 (cattle_info) + +```sql +CREATE TABLE cattle_info ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '牛只ID', + order_id BIGINT NOT NULL COMMENT '订单ID', + supplier_id BIGINT NOT NULL COMMENT '供应商ID', + + -- 基本信息 + cattle_no VARCHAR(50) COMMENT '牛只编号', + breed VARCHAR(50) NOT NULL COMMENT '品种', + gender ENUM('male', 'female') NOT NULL COMMENT '性别', + age_months INT COMMENT '月龄', + weight DECIMAL(6,2) COMMENT '重量(kg)', + height DECIMAL(5,2) COMMENT '体高(cm)', + body_length DECIMAL(5,2) COMMENT '体长(cm)', + + -- 健康信息 + health_status ENUM('healthy', 'sick', 'quarantine', 'dead') DEFAULT 'healthy' COMMENT '健康状态', + vaccination_records JSON COMMENT '疫苗记录', + medical_history JSON COMMENT '病史记录', + quarantine_certificate VARCHAR(500) COMMENT '检疫证明URL', + + -- 质量评级 + quality_grade ENUM('A', 'B', 'C', 'D') COMMENT '质量等级', + meat_quality_score DECIMAL(3,1) COMMENT '肉质评分', + appearance_score DECIMAL(3,1) COMMENT '外观评分', + health_score DECIMAL(3,1) COMMENT '健康评分', + + -- 来源信息 + origin_farm VARCHAR(200) COMMENT '来源农场', + origin_address TEXT COMMENT '来源地址', + birth_date DATE COMMENT '出生日期', + parent_info JSON COMMENT '父母信息', + + -- 状态信息 + status ENUM('registered', 'prepared', 'loaded', 'transported', 'delivered', 'accepted', 'rejected') DEFAULT 'registered' COMMENT '状态', + + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE, + FOREIGN KEY (supplier_id) REFERENCES users(id), + + INDEX idx_order_id (order_id), + INDEX idx_supplier_id (supplier_id), + INDEX idx_cattle_no (cattle_no), + INDEX idx_breed (breed), + INDEX idx_health_status (health_status), + INDEX idx_quality_grade (quality_grade), + INDEX idx_status (status) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='牛只信息表'; +``` + +#### 2.4.2 质量检验记录表 (quality_inspections) + +```sql +CREATE TABLE quality_inspections ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '检验ID', + order_id BIGINT NOT NULL COMMENT '订单ID', + inspector_id BIGINT NOT NULL COMMENT '检验员ID', + inspection_type ENUM('pre_loading', 'during_transport', 'post_delivery') NOT NULL COMMENT '检验类型', + + -- 检验结果 + total_count INT NOT NULL COMMENT '总数量', + qualified_count INT NOT NULL COMMENT '合格数量', + unqualified_count INT NOT NULL COMMENT '不合格数量', + dead_count INT DEFAULT 0 COMMENT '死亡数量', + sick_count INT DEFAULT 0 COMMENT '患病数量', + + -- 重量信息 + total_weight DECIMAL(8,2) COMMENT '总重量', + average_weight DECIMAL(6,2) COMMENT '平均重量', + weight_variance DECIMAL(6,2) COMMENT '重量方差', + + -- 质量评估 + overall_grade ENUM('A', 'B', 'C', 'D') COMMENT '整体等级', + quality_score DECIMAL(4,2) COMMENT '质量评分', + health_score DECIMAL(4,2) COMMENT '健康评分', + appearance_score DECIMAL(4,2) COMMENT '外观评分', + + -- 检验详情 + inspection_items JSON COMMENT '检验项目详情', + defect_details JSON COMMENT '缺陷详情', + photos JSON COMMENT '检验照片', + videos JSON COMMENT '检验视频', + + -- 结论 + is_passed BOOLEAN NOT NULL COMMENT '是否通过检验', + rejection_reason TEXT COMMENT '拒收原因', + recommendations TEXT COMMENT '建议', + + inspection_date DATETIME NOT NULL COMMENT '检验时间', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE, + FOREIGN KEY (inspector_id) REFERENCES users(id), + + INDEX idx_order_id (order_id), + INDEX idx_inspector_id (inspector_id), + INDEX idx_inspection_type (inspection_type), + INDEX idx_is_passed (is_passed), + INDEX idx_inspection_date (inspection_date), + INDEX idx_overall_grade (overall_grade) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='质量检验记录表'; +``` + +### 2.5 财务管理模块 + +#### 2.5.1 财务结算表 (financial_settlements) + +```sql +CREATE TABLE financial_settlements ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '结算ID', + settlement_no VARCHAR(50) UNIQUE NOT NULL COMMENT '结算单号', + order_id BIGINT NOT NULL COMMENT '订单ID', + + -- 结算金额 + order_amount DECIMAL(12,2) NOT NULL COMMENT '订单金额', + prepaid_amount DECIMAL(12,2) DEFAULT 0 COMMENT '预付金额', + transport_fee DECIMAL(10,2) DEFAULT 0 COMMENT '运输费用', + insurance_fee DECIMAL(10,2) DEFAULT 0 COMMENT '保险费用', + service_fee DECIMAL(10,2) DEFAULT 0 COMMENT '服务费', + penalty_amount DECIMAL(10,2) DEFAULT 0 COMMENT '违约金', + discount_amount DECIMAL(10,2) DEFAULT 0 COMMENT '优惠金额', + tax_amount DECIMAL(10,2) DEFAULT 0 COMMENT '税费', + final_amount DECIMAL(12,2) NOT NULL COMMENT '最终结算金额', + + -- 结算方式 + settlement_type ENUM('full_payment', 'partial_payment', 'installment') DEFAULT 'full_payment' COMMENT '结算方式', + payment_terms VARCHAR(200) COMMENT '付款条件', + + -- 状态信息 + status ENUM('draft', 'pending', 'approved', 'paid', 'cancelled') DEFAULT 'draft' COMMENT '结算状态', + + -- 审批信息 + approver_id BIGINT COMMENT '审批人ID', + approved_at TIMESTAMP NULL COMMENT '审批时间', + approval_notes TEXT COMMENT '审批备注', + + -- 时间信息 + settlement_date DATE NOT NULL COMMENT '结算日期', + due_date DATE COMMENT '付款截止日期', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + FOREIGN KEY (order_id) REFERENCES orders(id), + FOREIGN KEY (approver_id) REFERENCES users(id), + + INDEX idx_settlement_no (settlement_no), + INDEX idx_order_id (order_id), + INDEX idx_status (status), + INDEX idx_settlement_date (settlement_date), + INDEX idx_due_date (due_date), + INDEX idx_approver_id (approver_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='财务结算表'; +``` + +#### 2.5.2 支付记录表 (payment_records) + +```sql +CREATE TABLE payment_records ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '支付ID', + payment_no VARCHAR(50) UNIQUE NOT NULL COMMENT '支付单号', + settlement_id BIGINT NOT NULL COMMENT '结算ID', + order_id BIGINT NOT NULL COMMENT '订单ID', + payer_id BIGINT NOT NULL COMMENT '付款人ID', + payee_id BIGINT NOT NULL COMMENT '收款人ID', + + -- 支付金额 + payment_amount DECIMAL(12,2) NOT NULL COMMENT '支付金额', + currency VARCHAR(10) DEFAULT 'CNY' COMMENT '货币类型', + + -- 支付方式 + payment_method ENUM('bank_transfer', 'alipay', 'wechat_pay', 'cash', 'check', 'other') NOT NULL COMMENT '支付方式', + payment_channel VARCHAR(100) COMMENT '支付渠道', + + -- 第三方支付信息 + third_party_order_no VARCHAR(100) COMMENT '第三方订单号', + third_party_transaction_id VARCHAR(100) COMMENT '第三方交易ID', + + -- 银行信息 + payer_bank_account VARCHAR(50) COMMENT '付款账户', + payer_bank_name VARCHAR(200) COMMENT '付款银行', + payee_bank_account VARCHAR(50) COMMENT '收款账户', + payee_bank_name VARCHAR(200) COMMENT '收款银行', + + -- 状态信息 + status ENUM('pending', 'processing', 'success', 'failed', 'cancelled', 'refunded') DEFAULT 'pending' COMMENT '支付状态', + failure_reason TEXT COMMENT '失败原因', + + -- 时间信息 + payment_time DATETIME COMMENT '支付时间', + confirmed_time DATETIME COMMENT '确认时间', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + -- 备注信息 + notes TEXT COMMENT '支付备注', + receipt_url VARCHAR(500) COMMENT '支付凭证URL', + + FOREIGN KEY (settlement_id) REFERENCES financial_settlements(id), + FOREIGN KEY (order_id) REFERENCES orders(id), + FOREIGN KEY (payer_id) REFERENCES users(id), + FOREIGN KEY (payee_id) REFERENCES users(id), + + INDEX idx_payment_no (payment_no), + INDEX idx_settlement_id (settlement_id), + INDEX idx_order_id (order_id), + INDEX idx_payer_id (payer_id), + INDEX idx_payee_id (payee_id), + INDEX idx_status (status), + INDEX idx_payment_method (payment_method), + INDEX idx_payment_time (payment_time), + INDEX idx_third_party_order_no (third_party_order_no) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='支付记录表'; +``` + +### 2.6 系统管理模块 + +#### 2.6.1 系统配置表 (system_configs) + +```sql +CREATE TABLE system_configs ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '配置ID', + config_key VARCHAR(100) UNIQUE NOT NULL COMMENT '配置键', + config_value TEXT NOT NULL COMMENT '配置值', + config_type ENUM('string', 'number', 'boolean', 'json', 'array') DEFAULT 'string' COMMENT '配置类型', + category VARCHAR(50) NOT NULL COMMENT '配置分类', + description TEXT COMMENT '配置描述', + is_public BOOLEAN DEFAULT FALSE COMMENT '是否公开配置', + is_editable BOOLEAN DEFAULT TRUE COMMENT '是否可编辑', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + INDEX idx_config_key (config_key), + INDEX idx_category (category), + INDEX idx_is_public (is_public) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统配置表'; +``` + +#### 2.6.2 操作日志表 (operation_logs) + +```sql +CREATE TABLE operation_logs ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '日志ID', + user_id BIGINT COMMENT '操作用户ID', + username VARCHAR(100) COMMENT '用户名', + user_role VARCHAR(50) COMMENT '用户角色', + + -- 操作信息 + operation_type VARCHAR(50) NOT NULL COMMENT '操作类型', + operation_module VARCHAR(50) NOT NULL COMMENT '操作模块', + operation_description TEXT COMMENT '操作描述', + + -- 请求信息 + request_method VARCHAR(10) COMMENT '请求方法', + request_url VARCHAR(500) COMMENT '请求URL', + request_params JSON COMMENT '请求参数', + request_body JSON COMMENT '请求体', + + -- 响应信息 + response_status INT COMMENT '响应状态码', + response_data JSON COMMENT '响应数据', + + -- 环境信息 + ip_address VARCHAR(45) COMMENT 'IP地址', + user_agent TEXT COMMENT '用户代理', + device_info JSON COMMENT '设备信息', + + -- 时间信息 + execution_time INT COMMENT '执行时间(毫秒)', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + + FOREIGN KEY (user_id) REFERENCES users(id), + + INDEX idx_user_id (user_id), + INDEX idx_operation_type (operation_type), + INDEX idx_operation_module (operation_module), + INDEX idx_ip_address (ip_address), + INDEX idx_created_at (created_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='操作日志表' +PARTITION BY RANGE (YEAR(created_at)) ( + PARTITION p2024 VALUES LESS THAN (2025), + PARTITION p2025 VALUES LESS THAN (2026), + PARTITION p_future VALUES LESS THAN MAXVALUE +); +``` + +#### 2.6.3 消息通知表 (notifications) + +```sql +CREATE TABLE notifications ( + id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '通知ID', + recipient_id BIGINT NOT NULL COMMENT '接收人ID', + sender_id BIGINT COMMENT '发送人ID', + + -- 通知内容 + title VARCHAR(200) NOT NULL COMMENT '通知标题', + content TEXT NOT NULL COMMENT '通知内容', + notification_type ENUM('system', 'order', 'transport', 'payment', 'quality', 'emergency') NOT NULL COMMENT '通知类型', + priority ENUM('low', 'medium', 'high', 'urgent') DEFAULT 'medium' COMMENT '优先级', + + -- 关联信息 + related_type VARCHAR(50) COMMENT '关联类型', + related_id BIGINT COMMENT '关联ID', + + -- 发送渠道 + channels JSON COMMENT '发送渠道(app, sms, email, wechat)', + + -- 状态信息 + is_read BOOLEAN DEFAULT FALSE COMMENT '是否已读', + read_at TIMESTAMP NULL COMMENT '阅读时间', + is_sent BOOLEAN DEFAULT FALSE COMMENT '是否已发送', + sent_at TIMESTAMP NULL COMMENT '发送时间', + + -- 时间信息 + scheduled_at TIMESTAMP COMMENT '计划发送时间', + expires_at TIMESTAMP COMMENT '过期时间', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + + FOREIGN KEY (recipient_id) REFERENCES users(id), + FOREIGN KEY (sender_id) REFERENCES users(id), + + INDEX idx_recipient_id (recipient_id), + INDEX idx_sender_id (sender_id), + INDEX idx_notification_type (notification_type), + INDEX idx_priority (priority), + INDEX idx_is_read (is_read), + INDEX idx_is_sent (is_sent), + INDEX idx_created_at (created_at), + INDEX idx_scheduled_at (scheduled_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='消息通知表'; +``` + +## 3. 数据库关系图 + +```mermaid +erDiagram + users ||--o{ user_profiles : "1:1" + users ||--o{ user_tokens : "1:N" + users ||--o{ orders : "client_id" + users ||--o{ orders : "trader_id" + users ||--o{ orders : "supplier_id" + users ||--o{ transport_tasks : "driver_id" + users ||--o{ operation_logs : "user_id" + users ||--o{ notifications : "recipient_id" + + orders ||--o{ order_status_logs : "1:N" + orders ||--o{ order_attachments : "1:N" + orders ||--o{ transport_tasks : "1:N" + orders ||--o{ cattle_info : "1:N" + orders ||--o{ quality_inspections : "1:N" + orders ||--o{ financial_settlements : "1:1" + orders ||--o{ payment_records : "1:N" + + transport_tasks ||--o{ location_tracks : "1:N" + transport_tasks ||--o{ transport_events : "1:N" + + financial_settlements ||--o{ payment_records : "1:N" + + users { + bigint id PK + varchar phone UK + varchar password + varchar name + enum role + enum status + varchar avatar + timestamp created_at + timestamp updated_at + } + + orders { + bigint id PK + varchar order_no UK + bigint client_id FK + bigint trader_id FK + bigint supplier_id FK + varchar cattle_type + int quantity + decimal unit_price + decimal total_amount + enum status + timestamp created_at + timestamp updated_at + } + + transport_tasks { + bigint id PK + varchar task_no UK + bigint order_id FK + bigint driver_id FK + varchar vehicle_no + varchar start_location + varchar end_location + enum status + timestamp created_at + timestamp updated_at + } + + location_tracks { + bigint id PK + bigint task_id FK + decimal latitude + decimal longitude + decimal speed + timestamp recorded_at + timestamp created_at + } +``` + +## 4. 索引优化策略 + +### 4.1 主要索引设计 + +#### 4.1.1 单列索引 +```sql +-- 用户表索引 +CREATE INDEX idx_users_phone ON users(phone); +CREATE INDEX idx_users_role ON users(role); +CREATE INDEX idx_users_status ON users(status); + +-- 订单表索引 +CREATE INDEX idx_orders_status ON orders(status); +CREATE INDEX idx_orders_created_at ON orders(created_at); +CREATE INDEX idx_orders_cattle_type ON orders(cattle_type); +``` + +#### 4.1.2 复合索引 +```sql +-- 订单查询优化 +CREATE INDEX idx_orders_client_status ON orders(client_id, status); +CREATE INDEX idx_orders_supplier_status ON orders(supplier_id, status); +CREATE INDEX idx_orders_status_created ON orders(status, created_at); + +-- 位置跟踪查询优化 +CREATE INDEX idx_location_task_time ON location_tracks(task_id, recorded_at); +CREATE INDEX idx_location_time_status ON location_tracks(recorded_at, cattle_status); + +-- 支付记录查询优化 +CREATE INDEX idx_payment_payer_status ON payment_records(payer_id, status); +CREATE INDEX idx_payment_method_time ON payment_records(payment_method, payment_time); +``` + +#### 4.1.3 覆盖索引 +```sql +-- 订单列表查询覆盖索引 +CREATE INDEX idx_orders_list_cover ON orders(status, client_id, created_at, order_no, cattle_type, total_amount); + +-- 用户基本信息覆盖索引 +CREATE INDEX idx_users_basic_cover ON users(id, name, role, status, avatar); +``` + +### 4.2 分区策略 + +#### 4.2.1 时间分区 +```sql +-- 位置跟踪表按年分区 +ALTER TABLE location_tracks PARTITION BY RANGE (YEAR(recorded_at)) ( + PARTITION p2024 VALUES LESS THAN (2025), + PARTITION p2025 VALUES LESS THAN (2026), + PARTITION p2026 VALUES LESS THAN (2027), + PARTITION p_future VALUES LESS THAN MAXVALUE +); + +-- 操作日志表按月分区 +ALTER TABLE operation_logs PARTITION BY RANGE (YEAR(created_at) * 100 + MONTH(created_at)) ( + PARTITION p202401 VALUES LESS THAN (202402), + PARTITION p202402 VALUES LESS THAN (202403), + -- ... 其他月份分区 + PARTITION p_future VALUES LESS THAN MAXVALUE +); +``` + +## 5. 数据库安全策略 + +### 5.1 访问控制 + +#### 5.1.1 用户权限设计 +```sql +-- 应用程序数据库用户 +CREATE USER 'niumall_app'@'%' IDENTIFIED BY 'strong_password_123!'; +GRANT SELECT, INSERT, UPDATE, DELETE ON niumall.* TO 'niumall_app'@'%'; + +-- 只读用户(用于报表和分析) +CREATE USER 'niumall_readonly'@'%' IDENTIFIED BY 'readonly_password_123!'; +GRANT SELECT ON niumall.* TO 'niumall_readonly'@'%'; + +-- 备份用户 +CREATE USER 'niumall_backup'@'localhost' IDENTIFIED BY 'backup_password_123!'; +GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON niumall.* TO 'niumall_backup'@'localhost'; +``` + +#### 5.1.2 敏感数据加密 +```sql +-- 用户密码加密存储(应用层处理) +-- 银行账号加密存储 +-- 身份证号加密存储 +-- 手机号部分加密显示 +``` + +### 5.2 数据备份策略 + +#### 5.2.1 备份计划 +```bash +#!/bin/bash +# 每日全量备份脚本 +DATE=$(date +%Y%m%d_%H%M%S) +BACKUP_DIR="/backup/mysql" +DB_NAME="niumall" + +# 全量备份 +mysqldump -u niumall_backup -p${BACKUP_PASSWORD} \ + --single-transaction \ + --routines \ + --triggers \ + --events \ + ${DB_NAME} > ${BACKUP_DIR}/niumall_full_${DATE}.sql + +# 压缩备份文件 +gzip ${BACKUP_DIR}/niumall_full_${DATE}.sql + +# 删除7天前的备份文件 +find ${BACKUP_DIR} -name "niumall_full_*.sql.gz" -mtime +7 -delete +``` + +#### 5.2.2 恢复测试 +```bash +#!/bin/bash +# 备份恢复测试脚本 +TEST_DB="niumall_test" +BACKUP_FILE="niumall_full_20241220_120000.sql.gz" + +# 创建测试数据库 +mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS ${TEST_DB};" + +# 恢复数据 +zcat ${BACKUP_FILE} | mysql -u root -p ${TEST_DB} + +# 验证数据完整性 +mysql -u root -p ${TEST_DB} -e "SELECT COUNT(*) FROM users;" +mysql -u root -p ${TEST_DB} -e "SELECT COUNT(*) FROM orders;" +``` + +## 6. 性能监控与优化 + +### 6.1 慢查询监控 + +#### 6.1.1 慢查询配置 +```sql +-- 启用慢查询日志 +SET GLOBAL slow_query_log = 'ON'; +SET GLOBAL long_query_time = 1; +SET GLOBAL log_queries_not_using_indexes = 'ON'; +``` + +#### 6.1.2 常见慢查询优化 +```sql +-- 优化前:全表扫描 +SELECT * FROM orders WHERE created_at > '2024-01-01'; + +-- 优化后:使用索引 +SELECT id, order_no, client_id, status, created_at +FROM orders +WHERE created_at > '2024-01-01' +ORDER BY created_at DESC +LIMIT 100; + +-- 添加索引 +CREATE INDEX idx_orders_created_at ON orders(created_at); +``` + +### 6.2 数据库监控指标 + +| 监控指标 | 正常范围 | 告警阈值 | 处理建议 | +|---------|---------|---------|----------| +| 连接数 | < 80% | > 90% | 检查连接池配置 | +| CPU使用率 | < 70% | > 85% | 优化查询,增加资源 | +| 内存使用率 | < 80% | > 90% | 调整缓存配置 | +| 磁盘使用率 | < 80% | > 90% | 清理日志,扩容 | +| 慢查询数量 | < 10/小时 | > 50/小时 | 优化SQL语句 | +| 锁等待时间 | < 1秒 | > 5秒 | 优化事务逻辑 | + +## 7. 数据迁移与版本管理 + +### 7.1 数据库版本控制 + +#### 7.1.1 迁移脚本示例 +```sql +-- V1.0.0__Initial_schema.sql +-- 创建初始表结构 + +-- V1.0.1__Add_user_profiles.sql +-- 添加用户详情表 + +-- V1.1.0__Add_transport_module.sql +-- 添加运输管理模块 + +-- V1.1.1__Add_location_tracking.sql +-- 添加位置跟踪功能 +``` + +#### 7.1.2 数据迁移脚本 +```sql +-- 用户数据迁移示例 +INSERT INTO users (phone, password, name, role, status, created_at) +SELECT + old_phone, + old_password_hash, + old_username, + CASE old_user_type + WHEN 1 THEN 'client' + WHEN 2 THEN 'supplier' + WHEN 3 THEN 'driver' + ELSE 'admin' + END, + CASE old_status + WHEN 1 THEN 'active' + ELSE 'inactive' + END, + old_create_time +FROM old_user_table +WHERE old_phone IS NOT NULL; +``` + +### 7.2 数据一致性检查 + +#### 7.2.1 数据完整性验证 +```sql +-- 检查外键约束 +SELECT + TABLE_NAME, + CONSTRAINT_NAME, + REFERENCED_TABLE_NAME +FROM information_schema.KEY_COLUMN_USAGE +WHERE REFERENCED_TABLE_SCHEMA = 'niumall' +AND REFERENCED_TABLE_NAME IS NOT NULL; + +-- 检查数据一致性 +SELECT + o.id, + o.order_no, + o.client_id, + u.name as client_name +FROM orders o +LEFT JOIN users u ON o.client_id = u.id +WHERE u.id IS NULL; +``` + +#### 7.2.2 数据质量监控 +```sql +-- 检查重复数据 +SELECT phone, COUNT(*) as count +FROM users +GROUP BY phone +HAVING COUNT(*) > 1; + +-- 检查空值数据 +SELECT + COUNT(*) as total_orders, + COUNT(client_id) as orders_with_client, + COUNT(supplier_id) as orders_with_supplier +FROM orders; +``` + +--- + +**文档维护**:本文档由数据库团队负责维护,数据库结构变更时及时更新。 + +**最后更新时间**:2024年12月20日 \ No newline at end of file diff --git a/docs/测试指南.md b/docs/测试指南.md new file mode 100644 index 0000000..82fc321 --- /dev/null +++ b/docs/测试指南.md @@ -0,0 +1,1181 @@ +# 活牛采购智能数字化系统 - 测试指南 + +## 版本历史 +| 版本 | 日期 | 作者 | 变更说明 | +|------|------|------|----------| +| v1.0 | 2024-12-20 | 测试团队 | 初版测试指南 | + +## 1. 测试概述 + +### 1.1 测试策略 + +本系统采用多层次测试策略,确保系统质量和稳定性: + +- **单元测试**: 测试单个函数和模块 +- **集成测试**: 测试模块间的交互 +- **API测试**: 测试接口功能和性能 +- **端到端测试**: 测试完整业务流程 +- **性能测试**: 测试系统性能和负载能力 +- **安全测试**: 测试系统安全性 + +### 1.2 测试环境 + +#### 测试环境配置 +```bash +# 测试环境要求 +Node.js >= 18.0.0 +MySQL >= 8.0 (测试数据库) +Redis >= 6.0 (测试缓存) +Docker >= 20.10 (容器测试) +``` + +#### 测试数据库配置 +```sql +-- 创建测试数据库 +CREATE DATABASE niumall_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- 创建测试用户 +CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'test_password'; +GRANT ALL PRIVILEGES ON niumall_test.* TO 'test_user'@'localhost'; +FLUSH PRIVILEGES; +``` + +## 2. 单元测试 + +### 2.1 测试框架配置 + +#### Jest配置文件 +```javascript +// jest.config.js +module.exports = { + testEnvironment: 'node', + roots: ['/src', '/tests'], + testMatch: [ + '**/__tests__/**/*.js', + '**/?(*.)+(spec|test).js' + ], + collectCoverageFrom: [ + 'src/**/*.js', + '!src/**/*.test.js', + '!src/config/**', + '!src/migrations/**' + ], + coverageDirectory: 'coverage', + coverageReporters: ['text', 'lcov', 'html'], + setupFilesAfterEnv: ['/tests/setup.js'], + testTimeout: 10000, + verbose: true +}; +``` + +#### 测试环境配置 +```javascript +// tests/setup.js +const { sequelize } = require('../src/models'); + +// 测试前设置 +beforeAll(async () => { + // 连接测试数据库 + await sequelize.authenticate(); + + // 同步数据库结构 + await sequelize.sync({ force: true }); +}); + +// 测试后清理 +afterAll(async () => { + // 关闭数据库连接 + await sequelize.close(); +}); + +// 每个测试前清理数据 +beforeEach(async () => { + // 清理测试数据 + await sequelize.truncate({ cascade: true }); +}); +``` + +### 2.2 模型测试 + +#### 用户模型测试 +```javascript +// tests/models/user.test.js +const { User } = require('../../src/models'); + +describe('User Model', () => { + describe('创建用户', () => { + test('应该成功创建有效用户', async () => { + const userData = { + phone: '13800138000', + password: 'password123', + name: '测试用户', + role: 'buyer' + }; + + const user = await User.create(userData); + + expect(user.id).toBeDefined(); + expect(user.phone).toBe(userData.phone); + expect(user.name).toBe(userData.name); + expect(user.role).toBe(userData.role); + expect(user.password).not.toBe(userData.password); // 应该被加密 + }); + + test('应该拒绝无效手机号', async () => { + const userData = { + phone: '123', + password: 'password123', + name: '测试用户', + role: 'buyer' + }; + + await expect(User.create(userData)).rejects.toThrow(); + }); + + test('应该拒绝重复手机号', async () => { + const userData = { + phone: '13800138000', + password: 'password123', + name: '测试用户', + role: 'buyer' + }; + + await User.create(userData); + await expect(User.create(userData)).rejects.toThrow(); + }); + }); + + describe('用户验证', () => { + test('应该正确验证密码', async () => { + const password = 'password123'; + const user = await User.create({ + phone: '13800138000', + password, + name: '测试用户', + role: 'buyer' + }); + + const isValid = await user.validatePassword(password); + expect(isValid).toBe(true); + + const isInvalid = await user.validatePassword('wrongpassword'); + expect(isInvalid).toBe(false); + }); + }); +}); +``` + +#### 订单模型测试 +```javascript +// tests/models/order.test.js +const { Order, User } = require('../../src/models'); + +describe('Order Model', () => { + let buyer, seller; + + beforeEach(async () => { + buyer = await User.create({ + phone: '13800138001', + password: 'password123', + name: '采购商', + role: 'buyer' + }); + + seller = await User.create({ + phone: '13800138002', + password: 'password123', + name: '养殖户', + role: 'seller' + }); + }); + + test('应该成功创建订单', async () => { + const orderData = { + buyer_id: buyer.id, + seller_id: seller.id, + cattle_type: '肉牛', + quantity: 50, + unit_price: 15000, + total_amount: 750000, + delivery_date: new Date('2024-12-25'), + delivery_address: '测试地址' + }; + + const order = await Order.create(orderData); + + expect(order.id).toBeDefined(); + expect(order.status).toBe('pending'); + expect(order.total_amount).toBe(orderData.total_amount); + }); + + test('应该正确计算订单总金额', async () => { + const order = await Order.create({ + buyer_id: buyer.id, + seller_id: seller.id, + cattle_type: '肉牛', + quantity: 50, + unit_price: 15000, + delivery_date: new Date('2024-12-25'), + delivery_address: '测试地址' + }); + + expect(order.total_amount).toBe(50 * 15000); + }); +}); +``` + +### 2.3 服务层测试 + +#### 用户服务测试 +```javascript +// tests/services/userService.test.js +const UserService = require('../../src/services/userService'); +const { User } = require('../../src/models'); + +describe('UserService', () => { + describe('用户注册', () => { + test('应该成功注册新用户', async () => { + const userData = { + phone: '13800138000', + password: 'password123', + name: '测试用户', + role: 'buyer' + }; + + const result = await UserService.register(userData); + + expect(result.success).toBe(true); + expect(result.user.phone).toBe(userData.phone); + expect(result.token).toBeDefined(); + }); + + test('应该拒绝已存在的手机号', async () => { + const userData = { + phone: '13800138000', + password: 'password123', + name: '测试用户', + role: 'buyer' + }; + + await UserService.register(userData); + const result = await UserService.register(userData); + + expect(result.success).toBe(false); + expect(result.message).toContain('手机号已存在'); + }); + }); + + describe('用户登录', () => { + beforeEach(async () => { + await UserService.register({ + phone: '13800138000', + password: 'password123', + name: '测试用户', + role: 'buyer' + }); + }); + + test('应该成功登录有效用户', async () => { + const result = await UserService.login('13800138000', 'password123'); + + expect(result.success).toBe(true); + expect(result.user.phone).toBe('13800138000'); + expect(result.token).toBeDefined(); + }); + + test('应该拒绝错误密码', async () => { + const result = await UserService.login('13800138000', 'wrongpassword'); + + expect(result.success).toBe(false); + expect(result.message).toContain('密码错误'); + }); + + test('应该拒绝不存在的用户', async () => { + const result = await UserService.login('13800138999', 'password123'); + + expect(result.success).toBe(false); + expect(result.message).toContain('用户不存在'); + }); + }); +}); +``` + +### 2.4 运行单元测试 + +```bash +# 安装测试依赖 +npm install --save-dev jest supertest + +# 运行所有测试 +npm test + +# 运行特定测试文件 +npm test -- tests/models/user.test.js + +# 运行测试并生成覆盖率报告 +npm run test:coverage + +# 监听模式运行测试 +npm run test:watch +``` + +## 3. API测试 + +### 3.1 API测试框架 + +#### Supertest配置 +```javascript +// tests/api/setup.js +const request = require('supertest'); +const app = require('../../src/app'); + +// 创建测试客户端 +const api = request(app); + +// 辅助函数:获取认证token +async function getAuthToken(userData = {}) { + const defaultUser = { + phone: '13800138000', + password: 'password123', + name: '测试用户', + role: 'buyer' + }; + + const user = { ...defaultUser, ...userData }; + + // 注册用户 + await api.post('/api/auth/register').send(user); + + // 登录获取token + const response = await api + .post('/api/auth/login') + .send({ + phone: user.phone, + password: user.password + }); + + return response.body.token; +} + +module.exports = { api, getAuthToken }; +``` + +### 3.2 认证API测试 + +```javascript +// tests/api/auth.test.js +const { api } = require('./setup'); + +describe('Auth API', () => { + describe('POST /api/auth/register', () => { + test('应该成功注册新用户', async () => { + const userData = { + phone: '13800138000', + password: 'password123', + name: '测试用户', + role: 'buyer' + }; + + const response = await api + .post('/api/auth/register') + .send(userData) + .expect(201); + + expect(response.body.success).toBe(true); + expect(response.body.user.phone).toBe(userData.phone); + expect(response.body.token).toBeDefined(); + }); + + test('应该拒绝无效数据', async () => { + const invalidData = { + phone: '123', + password: '123' + }; + + const response = await api + .post('/api/auth/register') + .send(invalidData) + .expect(400); + + expect(response.body.success).toBe(false); + expect(response.body.errors).toBeDefined(); + }); + }); + + describe('POST /api/auth/login', () => { + beforeEach(async () => { + await api.post('/api/auth/register').send({ + phone: '13800138000', + password: 'password123', + name: '测试用户', + role: 'buyer' + }); + }); + + test('应该成功登录', async () => { + const response = await api + .post('/api/auth/login') + .send({ + phone: '13800138000', + password: 'password123' + }) + .expect(200); + + expect(response.body.success).toBe(true); + expect(response.body.token).toBeDefined(); + }); + + test('应该拒绝错误密码', async () => { + const response = await api + .post('/api/auth/login') + .send({ + phone: '13800138000', + password: 'wrongpassword' + }) + .expect(401); + + expect(response.body.success).toBe(false); + }); + }); +}); +``` + +### 3.3 订单API测试 + +```javascript +// tests/api/orders.test.js +const { api, getAuthToken } = require('./setup'); + +describe('Orders API', () => { + let buyerToken, sellerToken; + + beforeEach(async () => { + buyerToken = await getAuthToken({ + phone: '13800138001', + role: 'buyer' + }); + + sellerToken = await getAuthToken({ + phone: '13800138002', + role: 'seller' + }); + }); + + describe('POST /api/orders', () => { + test('采购商应该能创建订单', async () => { + const orderData = { + seller_phone: '13800138002', + cattle_type: '肉牛', + quantity: 50, + unit_price: 15000, + delivery_date: '2024-12-25', + delivery_address: '测试地址' + }; + + const response = await api + .post('/api/orders') + .set('Authorization', `Bearer ${buyerToken}`) + .send(orderData) + .expect(201); + + expect(response.body.success).toBe(true); + expect(response.body.order.status).toBe('pending'); + }); + + test('应该拒绝未认证的请求', async () => { + const orderData = { + seller_phone: '13800138002', + cattle_type: '肉牛', + quantity: 50, + unit_price: 15000 + }; + + await api + .post('/api/orders') + .send(orderData) + .expect(401); + }); + }); + + describe('GET /api/orders', () => { + test('应该返回用户的订单列表', async () => { + // 先创建一个订单 + await api + .post('/api/orders') + .set('Authorization', `Bearer ${buyerToken}`) + .send({ + seller_phone: '13800138002', + cattle_type: '肉牛', + quantity: 50, + unit_price: 15000, + delivery_date: '2024-12-25', + delivery_address: '测试地址' + }); + + const response = await api + .get('/api/orders') + .set('Authorization', `Bearer ${buyerToken}`) + .expect(200); + + expect(response.body.success).toBe(true); + expect(Array.isArray(response.body.orders)).toBe(true); + expect(response.body.orders.length).toBeGreaterThan(0); + }); + }); +}); +``` + +## 4. 端到端测试 + +### 4.1 Cypress配置 + +```javascript +// cypress.config.js +const { defineConfig } = require('cypress'); + +module.exports = defineConfig({ + e2e: { + baseUrl: 'http://localhost:3000', + supportFile: 'cypress/support/e2e.js', + specPattern: 'cypress/e2e/**/*.cy.js', + video: true, + screenshot: true, + viewportWidth: 1280, + viewportHeight: 720, + defaultCommandTimeout: 10000, + requestTimeout: 10000, + responseTimeout: 10000 + } +}); +``` + +### 4.2 用户注册登录流程测试 + +```javascript +// cypress/e2e/auth.cy.js +describe('用户认证流程', () => { + beforeEach(() => { + // 清理数据库 + cy.task('db:seed'); + }); + + it('应该完成完整的注册登录流程', () => { + // 访问注册页面 + cy.visit('/register'); + + // 填写注册表单 + cy.get('[data-cy=phone-input]').type('13800138000'); + cy.get('[data-cy=password-input]').type('password123'); + cy.get('[data-cy=name-input]').type('测试用户'); + cy.get('[data-cy=role-select]').select('buyer'); + + // 提交注册 + cy.get('[data-cy=register-button]').click(); + + // 验证注册成功 + cy.url().should('include', '/dashboard'); + cy.get('[data-cy=user-name]').should('contain', '测试用户'); + + // 退出登录 + cy.get('[data-cy=logout-button]').click(); + + // 重新登录 + cy.visit('/login'); + cy.get('[data-cy=phone-input]').type('13800138000'); + cy.get('[data-cy=password-input]').type('password123'); + cy.get('[data-cy=login-button]').click(); + + // 验证登录成功 + cy.url().should('include', '/dashboard'); + }); +}); +``` + +### 4.3 订单创建流程测试 + +```javascript +// cypress/e2e/orders.cy.js +describe('订单管理流程', () => { + beforeEach(() => { + cy.task('db:seed'); + // 登录为采购商 + cy.login('buyer'); + }); + + it('应该完成完整的订单创建流程', () => { + // 访问订单创建页面 + cy.visit('/orders/create'); + + // 填写订单信息 + cy.get('[data-cy=seller-select]').select('养殖户A'); + cy.get('[data-cy=cattle-type-input]').type('肉牛'); + cy.get('[data-cy=quantity-input]').type('50'); + cy.get('[data-cy=unit-price-input]').type('15000'); + cy.get('[data-cy=delivery-date-input]').type('2024-12-25'); + cy.get('[data-cy=delivery-address-input]').type('测试地址'); + + // 提交订单 + cy.get('[data-cy=create-order-button]').click(); + + // 验证订单创建成功 + cy.get('[data-cy=success-message]').should('be.visible'); + cy.url().should('include', '/orders'); + + // 验证订单出现在列表中 + cy.get('[data-cy=order-list]').should('contain', '肉牛'); + cy.get('[data-cy=order-status]').should('contain', '待确认'); + }); + + it('应该能查看订单详情', () => { + // 创建测试订单 + cy.createTestOrder(); + + // 访问订单列表 + cy.visit('/orders'); + + // 点击查看详情 + cy.get('[data-cy=order-item]').first().click(); + + // 验证详情页面 + cy.url().should('include', '/orders/'); + cy.get('[data-cy=order-details]').should('be.visible'); + cy.get('[data-cy=cattle-type]').should('contain', '肉牛'); + cy.get('[data-cy=quantity]').should('contain', '50'); + }); +}); +``` + +## 5. 性能测试 + +### 5.1 负载测试配置 + +```javascript +// tests/performance/load-test.js +import http from 'k6/http'; +import { check, sleep } from 'k6'; +import { Rate } from 'k6/metrics'; + +// 自定义指标 +export let errorRate = new Rate('errors'); + +// 测试配置 +export let options = { + stages: [ + { duration: '2m', target: 100 }, // 2分钟内增加到100用户 + { duration: '5m', target: 100 }, // 保持100用户5分钟 + { duration: '2m', target: 200 }, // 2分钟内增加到200用户 + { duration: '5m', target: 200 }, // 保持200用户5分钟 + { duration: '2m', target: 0 }, // 2分钟内减少到0用户 + ], + thresholds: { + http_req_duration: ['p(99)<1500'], // 99%的请求在1.5秒内完成 + http_req_failed: ['rate<0.1'], // 错误率小于10% + errors: ['rate<0.1'], // 自定义错误率小于10% + }, +}; + +// 测试数据 +const users = [ + { phone: '13800138001', password: 'password123' }, + { phone: '13800138002', password: 'password123' }, + { phone: '13800138003', password: 'password123' }, +]; + +export default function () { + // 随机选择用户 + const user = users[Math.floor(Math.random() * users.length)]; + + // 登录 + let loginResponse = http.post('http://localhost:3000/api/auth/login', { + phone: user.phone, + password: user.password, + }); + + let loginSuccess = check(loginResponse, { + '登录状态码为200': (r) => r.status === 200, + '登录响应时间<500ms': (r) => r.timings.duration < 500, + }); + + errorRate.add(!loginSuccess); + + if (loginSuccess) { + const token = JSON.parse(loginResponse.body).token; + + // 获取订单列表 + let ordersResponse = http.get('http://localhost:3000/api/orders', { + headers: { Authorization: `Bearer ${token}` }, + }); + + let ordersSuccess = check(ordersResponse, { + '订单列表状态码为200': (r) => r.status === 200, + '订单列表响应时间<1000ms': (r) => r.timings.duration < 1000, + }); + + errorRate.add(!ordersSuccess); + + // 创建订单 + let createOrderResponse = http.post( + 'http://localhost:3000/api/orders', + JSON.stringify({ + seller_phone: '13800138002', + cattle_type: '肉牛', + quantity: Math.floor(Math.random() * 100) + 1, + unit_price: 15000, + delivery_date: '2024-12-25', + delivery_address: '测试地址', + }), + { + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + } + ); + + let createSuccess = check(createOrderResponse, { + '创建订单状态码为201': (r) => r.status === 201, + '创建订单响应时间<2000ms': (r) => r.timings.duration < 2000, + }); + + errorRate.add(!createSuccess); + } + + sleep(1); +} +``` + +### 5.2 数据库性能测试 + +```sql +-- 数据库性能测试脚本 +-- tests/performance/db-performance.sql + +-- 创建测试数据 +DELIMITER // +CREATE PROCEDURE GenerateTestData() +BEGIN + DECLARE i INT DEFAULT 1; + + -- 创建10000个用户 + WHILE i <= 10000 DO + INSERT INTO users (phone, password, name, role, created_at, updated_at) + VALUES ( + CONCAT('138', LPAD(i, 8, '0')), + '$2b$10$hash', + CONCAT('用户', i), + CASE WHEN i % 3 = 0 THEN 'seller' ELSE 'buyer' END, + NOW(), + NOW() + ); + SET i = i + 1; + END WHILE; + + -- 创建50000个订单 + SET i = 1; + WHILE i <= 50000 DO + INSERT INTO orders ( + buyer_id, seller_id, cattle_type, quantity, unit_price, + total_amount, status, delivery_date, delivery_address, + created_at, updated_at + ) + VALUES ( + FLOOR(RAND() * 6667) + 1, -- 随机买家 + FLOOR(RAND() * 3333) + 6668, -- 随机卖家 + CASE FLOOR(RAND() * 3) + WHEN 0 THEN '肉牛' + WHEN 1 THEN '奶牛' + ELSE '种牛' + END, + FLOOR(RAND() * 100) + 1, + FLOOR(RAND() * 5000) + 10000, + 0, -- 将通过触发器计算 + CASE FLOOR(RAND() * 5) + WHEN 0 THEN 'pending' + WHEN 1 THEN 'confirmed' + WHEN 2 THEN 'in_transit' + WHEN 3 THEN 'delivered' + ELSE 'completed' + END, + DATE_ADD(NOW(), INTERVAL FLOOR(RAND() * 30) DAY), + CONCAT('地址', i), + NOW() - INTERVAL FLOOR(RAND() * 365) DAY, + NOW() + ); + SET i = i + 1; + END WHILE; +END // +DELIMITER ; + +-- 执行数据生成 +CALL GenerateTestData(); + +-- 性能测试查询 +-- 1. 测试订单列表查询性能 +EXPLAIN ANALYZE +SELECT o.*, u1.name as buyer_name, u2.name as seller_name +FROM orders o +JOIN users u1 ON o.buyer_id = u1.id +JOIN users u2 ON o.seller_id = u2.id +WHERE o.status = 'pending' +ORDER BY o.created_at DESC +LIMIT 20; + +-- 2. 测试用户订单统计性能 +EXPLAIN ANALYZE +SELECT + u.id, + u.name, + COUNT(o.id) as order_count, + SUM(o.total_amount) as total_amount +FROM users u +LEFT JOIN orders o ON u.id = o.buyer_id +WHERE u.role = 'buyer' +GROUP BY u.id, u.name +ORDER BY total_amount DESC +LIMIT 100; + +-- 3. 测试复杂查询性能 +EXPLAIN ANALYZE +SELECT + DATE(o.created_at) as order_date, + o.cattle_type, + COUNT(*) as order_count, + AVG(o.unit_price) as avg_price, + SUM(o.total_amount) as total_amount +FROM orders o +WHERE o.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY) + AND o.status IN ('completed', 'delivered') +GROUP BY DATE(o.created_at), o.cattle_type +ORDER BY order_date DESC, total_amount DESC; +``` + +## 6. 安全测试 + +### 6.1 SQL注入测试 + +```javascript +// tests/security/sql-injection.test.js +const { api, getAuthToken } = require('../api/setup'); + +describe('SQL注入安全测试', () => { + let token; + + beforeEach(async () => { + token = await getAuthToken(); + }); + + test('应该防止登录接口SQL注入', async () => { + const maliciousInputs = [ + "' OR '1'='1", + "'; DROP TABLE users; --", + "' UNION SELECT * FROM users --", + "admin'--", + "' OR 1=1#" + ]; + + for (const input of maliciousInputs) { + const response = await api + .post('/api/auth/login') + .send({ + phone: input, + password: input + }); + + // 应该返回401而不是500或其他错误 + expect([400, 401]).toContain(response.status); + expect(response.body.success).toBe(false); + } + }); + + test('应该防止订单查询SQL注入', async () => { + const maliciousQueries = [ + "1' OR '1'='1", + "1; DROP TABLE orders; --", + "1 UNION SELECT * FROM users" + ]; + + for (const query of maliciousQueries) { + const response = await api + .get(`/api/orders/${query}`) + .set('Authorization', `Bearer ${token}`); + + // 应该返回400或404,不应该执行恶意SQL + expect([400, 404]).toContain(response.status); + } + }); +}); +``` + +### 6.2 XSS测试 + +```javascript +// tests/security/xss.test.js +const { api, getAuthToken } = require('../api/setup'); + +describe('XSS安全测试', () => { + let token; + + beforeEach(async () => { + token = await getAuthToken(); + }); + + test('应该过滤用户输入中的脚本', async () => { + const xssPayloads = [ + '', + '', + 'javascript:alert("xss")', + '', + '">' + ]; + + for (const payload of xssPayloads) { + const response = await api + .post('/api/orders') + .set('Authorization', `Bearer ${token}`) + .send({ + seller_phone: '13800138002', + cattle_type: payload, + quantity: 50, + unit_price: 15000, + delivery_date: '2024-12-25', + delivery_address: payload + }); + + if (response.status === 201) { + // 如果创建成功,检查返回的数据是否被正确转义 + expect(response.body.order.cattle_type).not.toContain('
Uni-app] --> I[API网关] + F[管理后台
Vue 3] --> I + H[企业官网
HTML5] --> J[静态资源] + end + + subgraph "服务层" + I[API网关
Nginx] --> K[认证服务] + I --> L[业务服务集群] + K[认证服务
JWT] --> L + L[业务服务
Express.js] --> M[数据访问层] + end + + subgraph "数据层" + M[数据访问层
Sequelize ORM] --> N[MySQL主库] + M --> O[MySQL从库] + M --> P[Redis缓存] + M --> Q[文件存储
MinIO/OSS] + end + + subgraph "基础设施层" + R[容器化部署
Docker] --> S[负载均衡
Nginx] + S --> T[应用服务器] + T --> U[数据库服务器] + V[监控告警
Prometheus] --> W[日志收集
ELK] + end +``` + +### 1.2 架构分层说明 + +| 层级 | 职责 | 技术栈 | 说明 | +|------|------|--------|------| +| **用户层** | 用户交互界面 | 浏览器、微信小程序 | 提供多端用户访问入口 | +| **应用层** | 前端应用 | Vue 3、Uni-app、HTML5 | 负责用户界面展示和交互 | +| **服务层** | 业务逻辑处理 | Express.js、JWT | 处理业务逻辑和数据处理 | +| **数据层** | 数据存储管理 | MySQL、Redis、MinIO | 负责数据持久化和缓存 | +| **基础设施层** | 运行环境支撑 | Docker、Nginx、监控 | 提供系统运行基础环境 | + +## 2. 技术栈选型 + +### 2.1 前端技术栈 + +| 技术/框架 | 版本 | 用途 | 选型理由 | +|-----------|------|------|----------| +| **Vue 3** | 3.4+ | 管理后台框架 | 组合式API、更好的TypeScript支持、性能优化 | +| **TypeScript** | 5.0+ | 类型系统 | 静态类型检查、提高代码质量和可维护性 | +| **Element Plus** | 2.4+ | UI组件库 | Vue 3生态、组件丰富、文档完善 | +| **Vite** | 5.0+ | 构建工具 | 极速开发体验、优化的构建性能 | +| **Pinia** | 2.1+ | 状态管理 | Vue 3官方推荐、API简洁、性能优异 | +| **Vue Router** | 4.2+ | 路由管理 | Vue 3官方路由、支持组合式API | +| **Uni-app** | 3.8+ | 小程序框架 | 一套代码多端运行、降低开发维护成本 | + +### 2.2 后端技术栈 + +| 技术/框架 | 版本 | 用途 | 选型理由 | +|-----------|------|------|----------| +| **Node.js** | 18+ | 运行环境 | 高性能、生态丰富、JavaScript全栈 | +| **Express.js** | 4.18+ | Web框架 | 轻量灵活、中间件丰富、学习成本低 | +| **Sequelize** | 6.35+ | ORM框架 | 支持多种数据库、简化数据库操作 | +| **JWT** | 9.0+ | 身份认证 | 无状态认证、跨域支持 | +| **Joi** | 17.11+ | 数据验证 | 强大的数据校验能力 | +| **Multer** | 1.4+ | 文件上传 | Express文件上传中间件 | +| **Socket.io** | 4.7+ | 实时通信 | WebSocket封装、实时数据推送 | + +### 2.3 数据存储技术栈 + +| 技术 | 版本 | 用途 | 选型理由 | +|------|------|------|----------| +| **MySQL** | 8.0+ | 关系型数据库 | 成熟稳定、ACID特性、适合复杂业务关系 | +| **Redis** | 7.0+ | 缓存数据库 | 高性能缓存、支持多种数据结构 | +| **MinIO** | Latest | 对象存储 | S3兼容、私有化部署、适合文件存储 | + +### 2.4 基础设施技术栈 + +| 技术 | 版本 | 用途 | 选型理由 | +|------|------|------|----------| +| **Docker** | 24.0+ | 容器化 | 环境一致性、部署便捷 | +| **Nginx** | 1.24+ | 反向代理 | 高性能、负载均衡、静态资源服务 | +| **PM2** | 5.3+ | 进程管理 | Node.js进程管理、自动重启 | +| **Prometheus** | 2.47+ | 监控系统 | 时序数据库、强大的查询语言 | +| **Grafana** | 10.2+ | 监控面板 | 可视化监控、丰富的图表 | + +## 3. 系统模块设计 + +### 3.1 核心业务模块 + +```mermaid +graph LR + A[用户管理模块] --> B[订单管理模块] + B --> C[供应商管理模块] + C --> D[运输管理模块] + D --> E[质量管理模块] + E --> F[财务管理模块] + F --> G[通知管理模块] + + H[权限管理] --> A + I[文件管理] --> C + I --> D + I --> E + J[日志管理] --> B + J --> D + J --> F +``` + +#### 3.1.1 用户管理模块 (User Management) + +**职责**: +- 用户注册、登录、注销 +- 用户信息管理和维护 +- 角色权限分配和控制 +- 用户状态管理 + +**核心功能**: +```javascript +/** + * 用户管理服务 + */ +class UserService { + // 用户注册 + async register(userData) { } + + // 用户登录 + async login(phone, password) { } + + // 获取用户信息 + async getUserInfo(userId) { } + + // 更新用户信息 + async updateUser(userId, updateData) { } + + // 用户权限验证 + async checkPermission(userId, permission) { } +} +``` + +**数据模型**: +- User(用户基本信息) +- Role(角色定义) +- Permission(权限定义) +- UserRole(用户角色关联) + +#### 3.1.2 订单管理模块 (Order Management) + +**职责**: +- 订单创建、查询、更新 +- 订单状态流转管理 +- 订单审核和确认 +- 订单统计和分析 + +**核心功能**: +```javascript +/** + * 订单管理服务 + */ +class OrderService { + // 创建订单 + async createOrder(orderData) { } + + // 查询订单列表 + async getOrderList(filters, pagination) { } + + // 获取订单详情 + async getOrderDetail(orderId) { } + + // 更新订单状态 + async updateOrderStatus(orderId, status) { } + + // 订单统计 + async getOrderStatistics(dateRange) { } +} +``` + +**状态流转**: +``` +待确认 → 已确认 → 准备中 → 运输中 → 已到达 → 已验收 → 已完成 +``` + +#### 3.1.3 运输管理模块 (Transport Management) + +**职责**: +- 运输任务分配和管理 +- 实时位置跟踪 +- 运输状态监控 +- 异常情况处理 + +**核心功能**: +```javascript +/** + * 运输管理服务 + */ +class TransportService { + // 创建运输任务 + async createTransportTask(taskData) { } + + // 更新位置信息 + async updateLocation(taskId, locationData) { } + + // 获取运输轨迹 + async getTransportTrack(taskId) { } + + // 异常情况上报 + async reportException(taskId, exceptionData) { } +} +``` + +### 3.2 前端模块结构 + +#### 3.2.1 管理后台模块结构 + +``` +admin-system/src/ +├── components/ # 公共组件 +│ ├── Layout/ # 布局组件 +│ ├── Charts/ # 图表组件 +│ ├── Forms/ # 表单组件 +│ └── Tables/ # 表格组件 +├── views/ # 页面组件 +│ ├── dashboard/ # 数据驾驶舱 +│ ├── order/ # 订单管理 +│ ├── user/ # 用户管理 +│ ├── transport/ # 运输管理 +│ ├── finance/ # 财务管理 +│ └── system/ # 系统管理 +├── stores/ # 状态管理 +│ ├── user.ts # 用户状态 +│ ├── order.ts # 订单状态 +│ └── app.ts # 应用状态 +├── api/ # API接口 +│ ├── user.ts # 用户接口 +│ ├── order.ts # 订单接口 +│ └── transport.ts # 运输接口 +├── utils/ # 工具函数 +│ ├── request.ts # HTTP请求封装 +│ ├── auth.ts # 认证工具 +│ └── common.ts # 通用工具 +└── types/ # TypeScript类型定义 + ├── user.ts # 用户类型 + ├── order.ts # 订单类型 + └── api.ts # API类型 +``` + +#### 3.2.2 小程序模块结构 + +``` +mini_program/ +├── client-mp/ # 采购人小程序 +│ ├── pages/ +│ │ ├── index/ # 首页 +│ │ ├── order/ # 订单管理 +│ │ ├── transport/ # 运输跟踪 +│ │ └── profile/ # 个人中心 +│ ├── components/ # 组件 +│ ├── utils/ # 工具函数 +│ └── api/ # 接口调用 +├── supplier-mp/ # 供应商小程序 +├── driver-mp/ # 司机小程序 +└── staff-mp/ # 内部员工小程序 +``` + +## 4. 数据库设计 + +### 4.1 数据库架构 + +```mermaid +graph TB + A[应用服务] --> B[读写分离中间件] + B --> C[MySQL主库
写操作] + B --> D[MySQL从库1
读操作] + B --> E[MySQL从库2
读操作] + + A --> F[Redis集群
缓存层] + F --> G[Redis主节点] + F --> H[Redis从节点] + + A --> I[文件存储
MinIO集群] +``` + +### 4.2 核心数据表设计 + +#### 4.2.1 用户相关表 + +```sql +-- 用户表 +CREATE TABLE users ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + phone VARCHAR(20) UNIQUE NOT NULL COMMENT '手机号', + password VARCHAR(255) NOT NULL COMMENT '密码', + name VARCHAR(100) NOT NULL COMMENT '姓名', + role ENUM('client', 'supplier', 'driver', 'trader', 'admin') NOT NULL COMMENT '角色', + status ENUM('active', 'inactive', 'banned') DEFAULT 'active' COMMENT '状态', + avatar VARCHAR(500) COMMENT '头像URL', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_phone (phone), + INDEX idx_role (role), + INDEX idx_status (status) +) COMMENT '用户表'; + +-- 用户详情表 +CREATE TABLE user_profiles ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + user_id BIGINT NOT NULL, + company_name VARCHAR(200) COMMENT '公司名称', + business_license VARCHAR(500) COMMENT '营业执照', + contact_address TEXT COMMENT '联系地址', + emergency_contact VARCHAR(100) COMMENT '紧急联系人', + emergency_phone VARCHAR(20) COMMENT '紧急联系电话', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, + INDEX idx_user_id (user_id) +) COMMENT '用户详情表'; +``` + +#### 4.2.2 订单相关表 + +```sql +-- 订单表 +CREATE TABLE orders ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + order_no VARCHAR(50) UNIQUE NOT NULL COMMENT '订单号', + client_id BIGINT NOT NULL COMMENT '采购人ID', + trader_id BIGINT COMMENT '贸易商ID', + supplier_id BIGINT COMMENT '供应商ID', + cattle_type VARCHAR(50) NOT NULL COMMENT '牛只品种', + quantity INT NOT NULL COMMENT '数量', + weight_range VARCHAR(50) COMMENT '重量范围', + unit_price DECIMAL(10,2) NOT NULL COMMENT '单价', + total_amount DECIMAL(12,2) NOT NULL COMMENT '总金额', + delivery_address TEXT NOT NULL COMMENT '交货地址', + delivery_time DATETIME COMMENT '要求交货时间', + status ENUM('pending', 'confirmed', 'preparing', 'transporting', 'arrived', 'accepted', 'completed', 'cancelled') DEFAULT 'pending', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (client_id) REFERENCES users(id), + FOREIGN KEY (trader_id) REFERENCES users(id), + FOREIGN KEY (supplier_id) REFERENCES users(id), + INDEX idx_order_no (order_no), + INDEX idx_client_id (client_id), + INDEX idx_status (status), + INDEX idx_created_at (created_at) +) COMMENT '订单表'; + +-- 订单状态变更记录表 +CREATE TABLE order_status_logs ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + order_id BIGINT NOT NULL, + from_status VARCHAR(50) COMMENT '原状态', + to_status VARCHAR(50) NOT NULL COMMENT '新状态', + operator_id BIGINT COMMENT '操作人ID', + remark TEXT COMMENT '备注', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE, + FOREIGN KEY (operator_id) REFERENCES users(id), + INDEX idx_order_id (order_id), + INDEX idx_created_at (created_at) +) COMMENT '订单状态变更记录表'; +``` + +#### 4.2.3 运输相关表 + +```sql +-- 运输任务表 +CREATE TABLE transport_tasks ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + task_no VARCHAR(50) UNIQUE NOT NULL COMMENT '任务号', + order_id BIGINT NOT NULL COMMENT '订单ID', + driver_id BIGINT NOT NULL COMMENT '司机ID', + vehicle_no VARCHAR(20) NOT NULL COMMENT '车牌号', + start_location VARCHAR(200) COMMENT '起始地点', + end_location VARCHAR(200) COMMENT '目的地点', + start_time DATETIME COMMENT '开始时间', + end_time DATETIME COMMENT '结束时间', + status ENUM('assigned', 'started', 'transporting', 'arrived', 'completed') DEFAULT 'assigned', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (order_id) REFERENCES orders(id), + FOREIGN KEY (driver_id) REFERENCES users(id), + INDEX idx_task_no (task_no), + INDEX idx_order_id (order_id), + INDEX idx_driver_id (driver_id), + INDEX idx_status (status) +) COMMENT '运输任务表'; + +-- 位置跟踪表 +CREATE TABLE location_tracks ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + task_id BIGINT NOT NULL COMMENT '任务ID', + latitude DECIMAL(10,6) NOT NULL COMMENT '纬度', + longitude DECIMAL(10,6) NOT NULL COMMENT '经度', + address VARCHAR(500) COMMENT '地址', + speed DECIMAL(5,2) COMMENT '速度', + direction DECIMAL(5,2) COMMENT '方向', + recorded_at TIMESTAMP NOT NULL COMMENT '记录时间', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (task_id) REFERENCES transport_tasks(id) ON DELETE CASCADE, + INDEX idx_task_id (task_id), + INDEX idx_recorded_at (recorded_at) +) COMMENT '位置跟踪表'; +``` + +### 4.3 数据库优化策略 + +#### 4.3.1 索引优化 +- **主键索引**:所有表使用自增主键 +- **唯一索引**:手机号、订单号等唯一字段 +- **复合索引**:常用查询条件组合 +- **覆盖索引**:减少回表查询 + +#### 4.3.2 分区策略 +```sql +-- 按时间分区的位置跟踪表 +CREATE TABLE location_tracks ( + -- 字段定义... +) PARTITION BY RANGE (YEAR(recorded_at)) ( + PARTITION p2024 VALUES LESS THAN (2025), + PARTITION p2025 VALUES LESS THAN (2026), + PARTITION p_future VALUES LESS THAN MAXVALUE +); +``` + +#### 4.3.3 读写分离 +- **主库**:处理所有写操作和实时性要求高的读操作 +- **从库**:处理统计查询、报表生成等读操作 +- **中间件**:自动路由读写请求 + +## 5. API设计规范 + +### 5.1 RESTful API设计原则 + +#### 5.1.1 URL设计规范 +``` +GET /api/v1/orders # 获取订单列表 +POST /api/v1/orders # 创建订单 +GET /api/v1/orders/:id # 获取订单详情 +PUT /api/v1/orders/:id # 更新订单 +DELETE /api/v1/orders/:id # 删除订单 +``` + +#### 5.1.2 HTTP状态码规范 +| 状态码 | 含义 | 使用场景 | +|--------|------|----------| +| 200 | OK | 请求成功 | +| 201 | Created | 资源创建成功 | +| 400 | Bad Request | 请求参数错误 | +| 401 | Unauthorized | 未认证 | +| 403 | Forbidden | 无权限 | +| 404 | Not Found | 资源不存在 | +| 500 | Internal Server Error | 服务器内部错误 | + +#### 5.1.3 响应格式规范 +```json +{ + "code": 200, + "message": "success", + "data": { + // 响应数据 + }, + "timestamp": "2024-12-20T10:00:00Z" +} +``` + +### 5.2 核心API接口设计 + +#### 5.2.1 用户认证接口 +```javascript +// 用户登录 +POST /api/v1/auth/login +{ + "phone": "13800138000", + "password": "password123" +} + +// 响应 +{ + "code": 200, + "message": "登录成功", + "data": { + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "user": { + "id": 1, + "name": "张三", + "role": "client", + "avatar": "https://example.com/avatar.jpg" + } + } +} +``` + +#### 5.2.2 订单管理接口 +```javascript +// 创建订单 +POST /api/v1/orders +{ + "cattleType": "西门塔尔", + "quantity": 50, + "weightRange": "400-500kg", + "unitPrice": 28.5, + "deliveryAddress": "北京市朝阳区...", + "deliveryTime": "2024-12-25T10:00:00Z" +} + +// 获取订单列表 +GET /api/v1/orders?page=1&limit=20&status=pending + +// 响应 +{ + "code": 200, + "message": "success", + "data": { + "list": [...], + "total": 100, + "page": 1, + "limit": 20 + } +} +``` + +## 6. 安全架构设计 + +### 6.1 认证与授权 + +#### 6.1.1 JWT认证机制 +```javascript +/** + * JWT Token结构 + */ +{ + "header": { + "alg": "HS256", + "typ": "JWT" + }, + "payload": { + "userId": 1, + "role": "client", + "permissions": ["order:read", "order:create"], + "exp": 1640995200, + "iat": 1640908800 + } +} +``` + +#### 6.1.2 权限控制模型 +```javascript +/** + * RBAC权限控制 + */ +const permissions = { + 'client': ['order:create', 'order:read', 'transport:read'], + 'supplier': ['order:read', 'order:update', 'cattle:manage'], + 'driver': ['transport:read', 'transport:update', 'location:report'], + 'admin': ['*'] // 所有权限 +}; +``` + +### 6.2 数据安全 + +#### 6.2.1 数据加密 +- **传输加密**:HTTPS/TLS 1.3 +- **存储加密**:敏感数据AES-256加密 +- **密码加密**:bcrypt哈希算法 + +#### 6.2.2 输入验证 +```javascript +/** + * 数据验证中间件 + */ +const orderValidation = Joi.object({ + cattleType: Joi.string().required(), + quantity: Joi.number().integer().min(1).max(1000).required(), + unitPrice: Joi.number().positive().precision(2).required(), + deliveryAddress: Joi.string().min(10).max(500).required() +}); +``` + +### 6.3 安全防护 + +#### 6.3.1 防护措施 +- **SQL注入防护**:参数化查询、ORM框架 +- **XSS防护**:输入过滤、输出编码 +- **CSRF防护**:CSRF Token验证 +- **请求限流**:基于IP和用户的限流策略 + +#### 6.3.2 监控告警 +```javascript +/** + * 安全事件监控 + */ +const securityEvents = { + 'login_failure': '登录失败次数过多', + 'permission_denied': '权限访问被拒绝', + 'sql_injection': 'SQL注入攻击尝试', + 'unusual_activity': '异常活动检测' +}; +``` + +## 7. 性能优化策略 + +### 7.1 前端性能优化 + +#### 7.1.1 代码分割与懒加载 +```javascript +// 路由懒加载 +const routes = [ + { + path: '/order', + component: () => import('@/views/order/OrderList.vue') + } +]; + +// 组件懒加载 +const LazyComponent = defineAsyncComponent(() => + import('@/components/HeavyComponent.vue') +); +``` + +#### 7.1.2 资源优化 +- **图片优化**:WebP格式、响应式图片 +- **代码压缩**:Gzip/Brotli压缩 +- **CDN加速**:静态资源CDN分发 +- **缓存策略**:浏览器缓存、Service Worker + +### 7.2 后端性能优化 + +#### 7.2.1 数据库优化 +```javascript +/** + * 查询优化示例 + */ +// 使用索引优化查询 +const orders = await Order.findAll({ + where: { + status: 'pending', + created_at: { + [Op.gte]: new Date('2024-01-01') + } + }, + include: [{ + model: User, + attributes: ['id', 'name'] // 只查询需要的字段 + }], + limit: 20, + offset: (page - 1) * 20 +}); +``` + +#### 7.2.2 缓存策略 +```javascript +/** + * Redis缓存策略 + */ +class CacheService { + // 用户信息缓存(30分钟) + async getUserInfo(userId) { + const cacheKey = `user:${userId}`; + let user = await redis.get(cacheKey); + + if (!user) { + user = await User.findByPk(userId); + await redis.setex(cacheKey, 1800, JSON.stringify(user)); + } + + return JSON.parse(user); + } + + // 订单列表缓存(5分钟) + async getOrderList(filters) { + const cacheKey = `orders:${JSON.stringify(filters)}`; + let orders = await redis.get(cacheKey); + + if (!orders) { + orders = await Order.findAll(filters); + await redis.setex(cacheKey, 300, JSON.stringify(orders)); + } + + return JSON.parse(orders); + } +} +``` + +### 7.3 系统性能监控 + +#### 7.3.1 关键性能指标 +| 指标 | 目标值 | 监控方式 | +|------|--------|----------| +| 页面加载时间 | < 2秒 | 前端性能监控 | +| API响应时间 | < 1秒 | APM监控 | +| 数据库查询时间 | < 100ms | 慢查询日志 | +| 系统可用性 | > 99.9% | 健康检查 | + +#### 7.3.2 性能监控工具 +- **前端监控**:Web Vitals、Performance API +- **后端监控**:Prometheus + Grafana +- **数据库监控**:MySQL Performance Schema +- **日志分析**:ELK Stack + +## 8. 部署架构 + +### 8.1 容器化部署 + +#### 8.1.1 Docker容器设计 +```dockerfile +# Node.js应用容器 +FROM node:18-alpine + +WORKDIR /app + +# 复制依赖文件 +COPY package*.json ./ +RUN npm ci --only=production + +# 复制应用代码 +COPY . . + +# 暴露端口 +EXPOSE 3000 + +# 启动应用 +CMD ["npm", "start"] +``` + +#### 8.1.2 Docker Compose编排 +```yaml +version: '3.8' + +services: + app: + build: . + ports: + - "3000:3000" + environment: + - NODE_ENV=production + - DB_HOST=mysql + - REDIS_HOST=redis + depends_on: + - mysql + - redis + + mysql: + image: mysql:8.0 + environment: + MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} + MYSQL_DATABASE: ${DB_NAME} + volumes: + - mysql_data:/var/lib/mysql + + redis: + image: redis:7-alpine + volumes: + - redis_data:/data + + nginx: + image: nginx:alpine + ports: + - "80:80" + - "443:443" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + - ./ssl:/etc/nginx/ssl + +volumes: + mysql_data: + redis_data: +``` + +### 8.2 生产环境架构 + +```mermaid +graph TB + A[负载均衡器
Nginx] --> B[Web服务器1
Node.js] + A --> C[Web服务器2
Node.js] + A --> D[Web服务器3
Node.js] + + B --> E[MySQL主库] + C --> E + D --> E + + B --> F[MySQL从库1] + C --> F + D --> F + + B --> G[Redis集群] + C --> G + D --> G + + H[文件存储
MinIO] --> I[对象存储] + + J[监控系统
Prometheus] --> K[告警系统
AlertManager] + K --> L[通知渠道
邮件/短信/钉钉] +``` + +### 8.3 CI/CD流水线 + +#### 8.3.1 自动化部署流程 +```yaml +# GitHub Actions配置 +name: Deploy to Production + +on: + push: + branches: [main] + +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 test + - run: npm run lint + + build: + needs: test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build Docker image + run: docker build -t niumall:${{ github.sha }} . + - name: Push to registry + run: docker push niumall:${{ github.sha }} + + deploy: + needs: build + runs-on: ubuntu-latest + steps: + - name: Deploy to production + run: | + ssh user@server "docker pull niumall:${{ github.sha }}" + ssh user@server "docker-compose up -d" +``` + +## 9. 扩展性设计 + +### 9.1 水平扩展策略 + +#### 9.1.1 应用层扩展 +- **无状态设计**:应用服务器无状态,支持水平扩展 +- **负载均衡**:Nginx负载均衡,支持多实例部署 +- **会话管理**:Redis集中式会话存储 + +#### 9.1.2 数据层扩展 +- **读写分离**:主从复制,读写分离 +- **分库分表**:按业务模块或时间分片 +- **缓存集群**:Redis集群,提高缓存容量 + +### 9.2 微服务演进路径 + +#### 9.2.1 服务拆分策略 +``` +单体应用 → 模块化应用 → 微服务架构 + +Phase 1: 模块化重构 +- 按业务领域拆分模块 +- 统一数据访问层 +- 服务接口标准化 + +Phase 2: 服务化改造 +- 独立部署单元 +- 服务间通信机制 +- 配置中心建设 + +Phase 3: 微服务架构 +- 服务注册发现 +- 分布式链路追踪 +- 熔断降级机制 +``` + +#### 9.2.2 技术栈演进 +| 阶段 | 架构模式 | 技术栈 | 复杂度 | +|------|---------|--------|--------| +| 当前 | 单体应用 | Express.js + MySQL | 低 | +| 中期 | 模块化应用 | Express.js + 微服务 | 中 | +| 长期 | 微服务架构 | Spring Cloud + K8s | 高 | + +--- + +**文档维护**:本文档由架构团队负责维护,重大架构变更时及时更新。 + +**最后更新时间**:2024年12月20日 \ No newline at end of file diff --git a/docs/部署运维指南.md b/docs/部署运维指南.md new file mode 100644 index 0000000..9719b97 --- /dev/null +++ b/docs/部署运维指南.md @@ -0,0 +1,434 @@ +# 活牛采购智能数字化系统 - 部署运维指南 + +## 版本历史 +| 版本 | 日期 | 作者 | 变更说明 | +|------|------|------|----------| +| v1.0 | 2024-12-20 | 运维团队 | 初版部署运维指南 | + +## 1. 环境要求 + +### 1.1 硬件要求 + +#### 生产环境最低配置 +| 组件 | CPU | 内存 | 存储 | 网络 | +|------|-----|------|------|------| +| Web服务器 | 4核 | 8GB | 100GB SSD | 1Gbps | +| 应用服务器 | 8核 | 16GB | 200GB SSD | 1Gbps | +| 数据库服务器 | 8核 | 32GB | 500GB SSD | 1Gbps | +| Redis缓存 | 4核 | 8GB | 50GB SSD | 1Gbps | +| 文件存储 | 4核 | 8GB | 2TB HDD | 1Gbps | + +#### 推荐配置 +| 组件 | CPU | 内存 | 存储 | 网络 | +|------|-----|------|------|------| +| Web服务器 | 8核 | 16GB | 200GB SSD | 10Gbps | +| 应用服务器 | 16核 | 32GB | 500GB SSD | 10Gbps | +| 数据库服务器 | 16核 | 64GB | 1TB SSD | 10Gbps | +| Redis缓存 | 8核 | 16GB | 100GB SSD | 10Gbps | +| 文件存储 | 8核 | 16GB | 5TB SSD | 10Gbps | + +### 1.2 软件要求 + +#### 操作系统 +- **推荐**: Ubuntu 20.04 LTS / CentOS 8 / RHEL 8 +- **最低**: Ubuntu 18.04 LTS / CentOS 7 + +#### 基础软件 +```bash +# 必需软件版本 +Node.js >= 18.0.0 +npm >= 8.0.0 +MySQL >= 8.0 +Redis >= 6.0 +Nginx >= 1.18 +Docker >= 20.10 +Docker Compose >= 2.0 +``` + +## 2. 快速部署 + +### 2.1 一键部署脚本 + +```bash +#!/bin/bash +# quick_deploy.sh - 活牛采购系统一键部署脚本 + +set -e + +echo "开始部署活牛采购智能数字化系统..." + +# 检查系统 +if [[ "$OSTYPE" != "linux-gnu"* ]]; then + echo "错误: 仅支持Linux系统" + exit 1 +fi + +# 更新系统 +sudo apt update && sudo apt upgrade -y + +# 安装基础依赖 +sudo apt install -y curl wget git vim htop tree unzip + +# 安装Node.js 18 +curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - +sudo apt install -y nodejs + +# 安装Docker +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh +sudo usermod -aG docker $USER + +# 安装Docker Compose +sudo curl -L "https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +sudo chmod +x /usr/local/bin/docker-compose + +# 创建应用目录 +sudo mkdir -p /opt/niumall +sudo chown -R $USER:$USER /opt/niumall + +# 克隆代码 +cd /opt/niumall +git clone https://github.com/your-org/niumall.git . + +# 启动服务 +docker-compose up -d + +echo "部署完成!" +echo "API服务: http://localhost:3000" +echo "管理后台: http://localhost" +``` + +### 2.2 Docker Compose配置 + +```yaml +# docker-compose.yml +version: '3.8' + +services: + # MySQL数据库 + mysql: + image: mysql:8.0 + container_name: niumall-mysql + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: root_password + MYSQL_DATABASE: niumall + MYSQL_USER: niumall_user + MYSQL_PASSWORD: user_password + volumes: + - mysql_data:/var/lib/mysql + ports: + - "3306:3306" + networks: + - niumall-network + + # Redis缓存 + redis: + image: redis:7-alpine + container_name: niumall-redis + restart: unless-stopped + command: redis-server --requirepass redis_password + volumes: + - redis_data:/data + ports: + - "6379:6379" + networks: + - niumall-network + + # 后端API服务 + api: + build: + context: ./backend + dockerfile: Dockerfile + container_name: niumall-api + restart: unless-stopped + environment: + NODE_ENV: production + DB_HOST: mysql + REDIS_HOST: redis + ports: + - "3000:3000" + networks: + - niumall-network + depends_on: + - mysql + - redis + + # 管理后台 + admin: + build: + context: ./admin-system + dockerfile: Dockerfile + container_name: niumall-admin + restart: unless-stopped + ports: + - "80:80" + networks: + - niumall-network + depends_on: + - api + +volumes: + mysql_data: + redis_data: + +networks: + niumall-network: + driver: bridge +``` + +## 3. 监控与维护 + +### 3.1 健康检查脚本 + +```bash +#!/bin/bash +# health_check.sh + +echo "=== 系统健康检查 $(date) ===" + +# 检查服务状态 +services=("mysql" "redis" "api" "admin") +for service in "${services[@]}"; do + if docker ps | grep -q "niumall-$service"; then + echo "$service: ✓ 运行中" + else + echo "$service: ✗ 已停止" + fi +done + +# 检查API健康状态 +if curl -f -s http://localhost:3000/health > /dev/null; then + echo "API服务: ✓ 健康" +else + echo "API服务: ✗ 异常" +fi + +# 检查系统资源 +echo "CPU使用率: $(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)" +echo "内存使用率: $(free -m | awk 'NR==2{printf "%.2f%%\n", $3*100/$2}')" +echo "磁盘使用率: $(df -h | awk '$NF=="/"{printf "%s\n", $5}')" + +echo "=== 检查完成 ===" +``` + +### 3.2 备份脚本 + +```bash +#!/bin/bash +# backup.sh + +DATE=$(date +%Y%m%d_%H%M%S) +BACKUP_DIR="/backup" + +mkdir -p $BACKUP_DIR + +# 数据库备份 +echo "开始数据库备份..." +docker exec niumall-mysql mysqldump -u root -proot_password niumall > $BACKUP_DIR/niumall_$DATE.sql +gzip $BACKUP_DIR/niumall_$DATE.sql + +# 删除7天前的备份 +find $BACKUP_DIR -name "niumall_*.sql.gz" -mtime +7 -delete + +echo "备份完成: niumall_$DATE.sql.gz" +``` + +### 3.3 日志查看 + +```bash +# 查看所有服务日志 +docker-compose logs + +# 查看特定服务日志 +docker-compose logs api +docker-compose logs mysql + +# 实时查看日志 +docker-compose logs -f api +``` + +## 4. 故障排除 + +### 4.1 常见问题 + +#### 服务无法启动 +```bash +# 检查容器状态 +docker-compose ps + +# 查看错误日志 +docker-compose logs [service_name] + +# 重启服务 +docker-compose restart [service_name] +``` + +#### 数据库连接失败 +```bash +# 检查MySQL容器 +docker exec -it niumall-mysql mysql -u root -p + +# 检查网络连接 +docker network ls +docker network inspect niumall_niumall-network +``` + +#### 端口冲突 +```bash +# 检查端口占用 +sudo netstat -tulpn | grep :3000 +sudo netstat -tulpn | grep :3306 + +# 修改docker-compose.yml中的端口映射 +``` + +### 4.2 紧急恢复 + +```bash +#!/bin/bash +# emergency_recovery.sh + +echo "开始紧急恢复..." + +# 停止所有服务 +docker-compose down + +# 清理容器和网络 +docker system prune -f + +# 重新启动服务 +docker-compose up -d + +# 等待服务启动 +sleep 30 + +# 健康检查 +./health_check.sh + +echo "紧急恢复完成" +``` + +## 5. 性能优化 + +### 5.1 数据库优化 + +```sql +-- 查看慢查询 +SHOW VARIABLES LIKE 'slow_query_log'; +SHOW VARIABLES LIKE 'long_query_time'; + +-- 分析表 +ANALYZE TABLE orders, users, transport_tasks; + +-- 优化表 +OPTIMIZE TABLE orders, users, transport_tasks; +``` + +### 5.2 缓存优化 + +```bash +# Redis内存使用情况 +docker exec niumall-redis redis-cli info memory + +# 清理过期键 +docker exec niumall-redis redis-cli --scan --pattern "*" | xargs docker exec niumall-redis redis-cli del +``` + +## 6. 安全配置 + +### 6.1 防火墙设置 + +```bash +# 安装ufw +sudo apt install ufw + +# 基本规则 +sudo ufw default deny incoming +sudo ufw default allow outgoing + +# 允许必要端口 +sudo ufw allow ssh +sudo ufw allow 80 +sudo ufw allow 443 + +# 启用防火墙 +sudo ufw enable +``` + +### 6.2 SSL证书 + +```bash +# 安装Certbot +sudo apt install certbot + +# 获取证书 +sudo certbot certonly --standalone -d api.niumall.com -d admin.niumall.com + +# 自动续期 +echo "0 12 * * * /usr/bin/certbot renew --quiet" | sudo crontab - +``` + +## 7. 维护计划 + +### 7.1 定时任务 + +```bash +# 编辑crontab +crontab -e + +# 添加定时任务 +# 每天凌晨2点备份数据库 +0 2 * * * /opt/niumall/scripts/backup.sh + +# 每小时检查系统健康状态 +0 * * * * /opt/niumall/scripts/health_check.sh >> /var/log/niumall/health.log + +# 每周日凌晨清理日志 +0 0 * * 0 docker system prune -f +``` + +### 7.2 更新流程 + +```bash +#!/bin/bash +# update.sh + +echo "开始更新系统..." + +# 拉取最新代码 +git pull origin main + +# 重新构建镜像 +docker-compose build + +# 滚动更新 +docker-compose up -d --no-deps api +docker-compose up -d --no-deps admin + +# 健康检查 +sleep 30 +./health_check.sh + +echo "更新完成" +``` + +## 8. 联系信息 + +### 8.1 技术支持 + +- **运维团队**: ops@niumall.com +- **开发团队**: dev@niumall.com +- **紧急联系**: +86-138-0000-0000 + +### 8.2 相关文档 + +- [项目总览](./项目总览.md) +- [产品需求文档](./产品需求文档.md) +- [系统架构设计](./系统架构设计.md) +- [数据库设计](./数据库设计.md) +- [API接口文档](./API接口文档.md) + +--- + +**注意**: 请根据实际环境调整配置参数,确保系统安全稳定运行。 \ No newline at end of file diff --git a/docs/项目总览.md b/docs/项目总览.md new file mode 100644 index 0000000..7199714 --- /dev/null +++ b/docs/项目总览.md @@ -0,0 +1,124 @@ +# 活牛采购智能数字化系统 - 项目总览 + +## 📋 项目简介 + +活牛采购智能数字化系统是一个专为活牛采购行业打造的全流程数字化管理平台。系统通过标准化采购流程、实时运输跟踪、智能结算支付等功能,解决传统活牛采购中信息不透明、流程不规范、风险控制难等核心痛点。 + +## 🎯 核心价值 + +- **流程标准化**:建立统一的采购流程规范,减少人为错误 +- **信息透明化**:实时跟踪采购全流程,提升信息透明度 +- **风险可控化**:通过数字化手段,降低采购风险 +- **效率最大化**:自动化处理重复性工作,提升整体效率 + +## 🏗️ 系统架构 + +### 多端应用矩阵 +- **管理后台**:基于Vue 3的Web管理系统,面向内部管理人员 +- **小程序矩阵**:基于Uni-app的跨平台小程序,包含4个专业小程序 + - 采购人小程序:订单管理、验收支付 + - 供应商小程序:订单处理、牛只管理 + - 司机小程序:运输跟踪、状态上报 + - 内部员工小程序:全流程监控管理 +- **企业官网**:基于HTML5的企业展示网站 + +### 技术栈 +- **前端**:Vue 3 + TypeScript + Element Plus + Uni-app +- **后端**:Node.js + Express.js + MySQL + Redis +- **部署**:Docker + Nginx + PM2 + +## 📚 文档导航 + +### 📋 产品文档 +- [产品需求文档 (PRD)](./产品需求文档.md) - 详细的产品功能需求和用户故事 +- [用户角色与权限](./用户角色与权限.md) - 系统用户角色定义和权限矩阵 + +### 🏗️ 技术文档 +- [系统架构设计](./系统架构设计.md) - 整体技术架构和模块划分 +- [数据库设计](./数据库设计.md) - 数据表结构和关系设计 +- [API接口文档](./API接口文档.md) - 后端接口规范和调用说明 +- [前端开发规范](./前端开发规范.md) - 前端代码规范和开发指南 + +### 🚀 部署运维 +- [环境配置指南](./环境配置指南.md) - 开发和生产环境配置 +- [部署运维手册](./部署运维手册.md) - 系统部署和运维操作指南 +- [监控告警方案](./监控告警方案.md) - 系统监控和故障处理 + +### 🧪 测试文档 +- [测试计划](./测试计划.md) - 测试策略和测试用例 +- [质量保证规范](./质量保证规范.md) - 代码质量和测试规范 + +### 📊 项目管理 +- [开发计划](./开发计划.md) - 项目里程碑和开发进度 +- [版本发布记录](./版本发布记录.md) - 系统版本更新记录 + +## 🚀 快速开始 + +### 环境要求 +- Node.js 16+ +- MySQL 5.7+ +- Redis 6.0+ + +### 本地开发 +```bash +# 1. 克隆项目 +git clone [项目地址] + +# 2. 安装依赖 +cd niumall +npm install + +# 3. 配置环境变量 +cp backend/.env.example backend/.env +# 编辑 .env 文件,配置数据库连接等信息 + +# 4. 初始化数据库 +cd backend +npm run init:db + +# 5. 启动后端服务 +npm run dev + +# 6. 启动前端服务 +cd admin-system +npm run dev +``` + +### 项目结构 +``` +niumall/ +├── admin-system/ # 管理后台 (Vue 3) +├── backend/ # 后端服务 (Node.js) +├── mini_program/ # 小程序矩阵 (Uni-app) +├── website/ # 企业官网 (HTML5) +├── docs/ # 项目文档 +└── README.md # 项目说明 +``` + +## 👥 团队协作 + +### 开发流程 +1. **需求分析** → 产品经理编写PRD文档 +2. **技术设计** → 架构师设计技术方案 +3. **开发实现** → 开发团队按模块开发 +4. **测试验收** → QA团队执行测试计划 +5. **部署上线** → 运维团队执行部署方案 + +### 代码规范 +- 遵循ESLint和Prettier配置 +- 提交信息遵循Conventional Commits规范 +- 代码审查通过后方可合并 + +## 📞 联系方式 + +- **项目负责人**:[姓名] - [邮箱] +- **技术负责人**:[姓名] - [邮箱] +- **产品负责人**:[姓名] - [邮箱] + +## 📄 许可证 + +本项目采用 [MIT License](../LICENSE) 许可证。 + +--- + +*最后更新时间:2024年12月* \ No newline at end of file