🔐 认证接口
用户登录,获取 JWT Token
请求参数
| 参数名 |
类型 |
必填 |
说明 |
| username |
string |
是 |
登录账号 |
| password |
string |
是 |
登录密码 |
请求示例
POST /api/login
Content-Type: application/json
{
"username": "admin",
"password": "admin123"
}
响应示例
{
"code": 200,
"message": "登录成功",
"data": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"user": {
"id": 1,
"username": "admin",
"real_name": "张三",
"role": "admin"
},
"expires_in": 86400
}
}
获取当前登录用户信息
请求头
Authorization: Bearer {token}
响应示例
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"operator_no": "OP001",
"username": "admin",
"real_name": "张三",
"role": "admin"
}
}
📷 文件上传
上传单张照片,用于包裹照片
请求参数
| 参数名 |
类型 |
必填 |
说明 |
| file |
file |
是 |
图片文件,支持:jpg, jpeg, png, gif,最大5MB |
请求示例
POST /api/upload
Authorization: Bearer {token}
Content-Type: multipart/form-data
file: [image file]
响应示例
{
"code": 201,
"message": "上传成功",
"data": {
"url": "http://yourdomain.com/uploads/202601/abc123_1234567890.jpg",
"filename": "abc123_1234567890.jpg",
"original_name": "package_photo.jpg",
"size": 245678,
"size_formatted": "240 KB",
"width": 1920,
"height": 1080
}
}
上传多张照片,用于打包照片
请求参数
| 参数名 |
类型 |
必填 |
说明 |
| files[] |
file[] |
是 |
多个图片文件 |
请求示例
POST /api/upload-multiple
Authorization: Bearer {token}
Content-Type: multipart/form-data
files[]: [image file 1]
files[]: [image file 2]
files[]: [image file 3]
响应示例
{
"code": 201,
"message": "上传成功",
"data": {
"files": [
{
"url": "http://yourdomain.com/uploads/202601/photo1.jpg",
"filename": "photo1.jpg"
},
{
"url": "http://yourdomain.com/uploads/202601/photo2.jpg",
"filename": "photo2.jpg"
}
],
"count": 2
}
}
删除照片
请求参数
| 参数名 |
类型 |
必填 |
说明 |
| path |
string |
是 |
文件路径,如:uploads/202601/xxx.jpg |
请求示例
POST /api/upload/delete
Authorization: Bearer {token}
Content-Type: application/json
{
"path": "uploads/202601/abc123.jpg"
}
📦 包裹管理
获取包裹列表,支持高级搜索和筛选
请求参数(Query Parameters)
| 参数名 |
类型 |
必填 |
说明 |
| page |
int |
否 |
页码,默认1 |
| limit |
int |
否 |
每页数量,默认10 |
| status |
string |
否 |
状态筛选:pending/received/combined/shipped/delivered/destroyed/pickup |
| customer_id |
int |
否 |
客户ID |
| tracking_no |
string |
否 |
快递单号(模糊搜索) |
| parcel_no |
string |
否 |
包裹编号(模糊搜索) |
| created_start |
string |
否 |
创建开始时间 格式:YYYY-MM-DD |
| created_end |
string |
否 |
创建结束时间 格式:YYYY-MM-DD |
| received_start |
string |
否 |
入库开始时间 格式:YYYY-MM-DD |
| received_end |
string |
否 |
入库结束时间 格式:YYYY-MM-DD |
请求示例
GET /api/parcels?customer_id=1001
GET /api/parcels?tracking_no=SF123456
GET /api/parcels?received_start=2026-01-01&received_end=2026-01-31
创建包裹(创建即入库)- 仅入库员、仓库主管、管理员
请求参数
| 参数名 |
类型 |
必填 |
说明 |
| parcel_no |
string |
是 |
包裹编号 |
| customer_id |
int |
是 |
客户ID |
| tracking_no |
string |
否 |
快递单号 |
| actual_weight |
decimal |
否 |
实际重量(kg),如:2.5 |
| photo_url |
string |
否 |
📸 包裹照片URL(需先通过 /api/upload 上传获取) |
| shelf_location |
string |
否 |
货架位置 |
| is_general_cargo |
int |
否 |
是否普货 0-否 1-是 |
| is_cosmetics |
int |
否 |
是否化妆品 0-否 1-是 |
| is_liquid |
int |
否 |
是否液体 0-否 1-是 |
| is_battery |
int |
否 |
是否含电池 0-否 1-是 |
| customer_remark |
string |
否 |
客户备注 |
| warehouse_remark |
string |
否 |
仓库备注 |
📸 照片上传流程
- 先调用
POST /api/upload 上传照片
- 获取返回的
url
- 在创建包裹时,将
url 传入 photo_url 参数
请求示例
POST /api/parcels
Authorization: Bearer {token}
Content-Type: application/json
{
"parcel_no": "PKG2026010013",
"customer_id": 1001,
"tracking_no": "SF9876543210",
"actual_weight": 2.5,
"photo_url": "http://yourdomain.com/uploads/202601/abc123.jpg",
"shelf_location": "A-01-01",
"is_general_cargo": 1,
"customer_remark": "轻拿轻放"
}
响应示例
{
"code": 201,
"message": "创建并入库成功",
"data": {
"id": 13
}
}
获取单个包裹详情
路径参数
| 参数名 |
类型 |
必填 |
说明 |
| id |
int |
是 |
包裹ID |
请求示例
GET /api/parcels/1
Authorization: Bearer {token}
响应示例
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"parcel_no": "PKG2026010001",
"customer_id": 1001,
"tracking_no": "SF1234567890",
"actual_weight": "2.500",
"photo_url": "http://yourdomain.com/uploads/202601/abc123.jpg",
"status": "received",
"shelf_location": "A-01-01",
"received_at": "2026-01-05 10:30:00"
}
}
处理包裹退货取件 - 仅入库员、仓库主管、管理员
路径参数
| 参数名 |
类型 |
必填 |
说明 |
| id |
int |
是 |
包裹ID |
请求参数
| 参数名 |
类型 |
必填 |
说明 |
| pickup_remark |
string |
是 |
退货取件备注,如退货原因 |
请求示例
POST /api/parcels/1/pickup
Authorization: Bearer {token}
Content-Type: application/json
{
"pickup_remark": "客户要求退货,商品尺寸不合适"
}
成功响应
{
"code": 200,
"message": "退货取件处理成功",
"data": {
"id": 1,
"status": "pickup",
"pickup_at": "2026-01-08 14:30:00"
}
}
📦 合箱包裹管理
获取合箱包裹列表,支持高级搜索和筛选
请求参数(Query Parameters)- 部分参数
| 参数名 |
类型 |
必填 |
说明 |
| page |
int |
否 |
页码,默认1 |
| customer_id |
int |
否 |
客户ID |
| status |
string |
否 |
状态:pending/packed/cancelled |
| packed_start |
string |
否 |
打包开始时间 格式:YYYY-MM-DD |
| packed_end |
string |
否 |
打包结束时间 格式:YYYY-MM-DD |
| weight_min |
decimal |
否 |
最小重量(kg) |
| weight_max |
decimal |
否 |
最大重量(kg) |
请求示例
GET /api/combined-packages?weight_min=2.0&weight_max=5.0
GET /api/combined-packages?packed_start=2026-01-01&packed_end=2026-01-31
创建合箱包裹 - 仅打包员、仓库主管、管理员
请求参数
| 参数名 |
类型 |
必填 |
说明 |
| package_no |
string |
是 |
合箱包裹编号 |
| customer_id |
int |
是 |
客户ID |
| parcel_count |
int |
是 |
包含小包裹数量 |
| parcel_ids |
string |
否 |
包裹ID列表,逗号分隔 |
| remark |
string |
否 |
备注 |
请求示例
POST /api/combined-packages
Authorization: Bearer {token}
Content-Type: application/json
{
"package_no": "CB2026010002",
"customer_id": 1001,
"parcel_count": 3,
"parcel_ids": "1,2,3",
"remark": "待打包"
}
完成打包,录入尺寸和重量 - 仅打包员、仓库主管、管理员
路径参数
| 参数名 |
类型 |
必填 |
说明 |
| id |
int |
是 |
合箱包裹ID |
请求参数
| 参数名 |
类型 |
必填 |
说明 |
| actual_weight |
decimal |
是 |
实际重量(kg) |
| length |
decimal |
是 |
长度(cm) |
| width |
decimal |
是 |
宽度(cm) |
| height |
decimal |
是 |
高度(cm) |
| package_photos |
string |
否 |
📸 打包照片URL列表,多个URL用逗号分隔(需先通过 /api/upload-multiple 上传获取) |
| volume_divisor |
int |
否 |
体积除数,默认6000 |
📸 照片上传流程
- 先调用
POST /api/upload-multiple 上传多张照片
- 获取返回的多个
url
- 将多个URL用逗号连接:
url1,url2,url3
- 在完成打包时,将连接后的字符串传入
package_photos 参数
请求示例
POST /api/combined-packages/1/pack
Authorization: Bearer {token}
Content-Type: application/json
{
"actual_weight": 2.5,
"length": 40,
"width": 30,
"height": 20,
"package_photos": "http://yourdomain.com/uploads/202601/p1.jpg,http://yourdomain.com/uploads/202601/p2.jpg,http://yourdomain.com/uploads/202601/p3.jpg"
}
响应示例
{
"code": 200,
"message": "打包完成",
"data": null
}
💾 数据库更新说明
v1.1.1 新增了以下数据库字段,请执行以下 SQL 语句更新数据库:
ALTER TABLE `parcels`
ADD COLUMN `actual_weight` DECIMAL(10,3) DEFAULT NULL COMMENT '实际重量(kg)' AFTER `is_combined`;
ALTER TABLE `parcels`
ADD COLUMN `pickup_remark` TEXT COMMENT '退货取件备注' AFTER `warehouse_remark`,
ADD COLUMN `pickup_at` DATETIME DEFAULT NULL COMMENT '退货取件时间' AFTER `destroyed_at`,
ADD COLUMN `pickup_operator_id` BIGINT(20) DEFAULT NULL COMMENT '退货取件操作员ID' AFTER `pickup_at`,
ADD COLUMN `pickup_operator_name` VARCHAR(50) DEFAULT NULL COMMENT '退货取件操作员姓名' AFTER `pickup_operator_id`;
ALTER TABLE `parcels`
ADD KEY `idx_pickup_at` (`pickup_at`);