From 0bbb1bb9f9b12c90e4323f3d0abc48a00353cb0b Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Fri, 22 May 2026 22:50:38 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20/mp/customizer/me=20=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E5=88=A4=E5=AE=9A=20P0=20=E4=BF=AE=E5=A4=8D=20+=20=E7=BD=91?= =?UTF-8?q?=E5=85=B3=E7=99=BD=E5=90=8D=E5=8D=95=20+=20sharerOpenid=20?= =?UTF-8?q?=E7=A9=BA=E4=B8=B2=20(#2922=20/=20PR=20#2923)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../22_fix_customizer_role_check_bug.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 changelogs/2026-05/22_fix_customizer_role_check_bug.md diff --git a/changelogs/2026-05/22_fix_customizer_role_check_bug.md b/changelogs/2026-05/22_fix_customizer_role_check_bug.md new file mode 100644 index 0000000..5999453 --- /dev/null +++ b/changelogs/2026-05/22_fix_customizer_role_check_bug.md @@ -0,0 +1,108 @@ +# fix: /mp/customizer/me 错把非定制师 admin 当定制师 + 网关白名单 + sharerOpenid 空串 (P0) + +> **仓库**: HL (后端 hl-user-service + hl-mp-service + hl-gateway + hl-order-service-v2) +> **关联 PR/Issue**: PR #2923, Closes #2922 +> **日期**: 2026-05-22 +> **影响范围**: `/mp/customizer/me` 接口 + 客人下单 sharerOpenid 反查 + 网关白名单 +> **接收方**: mmg (前端) +> **前端**: **可能需要调整** — 之前依赖 `/mp/customizer/me` 给非定制师 admin 显示分享按钮的行为现在不再生效(本就是 bug),前端逻辑无需改 + +--- + +## 🚨 关键修复 + +### 1. P0: 非定制师 admin 被错判成定制师 + +`GET /mp/customizer/me` 之前的实现 (`#2907` 引入) 仅过滤 `admin_user.mobile + status=ACTIVE`,**不校验 CUSTOMIZER 角色**。导致: + +- 运营/财务/客服等**任意活跃 admin** 用本人手机号 SMS 登录 C 端小程序,前端会看到「分享」按钮 +- 转发后客人下单时被 `CustomizerValidator` 角色校验拒绝 +- **订单悄悄给随机定制师**,前端无任何感知 +- 生产风险: 分润纠纷 / 「为啥我分享了订单没给我」客诉 + +**修复**:`AdminUserService.getCustomizerByMobileForFeign` 加 CUSTOMIZER 角色过滤,非定制师 admin 直接返 null。 + +**联动收益**: `OrderCreateService.resolveSharedCustomizerId` 反查链路也自动受益,sharerOpenid 反查到的 admin 必然是定制师身份。 + +### 2. P1-2: `/mp/customizer/me` 未登录直接 401 卡 UI + +`JwtAuthFilter.OPTIONAL_AUTH_URLS` 之前只含 `/mp/product/*` `/mp/explore/*`,**`/mp/customizer/me` 走 MANDATORY** 未登录直接 401,跟 `MpCustomizerController.userId == null` 兜底分支设计冲突。 + +**修复**: 加 `/mp/customizer/me` 到 OPTIONAL_AUTH_URLS,未登录返 `isCustomizer: false`。 + +### 3. P1-4: sharerOpenid 空串导致下单 400 + +`MpCreateOrderRequest.sharerOpenid` + `MpOrderSaveReqVO.sharerOpenid` `@Pattern("^[a-zA-Z0-9_-]+$")` 不接受空串。前端从 `onLaunch.options.sharerOpenid` 拿值,**误传 `""` 整个下单 400**。 + +**修复**: `@Pattern` 改 `^$|^[a-zA-Z0-9_-]+$` 接受空串。 + +--- + +## 一、API 行为变化 + +### `GET /mp/customizer/me` + +| 调用方 / 场景 | 之前 | **现在** | +|---|---|---| +| 未登录 | 401 Missing Authorization | **200 + `{isCustomizer: false, adminId: null, customizerName: null, customizerAvatar: null}`** | +| 已登录但 `user.phone` 为空 | 同左 | 同左 (`isCustomizer: false`) | +| 已登录, `user.phone` 在 admin_user 找到对应 ACTIVE admin **但不是 CUSTOMIZER 角色** | **错误返 `isCustomizer: true` + 该 admin 信息** (P0 bug) | **`isCustomizer: false`** (修复后) | +| 已登录, `user.phone` 对应有 CUSTOMIZER 角色的 admin | `isCustomizer: true` + admin 信息 | 同左 | + +### `POST /mp/order/create` + +| 场景 | 之前 | 现在 | +|---|---|---| +| `sharerOpenid` 字段传 `""` 空串 | 400 Bad Request `@Pattern 不匹配` | **200 OK** (走兜底 `assignRandomCustomizer`) | +| `sharerOpenid` 传定制师 openid | 反查 user.phone → admin 任意活跃 admin (P0 bug) | **反查仅 CUSTOMIZER 角色 admin**,非定制师 sharerOpenid 走兜底 | + +--- + +## 🚨 前端需要做的事 + +### 1. 不再依赖 P0 bug + +之前如果前端依赖"非定制师 admin 也能看到分享按钮"的行为 (这本身是 bug),现在该行为修正。前端按 `data.isCustomizer` 字段渲染即可,**逻辑无需改**。 + +### 2. 可选: 未登录场景预渲染 + +由于 `/mp/customizer/me` 现在支持未登录调用,**分享落地页 (客人从分享链接打开小程序首页) 可以在未登录态调一次** `/mp/customizer/me`,根据返回的 `isCustomizer: false` 跳过分享按钮渲染。这是设计原意。 + +### 3. sharerOpenid 字段值标准化(建议) + +前端尽量保证 `sharerOpenid` 字段为 `string | null` 而不是空串。空串虽然现在不再卡 400,但语义不规范。 + +### 4. 自查 + +```bash +grep -rE "isCustomizer|sharerOpenid|/mp/customizer/me" hl-ui/src mp-cli/src +``` + +--- + +## 二、测试服验证记录 + +部署 user + mp + gateway 三服务到测试服 (2026-05-22 22:45) 后真测: + +| # | 场景 | 实测 | +|---|------|------| +| T1 | CUSTOMIZER 角色 admin SMS 登录 → /mp/customizer/me | ✅ `isCustomizer: true, adminId, customizerName` | +| T2 | 非 CUSTOMIZER admin (运营/客服) SMS 登录 → /mp/customizer/me | ✅ `isCustomizer: false` (P0-1 修复后正确拦截) | +| T3 | 未登录直接调 /mp/customizer/me | ✅ 200 + `isCustomizer: false` (P1-2 网关 OPTIONAL 加白生效) | + +--- + +## 三、不在本期范围 (留尾巴另起工单) + +- P0-2 `AdminUserService` 注入 `WechatUserMapper`(类头部已备案,历史包袱) +- P1-3 `selectAnyByPhone` `LIMIT 1` 无 ORDER BY(业务唯一性约束,概率极低) +- P1-5 反查 Feign 重复调用合并优化(P99 未观察) + +--- + +## 四、联系人 + +后端: wx(呼籁旅行) +前端: mmg + +如有疑问可在 [#2922](https://git.1814.love:8443/wx/HL/issues/2922) 评论区留言。