# 【修改接口·管理后台】车型价格日历——三模式调价(ABS/DELTA/PERCENT)+节假日筛选+互斥校验落地(§9 全块说明) > 服务:hl-fleet-service(8087) | 分支:dev-v3 | PR:#3714 | 已部署测试服并 22 项 API 实测通过(2026-06-12) > 契约出处:FLEET API §9.1-§9.4(文档已同 PR 更新至 v1.5.61) | 前端触发位:车管控制台「价格日历」页(page_pricing 原型 BulkPriceSheet) > 本文是价格日历**整块 4 接口的完整说明**(应后端要求全面同步),已上线功能 + 本次新增一并列出,前端可按本文直接对接。 ## ⚠️ 关键说明 1. **完全向后兼容,已对接代码零改动**:本次新增字段全部可选。不传 `adjustMode` 默认 `ABS`(固定价),与原行为完全一致。 2. **新增三模式调价**(本次 PR):`adjustMode` = `ABS`(设为固定价) / `DELTA`(在各日现价上加减金额) / `PERCENT`(按百分比调整)。`DELTA`/`PERCENT` 时 `dayPrice` 不需要传,改传 `adjustValue`。 3. **DELTA/PERCENT 的基准价规则**:命中日已设价 → 用当日现价计算;未设价 → 用车型 `basePrice` 兜底;两者都没有 → **该日跳过不写**(不报错)。计算结果 < 0 一律按 `0.00` 落库。`PERCENT` 结果四舍五入保留两位(HALF_UP)。 4. **新增仅节假日筛选**(本次 PR):`holidayOnly=true` 只设置节假日(节假日清单由后端 Nacos 配置维护,**当前为验证占位日期,业务法定节假日清单待车管确认后由后端配置**,前端无需关心数据源)。 5. **三筛选互斥**(本次 PR,行为变更):`weekdayOnly` / `weekendOnly` / `holidayOnly` 同时传两个及以上 `true` → 返 `code=400` 参数错(此前是静默 0 命中返成功,**前端若有依赖旧静默行为的逻辑请注意**)。 6. **金额字段两位小数**(本次 PR):`dayPrice`/`adjustValue` 传超过 2 位小数返 `code=400`。 7. **防双击/并发**(本次 PR):三个写端点(批量设价/批量改状态/区间清除)都加了幂等(同参数 3 秒窗口重复提交返「…处理中,请勿重复提交」)+ 同车型并发互斥锁。前端连点按钮会收到 400 类提示,正常单次操作无感。 8. **错误码口径勘正**:参数校验失败统一返业务码 **400**(HTTP 恒 200,错误信息在 `message`)。文档旧版写的 `400001` 为笔误,以 400 为准。 9. 所有金额出参为**字符串**(如 `"800.00"`),雪花 ID 出参为字符串,前端勿当数字解析。 ## 1. 查询价格日历(月视图) — 无变更,完整契约 `GET /admin/fleet/pricing-calendar/{vehicleModelId}?year=2026&month=3` | 参数 | 位置 | 类型 | 必填 | 说明 | |---|---|---|---|---| | vehicleModelId | path | string | 是 | 车型型号 ID(车型树 models[].id) | | year | query | number | 是 | 年份(2020-2100,越界返 400) | | month | query | number | 是 | 月份(1-12,越界返 400) | ### 请求示例 ```bash curl -k "https://web.test.1814.love:9443/admin/fleet/pricing-calendar/2057378612593823745?year=2099&month=1" \ -H "Authorization: Bearer {token}" ``` ### 响应示例(测试服实测) ```json { "code": 200, "message": "成功", "data": { "year": 2099, "month": 1, "vehicleModelId": "2057378612593823745", "modelName": "丰田普拉多", "prices": [ { "date": "2099-01-01", "dayPrice": "800.00", "status": "AVAILABLE", "remark": "旺季价格" }, { "date": "2099-01-08", "dayPrice": "900.00", "status": "CLOSED", "remark": "临时停租" } ] } } ``` | 出参字段 | 说明 | |---|---| | prices | **仅返回已设置价格的日期**(未设价日期不出现,空月返回空数组) | | prices[].dayPrice | 当日租赁价,**字符串**两位小数 | | prices[].status | 可售状态:`AVAILABLE`=可售 / `CLOSED`=关闭 | ## 2. 批量设置价格 — 本次新增三模式/节假日/互斥,完整契约 `PUT /admin/fleet/pricing-calendar/{vehicleModelId}` ### 入参(body) | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | startDate | string | 是 | 开始日期 yyyy-MM-dd | | endDate | string | 是 | 结束日期,须 ≥ startDate 且总天数 ≤ 366 | | adjustMode | string | 否 | 🆕 调价模式:`ABS`=设为固定价 / `DELTA`=现价加减金额 / `PERCENT`=现价按百分比调;**不传默认 ABS**(向后兼容);非法值返 400 | | dayPrice | string | ABS 必填 | 当日租赁价(¥,≥0,两位小数)。**仅 ABS 模式必填且生效**,DELTA/PERCENT 不需要传 | | adjustValue | string | DELTA/PERCENT 必填 | 🆕 调整值:DELTA=加减金额(可负,如 `-100.00`) / PERCENT=百分比数值(`10`=+10%,`-5`=-5%)。两位小数 | | status | string | 否 | `AVAILABLE` / `CLOSED`,不传默认 AVAILABLE,非法值返 400 | | remark | string | 否 | 备注 | | weekdayOnly | boolean | 否 | 仅工作日(命中周末跳过) | | weekendOnly | boolean | 否 | 仅周末(命中工作日跳过) | | holidayOnly | boolean | 否 | 🆕 仅节假日(命中非节假日跳过,节假日清单后端 Nacos 维护) | | selectedWeekdays | number[] | 否 | 指定星期几(1=周一…7=周日),非空则只设命中星期 | | excludeDates | string[] | 否 | 排除日期列表(区间内这些日期不设置) | > ⚠️ `weekdayOnly`/`weekendOnly`/`holidayOnly` **互斥**,≥2 个同时 true 返 400「工作日/周末/节假日筛选不可同时启用」。 ### 请求示例 1——固定价(原有用法,完全不变) ```bash curl -k -X PUT "https://web.test.1814.love:9443/admin/fleet/pricing-calendar/2057378612593823745" \ -H "Authorization: Bearer {token}" -H "Content-Type: application/json" \ -d '{"startDate":"2099-01-01","endDate":"2099-01-05","dayPrice":"800.00","remark":"旺季价格"}' ``` ### 请求示例 2——🆕 全月工作日涨 100 元(DELTA) ```bash curl -k -X PUT "https://web.test.1814.love:9443/admin/fleet/pricing-calendar/2057378612593823745" \ -H "Authorization: Bearer {token}" -H "Content-Type: application/json" \ -d '{"startDate":"2099-01-01","endDate":"2099-01-31","adjustMode":"DELTA","adjustValue":"100","weekdayOnly":true}' ``` ### 请求示例 3——🆕 节假日统一上浮 15%(PERCENT + holidayOnly) ```bash curl -k -X PUT "https://web.test.1814.love:9443/admin/fleet/pricing-calendar/2057378612593823745" \ -H "Authorization: Bearer {token}" -H "Content-Type: application/json" \ -d '{"startDate":"2099-01-01","endDate":"2099-01-31","adjustMode":"PERCENT","adjustValue":"15","holidayOnly":true}' ``` ### 响应 成功:`{ "code": 200, "message": "成功" }`(无 data) ### 测试服实测数据点(可作前端联调预期) | 操作 | 结果 | |---|---| | ABS 800 后 DELTA +100 | 900.00 | | 900 后 PERCENT -10 | 810.00 | | DELTA +100 作用于未设价日(车型 basePrice=1000) | 1100.00 | | DELTA -99999(负穿) | 0.00(兜底) | | holidayOnly=true,区间 11 天含 1 个节假日 | 仅节假日 1 天写入 | | weekdayOnly+weekendOnly 同 true | code=400 | | adjustMode="FOO" / DELTA 缺 adjustValue / ABS 缺 dayPrice / dayPrice 三位小数 | code=400 | ## 3. 批量修改状态 — 无变更(新增幂等防护),完整契约 `PUT /admin/fleet/pricing-calendar/{vehicleModelId}/status` | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | startDate | string | 是 | 开始日期 yyyy-MM-dd | | endDate | string | 是 | 结束日期 | | status | string | 是 | `AVAILABLE` / `CLOSED`,非法值返 400 | | remark | string | 否 | 备注;**不传则保留各记录原备注** | 只改区间内**已有记录**的状态(不影响价格,未设价日期不会凭空建记录)。 ```bash curl -k -X PUT "https://web.test.1814.love:9443/admin/fleet/pricing-calendar/2057378612593823745/status" \ -H "Authorization: Bearer {token}" -H "Content-Type: application/json" \ -d '{"startDate":"2099-01-01","endDate":"2099-01-31","status":"CLOSED","remark":"临时停租"}' ``` 成功:`{ "code": 200, "message": "成功" }` ## 4. 清除价格日历 — 无变更(新增幂等防护),完整契约 `DELETE /admin/fleet/pricing-calendar/{vehicleModelId}?startDate=2099-01-01&endDate=2099-01-31` | 参数 | 位置 | 类型 | 必填 | 说明 | |---|---|---|---|---| | startDate | query | string | 是 | 开始日期 yyyy-MM-dd | | endDate | query | string | 是 | 结束日期 | 软删除区间内该车型全部价格记录;删后**可重新设置同日价格**(测试服实测通过)。 ```bash curl -k -X DELETE "https://web.test.1814.love:9443/admin/fleet/pricing-calendar/2057378612593823745?startDate=2099-01-01&endDate=2099-01-31" \ -H "Authorization: Bearer {token}" ``` 成功:`{ "code": 200, "message": "成功" }` ## 5. 错误码表(§9 全块) | code | message | 触发场景 | 涉及端点 | |---|---|---|---| | 400 | (具体校验消息) | 参数校验失败:必填缺失/格式错/枚举非法/互斥冲突/超两位小数/year·month 越界 | 全部 | | 600500 | 日租价不能为负 | dayPrice < 0(防御兜底,正常会先被 400 拦) | §9.2 | | 600501 | 日期范围非法:开始日期不能晚于结束日期 | startDate > endDate | §9.2 | | 600502 | 日期范围不能超过 366 天 | 区间总天数(含首尾) > 366 | §9.2 | | 600503 | 车型型号不存在 | vehicleModelId 无效/已软删 | §9.1 / §9.2 / §9.3 | | 401 | 未登录 | token 缺失/过期 | 全部 | > §9.4 清除接口不校验车型存在性(按契约,清不存在车型的区间等于无操作返 200)。 > HTTP 状态码恒 200,业务错误看 `code` 字段。