# 菜品优惠接口文档 版本:`v1` 模块:`alien-store` 前缀:`/store/productDiscount` --- ## 统一返回结构 接口返回统一为 `R`: - `code`:200 成功,非 200 失败 - `msg`:提示信息 - `data`:业务数据 --- ## 一、优惠规则接口(已实现) ### 1) 列表 - **URL**:`GET /store/productDiscount/list` - **Query 参数** | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | storeId | Integer | 是 | 门店ID | | productId | Integer | 否 | 菜品ID筛选 | | ruleName | String | 否 | 规则名称模糊搜索 | | status | Integer | 否 | 0关闭,1开启 | | pageNum | Integer | 否 | 默认1 | | pageSize | Integer | 否 | 默认10 | - **返回 data**:`IPage` | 字段 | 类型 | 说明 | |---|---|---| | id | Integer | 规则ID | | storeId | Integer | 门店ID | | productId | Integer | 菜品ID | | productName | String | 菜品名称(当前版本可能为空,见文末说明) | | ruleName | String | 规则名称 | | discountType | String | FREE / DISCOUNT | | discountRate | BigDecimal | 折扣比例(FREE可能为空) | | effectiveMode | String | PERMANENT / CUSTOM | | dateRange | String | 日期范围,如 `2026-04-01 ~ 2026-04-30` 或 `永久生效` | | slotCount | Integer | 时段数量 | | status | Integer | 0关闭,1开启 | | updatedTime | DateTime | 更新时间 | --- ### 2) 详情(编辑回显) - **URL**:`GET /store/productDiscount/detail?id={id}` - **Query 参数** | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | id | Integer | 是 | 规则ID | - **返回 data**:`StoreProductDiscountRuleDetailVo` | 字段 | 类型 | 说明 | |---|---|---| | id | Integer | 规则ID | | storeId | Integer | 门店ID | | productId | Integer | 菜品ID | | productName | String | 菜品名称(当前版本可能为空) | | ruleName | String | 规则名称 | | discountType | String | FREE / DISCOUNT | | discountRate | BigDecimal | 折扣比例 | | effectiveMode | String | PERMANENT / CUSTOM | | startDate | String | 开始日期 yyyy-MM-dd | | endDate | String | 结束日期 yyyy-MM-dd | | status | Integer | 状态 | | slots | Array | 生效时段列表 | `slots` 子项: | 字段 | 类型 | 说明 | |---|---|---| | weekdayMask | Integer | 星期掩码(周一到周日按位) | | startTime | String | HH:mm:ss | | endTime | String | HH:mm:ss | --- ### 3) 新建优惠 - **URL**:`POST /store/productDiscount/create` - **Content-Type**:`application/json` 请求体:`StoreProductDiscountRuleSaveDto` | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | storeId | Integer | 是 | 门店ID | | productId | Integer | 是 | 菜品ID | | ruleName | String | 是 | 规则名称(同店同菜品唯一) | | discountType | String | 是 | FREE / DISCOUNT | | discountRate | BigDecimal | DISCOUNT必填 | 折扣比例(0-100) | | effectiveMode | String | 是 | PERMANENT / CUSTOM | | startDate | String | CUSTOM必填 | yyyy-MM-dd | | endDate | String | CUSTOM必填 | yyyy-MM-dd | | slots | Array | 否 | 生效时段(FREE/DISCOUNT均可不传) | | status | Integer | 是 | 0关闭,1开启 | 请求示例(折扣): ```json { "storeId": 1, "productId": 10001, "ruleName": "周末八折", "discountType": "DISCOUNT", "discountRate": 80, "effectiveMode": "CUSTOM", "startDate": "2026-04-01", "endDate": "2026-06-30", "slots": [ { "weekdayMask": 65, "startTime": "10:00:00", "endTime": "22:00:00" } ], "status": 1 } ``` 请求示例(免费): ```json { "storeId": 1, "productId": 10001, "ruleName": "工作日免费", "discountType": "FREE", "effectiveMode": "PERMANENT", "status": 1 } ``` --- ### 4) 编辑优惠 - **URL**:`POST /store/productDiscount/update` - **Content-Type**:`application/json` - 请求体同“新建”,且 `id` 必填 --- ### 5) 删除优惠 - **URL**:`POST /store/productDiscount/delete?id={id}` | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | id | Integer | 是 | 规则ID | --- ### 6) 切换启用状态 - **URL**:`POST /store/productDiscount/switchStatus?id={id}&status={0|1}` | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | id | Integer | 是 | 规则ID | | status | Integer | 是 | 0关闭,1开启 | --- ## 二、核心校验规则(后端已实现) 1. **名称唯一**:同门店同菜品下,`ruleName` 不可重复 2. **DISCOUNT 规则**:`discountRate` 必填,且仅支持 `effectiveMode=CUSTOM` 3. **CUSTOM 日期**:`startDate/endDate` 必填,且开始不能晚于结束 4. **时间格式**:`startTime/endTime` 必须成对出现,且开始早于结束 5. **时间冲突校验(同店同菜品,开启状态)**: - 日期有交集 - 星期有交集(weekdayMask 按位与 > 0) - 时间有交集(start1 < end2 && start2 < end1) - 若重叠且类型不同:报“该菜品在该时间段已配置其他类型优惠” - 若重叠且类型相同:报“该菜品优惠时间重叠,请调整生效日期/星期/时间” 6. **未配置时段时**:按“全星期+全天”参与冲突判断 --- ## 三、常见错误提示 - `门店ID不能为空` - `菜品ID不能为空` - `规则名称不能为空` - `优惠类型不能为空` - `优惠类型不合法` - `折扣比例不能为空` - `折扣优惠仅支持自定义日期` - `自定义日期开始/结束不能为空` - `开始日期不能大于结束日期` - `生效时间需成对出现` - `生效开始时间必须早于结束时间` - `该菜品优惠名称已存在` - `该菜品在该时间段已配置其他类型优惠` - `该菜品优惠时间重叠,请调整生效日期/星期/时间` --- ## 四、联调注意事项 1. 当前代码中 `productName` 字段映射查询尚未接入真实菜品表查询,返回可能为空;建议联调先以 `productId` 为主。 2. 你提到的“菜品列表(按名称模糊)”接口,目前尚未在本次代码中新增;如需我可补: - `GET /store/product/list?storeId=1&keyword=鱼&pageNum=1&pageSize=10`