hl-api-changelog/changelogs-v2/2026-06/03_3389_资源默认收费+收费否禁价格日历+退费说明接入-管理后台.md

6.4 KiB

【需求·管理后台】资源默认收费 + 收费=否禁价格日历 + 退费说明接入(景区 / 活动 / 酒店)

PR: #3392 #3395工单 #3389 服务: hl-resource-service | 更新时间: 2026-06-03 存放目录: changelogs-v2/2026-06/ 影响范围: 管理后台「资源管理 / 景区·游玩项目·酒店」编辑页 状态: 已合并 dev-v3 + 测试服部署双实例 + API 实测通过

⚠️ 关键说明

来自景区编辑页的 3 点反馈,后端已处理(部分是前端没接已实现的接口):

  1. 默认收费:景区 / 游玩项目 / 酒店新建时「是否收费」默认改为 收费(1)。前端开关初始态请置为「收费」开。
  2. 收费=否 → 没有价格日历:前端在「是否收费=否」时隐藏价格日历区;后端已加兜底——给收费=否的景区 / 活动设价会被拒(错误码 390901)。
  3. 价格日历不做合并接口:基本信息与价格日历仍是两个接口,前端保存时分两次调(先存基本信息,再批量设价)。
  4. 退费说明:后端早已实现(/admin/refund-note,覆盖景区+活动),前端编辑页缺这块 UI,本文补齐接口契约请接入。

服务资源 ServiceItem 的「是否收费」是 isPaid+真实定价语义(另有定价校验),不在本次默认收费范围,保持现状。

1. 默认收费(景区 / 活动 / 酒店)

新建资源不传 isCharged 时,后端默认 1=收费;前端显式传 0 仍尊重为「否」。

资源 字段 新建接口 默认值
景区 Scenic isCharged POST /admin/scenic/spot 1=收费
游玩项目 Activity isCharged POST /admin/activity/item 1=收费
酒店 Hotel isCharged POST /admin/hotel/item 1=收费

前端动作:新建表单「是否收费」开关初始置「收费(开)」。编辑回显仍读后端返回的 isCharged

2. 收费=否 → 无价格日历

2.1 前端

「是否收费=否」时隐藏价格日历区(不展示、不允许设价)。

2.2 后端兜底(防脏数据)

对收费=否(isCharged=0)的景区 / 活动调批量设价接口,后端直接拒绝:

# 收费=否的景区设价 → 被拦截
curl -X PUT -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
  -d '{"startDate":"2026-07-01","endDate":"2026-07-03","costPrice":100,"status":1}' \
  "https://api.test.1814.love:9443/admin/scenic/spot/{scenicId}/prices"

响应(测试服实测):

{ "code": 390901, "message": "资源未设为收费,不可设置价格日历" }
  • 仅拦批量设价 PUT /spot/{id}/prices;查询、改可售状态、清除价格不受影响。
  • 酒店价格日历是 room-type 级,本期不做后端兜底,前端按 2.1 隐藏即可。

3. 价格日历保存方式(分两次调,不合并接口)

经确认不新增合并接口。前端编辑保存时分两次调用现有接口:

  1. 先存基本信息:PUT /admin/scenic/spot/{scenicId}
  2. 再批量设价:PUT /admin/scenic/spot/{scenicId}/prices(仅在收费=是时调)

4. 退费说明接入(景区 / 活动)

⚠️ 本节已废弃2026-06-03 更新):退费说明已改为融合进资源编辑接口(不再走独立 /admin/refund-note),并扩展支持服务 SERVICE。前端请按新 changelog 03_3406_退费说明融合进资源编辑接口-景区活动服务-管理后台.md 接入,勿按下方独立接口接。下方内容仅作历史留存。

后端模块早已上线PR #3273 等),前端编辑页缺 UI,请接入。仅覆盖 SCENIC / ACTIVITY 两类。

4.1 接口表

操作 方法 / 路径 参数
查询 GET /admin/refund-note query: resourceType(SCENIC/ACTIVITY) + resourceId。未配置返 data:null(不报错)
保存(upsert) PUT /admin/refund-note body: RefundNoteSaveReqVO按 resourceType+resourceId upsert 整块)
删除(软删) DELETE /admin/refund-note query: resourceType + resourceId(幂等,未配置也返 code:200 data:false

4.2 保存请求体RefundNoteSaveReqVO

字段 类型 必填 说明
resourceType String SCENIC / ACTIVITY
resourceId Long 关联资源 ID
intro String 资源级备注≤255 字),如「苔藓为赠送项目,不退费」
items List 退费明细,至少 1 条、最多 50 条

items[] 每项RefundNoteItemVO

字段 类型 必填 说明
title String 展示标题,如「成人未参加」
amount BigDecimal 退费金额(赠送项目填 0
unitLabel String 展示文案 /人 /团 /辆
settleScope String 结算粒度 PER_PERSON / PER_TEAM / PER_VEHICLE
settleScopeLabel String 结算粒度中文名(出参后端拼,入参可省)
remark String 备注,如「仅限儿童」
effectiveFrom LocalDate 规则生效起日null=无限制)
effectiveTo LocalDate 规则生效止日null=无限制)

4.3 示例

# 查询景区退费说明
curl -H "Authorization: Bearer <token>" \
  "https://api.test.1814.love:9443/admin/refund-note?resourceType=SCENIC&resourceId=3001000000000000019"

# 保存
curl -X PUT -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
  -d '{
    "resourceType": "SCENIC",
    "resourceId": 3001000000000000019,
    "intro": "苔藓为赠送项目,不退费",
    "items": [
      {"title":"成人未参加","amount":44.00,"unitLabel":"/人","settleScope":"PER_PERSON","remark":"仅限成人"}
    ]
  }' \
  "https://api.test.1814.love:9443/admin/refund-note"

查询响应RefundNoteRespVOnoteId / resourceType / resourceId / intro / items[] / createTime / updateTimenoteId 字符串透传防精度丢失,settleScopeLabel 后端回填中文。

5. 前端动作清单

  1. 景区 / 活动 / 酒店新建表单「是否收费」开关默认置「收费」。
  2. 「是否收费=否」时隐藏价格日历区(编辑页 + 新建页)。
  3. 保存仍分两次调(基本信息 + 价格日历),价格日历仅收费=是时调。
  4. 景区 / 活动编辑页接入「退费说明」模块GET/PUT/DELETE /admin/refund-note)。