# 后端 fix 通知 — admin 产品分享 2 项回归已修复

**日期**: 2026-05-09
**类型**: 后端修复 (PR #1919 内部回归)
**模块**: 产品管理 → 产品列表 → **分享产品**(ShareModal)
**通知**: @mmg
**前端是否需改动**: 否(响应 schema 不变)
**严重性**: 高 (P1)→ 已修

---

## ⚠️ 关键变化

PR #1919 (Closes #1918) 实现的产品分享接口 `POST /admin/product/item/{id}/share` 上线后,经测试服真实跑发现 2 个 P1 回归 BUG。**PR #1924 (commit `e6a54fde`)** 已修复并合 dev、测试服已部署、QA 已复测通过:

1. **产品名后缀英文括号 → 中文全角括号**(契约/Swagger/前端通知约定的就是中文全角)
2. **fee_item 深拷贝丢数据**(原本可能丢 60-70%,现已全量复制)

前端**无需做任何改动**,响应 schema / 字段 / 语义都不变,只是落库/响应里的实际数据现在符合契约。

---

## BUG #1 — 产品名后缀字符

**修前**:`新产品名(来自admin的分享)` (英文半角括号 U+0028 / U+0029)
**修后**:`新产品名（来自admin的分享）` (中文全角括号 U+FF08 / U+FF09)

**前端验收**:
- ShareModal 调 share 接口后跳转到新产品编辑页,标题应显示中文全角括号后缀。
- 不需要前端代码做任何字符判断/兼容,直接展示后端返回的 `newProductName` 即可。

---

## BUG #2 — fee_item 深拷贝丢数据

**修前**:源产品 fee_item N 条 → 新产品仅复制部分(实测 27 → 9,部分类别全丢),原因是 MyBatis-Plus `Db.saveBatch` 的 KeyGenerator 在批处理 reuse PreparedStatement 场景下时机不可靠,部分行 id 注入失败触发 NOT NULL 约束冲突被静默跳过。

**修后**:`ProductCopyService.copyOneToMany` 显式 `IdWorker.getId()` 预分配雪花 id,根除丢条。同步把 itinerary 节点/酒店/路线点的 `setId(null)` 也改为预分配,语义统一。

**前端验收**:
- 分享后跳转到新产品的"费用项"配置页,条目数应等于源产品费用项条目数,且每条字段一致。

---

## 测试服已验证(2026-05-09 20:45+)

```
POST /admin/product/item/2044704111294672897/share  body {"targetAdminId":1002}
→ 200, newProductName 末字符 U+FF09 ✅
→ DB product.name 落库为「...（来自admin的分享）」中文全角 ✅
→ DB product_fee_item COUNT(*) = 源产品全量,id 全部 NOT NULL 互不重复 ✅
```

---

## 不影响范围

- 接口契约(URL / Method / 请求 VO / 响应 VO)零变化
- 鉴权 / 校验 / 幂等逻辑零变化
- 其他复制场景(`POST /admin/product/item/{id}/copy` 老接口)同步受益(同一 `copyOneToMany` 修复路径)

---

## 相关 PR

| PR | 说明 | 状态 |
|----|------|------|
| #1919 | 实现 admin 分享产品功能 (Closes #1918) | ✅ 已合 dev,但暴露 2 个回归 |
| **#1924** | **本通知关联**:修复 #1919 暴露的 2 个 P1 回归(中文括号 + fee_item 全量复制) | ✅ 已合 dev + 测试服已部署 + QA 通过 |

---

**联系人**: wx
