hl-api-changelog/changelogs/2026-04/30_fix_product_fee-deduction-display-label-no-prefix.md

4.4 KiB

修复: 费用包含 feeType 改名 景区/游玩项目 + name 去前缀

类型: 后端 BUG 修复(PR #1579 双 follow-up) 关联: 工单 #1580 / PR #1581 + 工单 #1582 / PR #1583 日期: 2026-04-30 前端处理者: mmg 影响范围: 管理后台「产品编辑 → 补充信息 → 费用说明 →『根据行程自动生成』」按钮


演进链(完整 5 PR)

PR 行为 产品 2045018534152478721 返回
#1568 修复漏景区/活动/酒店,每节点 1 条 35 条
#1577 按名字去重,name 改具体名 17 条
#1579 按 feeType 合并,name="门票xxx" 3 条(有 feeType 前缀)
#1581 feeType 改名 门票→景区,活动→游玩项目 3 条(name="景区xxx")
#1583 name 去 feeType 前缀,只剩名字拼接 3 条(name="黑山头,...")

用户反馈

  • 「怎么没分为 景区 游玩项目」(→ PR #1581:feeType 改名)
  • 「不要我圈出来的直接显示名字就行」(→ PR #1583:name 去前缀)

字段语义

字段
feeType 景区 / 游玩项目 / 住宿 / 餐饮 / 交通(展示名,前端 chip 用)
name "黑山头,白桦林景区,莫日格勒河,..." 仅名字拼接(中文「,」分隔)
sourceNodeName null
icon null(PR #1573 行为)

实现要点

// PR #1581: 加 displayLabel 私有静态映射
private static final Map<String, String> FEE_LABEL_DISPLAY = Map.of(
    "门票", "景区",        // 用户期望
    "活动", "游玩项目",   // 用户期望
    "住宿", "住宿",
    "餐饮", "餐饮",
    "交通", "交通"
);

// PR #1583: name 去前缀,直接 join
.map(e -> {
    String displayLabel = toDisplayLabel(e.getKey());
    String joinedNames = String.join(",", e.getValue());
    return FeeDeductionPreviewVO.builder()
        .feeType(displayLabel)        // chip 用展示名
        .name(joinedNames)            // 仅名字列表,无 feeType 前缀
        .source(SOURCE_AUTO)
        .sourceNodeName(null)
        .build();
})

底层逻辑保持:

  • 分组 key 仍是 feeLabel("门票"/"活动"/"住宿"等)
  • 排序 key 仍按 feeLabel(门票 → 活动 → 住宿 → 餐饮 → 交通)
  • feeIgnoredTypes 过滤仍按 feeLabel(保护历史数据兼容)
  • NodeTypeEnum.getFeeLabel() 不动(防止影响别处)

影响接口

方法 路径 改动
GET /admin/product/item/{id}/fee-deduction-preview feeType 字段值改为展示名(景区/游玩项目),name 字段去掉前缀

请求签名完全不变,响应字段不变。

响应示例

GET /admin/product/item/2045018534152478721/fee-deduction-preview
{
  "code": 200,
  "data": [
    {
      "feeType": "景区",
      "name": "黑山头,白桦林景区,莫日格勒河,莫日格勒河断崖,呼伦湖,阿尔山火车站",
      "source": "AUTO",
      "sourceNodeName": null,
      "icon": null
    },
    {
      "feeType": "游玩项目",
      "name": "ATV全地形越野车穿越,驯鹿拉车体验",
      "source": "AUTO",
      "sourceNodeName": null,
      "icon": null
    },
    {
      "feeType": "住宿",
      "name": "海拉尔洲季酒店,呼伦贝尔香格里拉大酒店,额尔古纳玖成万豪水汇智能酒店,额尔古纳豪星酒店,额尔古纳白桦大酒店,海拉尔海棠酒店,满洲里饭店(百年俄式),敖根栖息地,阿尔善国际维景度假温泉酒店",
      "source": "AUTO",
      "sourceNodeName": null,
      "icon": null
    }
  ]
}

(注:实际中文逗号是「,」非半角)

前端要做的改动

0 改动。前端 chip {{ item.feeType }} 显示「景区/游玩项目/住宿」,文字 {{ item.name }} 显示纯名字列表,UI 无重复无冗余。

测试覆盖

  • PR #1581:mvn test 1047/1047 全绿,加 feeDeductionPreview_displayLabelTranslation 验证 SCENIC→景区 / ACTIVITY→游玩项目 映射
  • PR #1583:21 处 name 断言批量去前缀,ProductValidationServiceTest 53/53 全绿

测试服 round-trip(产品 2045018534152478721)实测:

  • 3 条返回
  • feeType: 景区 / 游玩项目 / 住宿(顺序固定)
  • name: 黑山头,白桦林景区,... / ATV全地形越野车穿越,驯鹿拉车体验 / 海拉尔洲季酒店,呼伦贝尔香格里拉大酒店,...(无前缀)
  • sourceNodeName / icon 全 null

部署状态

  • Deploy Panel 已部署测试服 hl-product-service-v2 双实例(2026-04-30 17:25)
  • 正式环境暂未发布(等 dev → main release PR)