diff --git a/changelogs/2026-05/08_refactor_resource_extract_reference_check_helper.md b/changelogs/2026-05/08_refactor_resource_extract_reference_check_helper.md new file mode 100644 index 0000000..25e43e0 --- /dev/null +++ b/changelogs/2026-05/08_refactor_resource_extract_reference_check_helper.md @@ -0,0 +1,59 @@ +--- +date: 2026-05-08 +type: backend-refactor +module: hl-resource-service +priority: low +notify: ["@mmg"] +status: tested-passed +restart_service: hl-resource-service +gitea_pr: 1841 +gitea_issue: [] +--- + +# 资源服务 ResourceReferenceCheckHelper 抽取(纯重构,前端无感) + +## 背景 + +PR #1838 引入 fail-closed 后,resource service 11 个文件 16 处调用点重复 8-10 行 `productFeignClient.checkResourceInUse + isSuccess + throw + getData + 被引用 throw` 模板。 + +PR #1841 抽取到 `ResourceReferenceCheckHelper`,2 个公开方法: +- `throwIfInUse(type, id, errorCode)` — 单删除/下架场景 +- `getReferencingProducts(type, id)` — batchDelete 累积场景 + +每处调用点 8-10 行 → 1 行 helper 调用,**净减 178 行**(35 文件 +177/-355,加 helper+test +271 = 净增 87)。 + +## 前端可见变化 + +**完全无变化** — API 行为/响应/业务码全部保持一致。前端不需要任何改动。 + +测试服 round-trip 实测 (PR #1838 同样反例): +``` +DELETE /admin/scenic/spots/batch ids=[3001000000000000016] +HTTP=200 code=200 +data={successCount:0, deniedIds:["3001000000000000016"], + deniedReasons:["被产品使用: 结婚不回家、带孩子, 看一次真正的草原。、...(13 个产品名)"]} +post-check GET 景区仍存在 ✅ +``` + +## 重启服务 + +测试服已部署:`hl-resource-service`(PR #1841 合 dev → deploy panel)。 + +## 改造范围 + +11 个 service 文件 16 处调用点全部统一改用 helper: + +- ScenicSpotService 4 处(updateStatus / batchUpdateStatus / batchDelete / submitApproval) +- StaffService 2 处 / SuppliesService 2 处 +- HotelService / RoomTypeService / RestaurantService / ActivityService / ServiceItemService / SuppliesComboService / VehicleModelService / CostItemService 各 1 处 + +22 个既有 service test 同步切 mock(`ProductFeignClient` → `ResourceReferenceCheckHelper`)。 + +## 关联 + +- PR #1838 / #1839 / Issue #1821(纯重构 follow-up,无新工单) + +## Follow-up(本 PR 不修) + +- 余下 PR #1838 follow-up 项: RoomType 禁用按 HOTEL 维度校验语义偏严 / `product_itinerary_node(resource_type, resource_id)` 复合索引 / batchDelete TOCTOU 时序问题 +- 单测加 H2 集成测试或 @MybatisPlusTest 真跑 SQL 防止 mock 单测假阳(memory `experience/qa/mock-tests-pass-cr-pass-but-prod-schema-mismatch-real-deletes-2-resources.md`)