# 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) 评论区留言。