4.1 KiB
产品 Step1-5 保存接口 JSR-303 校验真实生效
日期: 2026-04-23 PR: #1270 (Closes #1269) — PR #1259 后续补丁 服务: hl-product-service-v2 / hl-order-service-v2 类型: fix(修复校验漏补)
背景
PR #1259(装备建议字段改条目列表)里 SaveReqVO 加了 JSR-303 校验注解(@NotBlank / @Size(max=20) / @Size(min=1, max=50)),但 AdminProductController 的 Controller 方法未加 @Valid 修饰符,校验注解实际未触发。非法数据仍能 200 入库。
本次补丁把 Step1-5 全部保存接口及一个订单接口补齐 @Valid,校验现在真实生效。
影响接口(9 处)
| 接口 | Method |
|---|---|
POST /admin/product/item/basic |
saveBasic |
POST /admin/product/item/{id}/itinerary |
saveItinerary |
POST /admin/product/item/{id}/route |
saveRoute |
POST /admin/product/item/{id}/price-calendar/batch |
savePriceCalendar |
POST /admin/product/item/{id}/schedule |
saveSchedule(2 个) |
POST /admin/product/item/{id}/schedule/batch |
batchCreateSchedule |
PUT /admin/product/item/{id}/supplement |
saveSupplement |
PUT /admin/product/item/{id}/detail-blocks |
saveDetailBlocks |
DELETE /admin/order/{orderId}/itinerary/pending/{editId} |
withdrawPendingEdit |
行为变化(前端必读)
之前(PR #1270 前)
PUT /admin/product/item/{id}/supplement
{
"equipmentList": [
{"text": ""} // 非法:空 text
]
}
→ 200 OK(错误地通过!数据存入 DB)
之后(PR #1270 后)
PUT /admin/product/item/{id}/supplement
{
"equipmentList": [
{"text": ""}
]
}
→ 400 {
"code": 400,
"success": false,
"message": "equipmentList[0].text: 装备文案不能为空"
}
装备建议校验规则(生效中)
| 规则 | 违反时错误消息 |
|---|---|
equipmentList 条目数 ≤ 20 |
equipmentList: 装备建议条目数不能超过20条 |
单条 text 非空非空白 |
equipmentList[0].text: 装备文案不能为空 |
单条 text 长度 1-50 字 |
equipmentList[0].text: 装备文案长度需在 1-50 字符之间 |
注意错误消息格式:{字段路径}: {消息},含数组索引([0]、[1] 等),前端可精确定位哪条条目出错。
前端建议
1. 前置校验(推荐)
admin 编辑器在提交前自行 validate 一次:
- 条目数 > 20 → 禁止提交 + toast
- 单条 text 空 → 禁止提交 + 红色高亮
- 单条 text 长度 > 50 → 禁止提交 + 高亮
避免走到后端才发现,体验更好。
2. 后端报错展示(兜底)
如果绕过了前置校验,后端 400 返回的 message 字段可直接 toast:
const resp = await api.saveSupplement(req);
if (resp.code !== 200) {
ElMessage.error(resp.message || '保存失败');
return;
}
错误消息已中文化,直接展示即可。
3. 数组索引提示
如果要做精细错误提示,可解析 equipmentList[N].text 中的 N,滚动聚焦到对应条目输入框。
其他接口的校验
basic / itinerary / route / price-calendar / schedule 等其他 Step 接口的 SaveReqVO 本来就有 JSR-303 注解,但同样因为缺 @Valid 没有生效。本次补丁一起修复。
常见校验约束(以 ProductBasicSaveReqVO 为例):
productType非空name长度 ≤ 30 字tripDays≥ 1- 具体以 Knife4j
@ApiModelProperty中的required/allowableValues为准
如果前端之前传错数据能 200,现在可能 400,请以实际接口返回为准调整。
向后兼容
- 合法请求:行为不变,仍 200
- 非法请求:从"假成功(200 入脏数据)"变为"正确失败(400 + 可读消息)"
- 属于修复性变化,非破坏性
验证
测试服网关已 curl 4 场景全过:
# 合法 3 条 → 200
# 21 条 → 400 equipmentList: 装备建议条目数不能超过20条
# 空 text → 400 equipmentList[0].text: 装备文案不能为空
# 51 字 text → 400 equipmentList[0].text: 装备文案长度需在 1-50 字符之间