Files
guilixu-admin/.workbuddy/memory/2026-08-17.md
T
gxwebsoft 6e57fba192 fix(special-zone): 修复白名单弹窗checkbox未显示问题并添加专区小程序码功能
- 修复 UserSelectModal 弹窗中复选框不显示的根因,正确传入 selection-type="checkbox"
- 新增后台接口获取专区小程序码图片流,支持正式/体验/开发版环境
- 管理后台专区列表新增二维码按钮,弹窗展示对应专区小程序码
- 小程序端支持扫码参数 scene 解析,实现扫码直接进入专区页面
- 优化二维码弹窗组件,支持切换小程序版本并动态加载二维码
- 重新构建前端及后端服务,确保新功能生效和兼容原有业务逻辑
2026-08-17 02:42:13 +08:00

65 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-08-17 工作日志
## 专区商品「移除」假成功 bug 修复
- 现象:guilixu.websoft.top/special/zone 移除专区商品提示成功,刷新(重查库)后商品仍在。
- 根因:`ShopHomeSectionController.removeGoods``listByIds` + `updateBatchById``shop_goods.section_ids`;单专区商品移除后 section_ids 变 null,但 `ShopGoods.sectionIds` 无更新策略注解,MP 全局默认 `NOT_NULL` 会忽略 null 值 → 不生成 `SET section_ids=NULL` → 库字段保持原值(假成功)。多专区商品(变非 null)正常,故仅单专区场景坏。
- 修复:`addGoods`/`removeGoods` 改用 `UpdateWrapper.set("section_ids", newVal).eq("goods_id", id)` 显式更新(newVal 可为 null),绕过字段策略。文件:guilixu-java `ShopHomeSectionController.java`
- 部署:需重新编译部署 guilixu-java(线上 shop-api)后端生效;前端无需改动。添加用同样模式统一修复。
- 验证:部署后用单专区商品移除测试,刷新不应再出现。
- 注:本机环境无 maven,未本地编译;改动为标准 MP 用法(IService.update(Wrapper) / UpdateWrapper.set 允许 null)。
## 专区白名单功能诊断(功能当前不可用)
- 设计意图:专区设为"受限专区"(restricted=1) 后,该专区商品仅白名单用户可用余额购买;小程序结算页 checkout.tsx 已调 `check-permission` 前端拦截。
- 致命错配:后台白名单弹窗 `UserSelectModal.vue``pageUsers`(@/api/system/user → sys_user 后台员工) 选用户;后端 `ShopHomeSectionController.checkPermission``getLoginUser().getUserId()`= shop_user 小程序买家 userId)。两套用户体系 id 不一致 → 白名单里加的任何人(后台员工)对真实买家都匹配不上 → 受限专区对买家永远拦截/强制余额,白名单形同虚设。
- 次要隐患:后端创建订单接口未做白名单强校验,仅前端拦截,可被绕过。
- 修复方向:① 白名单弹窗数据源从 `pageUsers`(sys_user) 改为 `pageShopUser`(@/api/shop/shopUser → shop_user 买家),使存的 user_id 与校验 userId 同体系;② 后端下单接口加白名单强校验防绕过。后台已有 pageShopUser 可用。
## 专区白名单:用户体系澄清 + 后端强校验(用户 2026-08-17 01:50 指令)
- 用户澄清:本项目的买家(小程序用户)就是 `sys_user` 体系,`pageShopUser` 实际不用/返回空。故白名单弹窗用 `pageUsers`(sys_user) 是**正确**的,之前"用户体系错配"判断为误判。
- 白名单弹窗 `UserSelectModal.vue` 现状(8-16 已改):`pageUsers({ keywords, ... })`**不传 isStaff**(搜索覆盖全部 sys_user)。源码无需再改。已 grep 确认 zone 目录下无残留 isStaff/pageShopUser。
- 后端补「受限专区白名单强校验」:`OrderBusinessService.java` 新增
- import`ShopHomeSectionService``ShopHomeSectionUserService``QueryWrapper``java.util.Set/LinkedHashSet`
- `@Resource` 注入 `homeSectionService``homeSectionUserService`
- `createOrder``validateDeliveryRegionIfNeeded` 之后调用 `validateSectionPermissionIfNeeded(request, shopOrder, loginUser)`
- 新方法逻辑:遍历 `request.goodsItems` → 取 `ShopGoods.sectionIds` → 找 restricted=1 的专区 → 校验 `loginUser.getUserId()` 是否在 `shop_home_section_user`count>0),否则抛 `BusinessException("该商品属于受限专区,仅限指定白名单用户购买")`
- 作用:前端 `check-permission` 的后端兜底,防止直接调 `/shop/shop-order` 下单绕过白名单。
- 部署:需重新编译部署 guilixu-javashop-api)。前端无需改动。
- 注:本机无 maven,未本地编译;改动为标准 MP 用法(IService.count(QueryWrapper) / getById)。
- 待确认:用户 "2.帮我补" 指令只写了前半句,已按上文补后端强校验;若其本意是"补菜单记录"(专区管理入口,动态路由待插入),需另出 INSERT SQL(菜单表结构待确认)。
## 专区白名单弹窗 checkbox 不显示(第三次修复,根因确认)
- 现象:白名单弹窗数据正常(12 条用户),但表格无 checkbox 勾选列,用户无法选择。
- 已尝试修复(前两次均未生效):
1. 8-16`reactive``computed` + `columnWidth: 48`(与 shopCoupon 对齐)
2. 同期:去掉 `isStaff: true`
- **真正根因**(读 `ele-pro-table` 源码 `node_modules/ele-admin-pro/es/ele-pro-table/index.js` 第 94-114 行确认):
- `ele-pro-table` 内部 `tableSelectionType` computed 有前置条件:必须传 `selection``current``selectionType="radio"` 三者之一,否则返回 `undefined`
- 返回 undefined → `tableRowSelection` 也返回 undefined → ant-design-vue Table 收到 `rowSelection=undefined`**不渲染 checkbox 列**
- 我们的弹窗三个条件都不满足(没传 :selection / :current / selectionType),所以不管 row-selection 配置多正确都不会出勾选框
- **最终修复**:模板 `<ele-pro-table>``selection-type="checkbox"`(第 18 行),使源码判断走通:`props2.selectionType !== "radio"` 为 true(是 "checkbox")→ 不走 early return → 返回 "checkbox" → checkbox 列正常渲染。
- 改动文件:`src/views/special/zone/components/UserSelectModal.vue`(仅模板加 1 个 prop
- 部署:重新构建前端即可(`npm run dev` 热更新或 `npm run build` 部署)。
## 专区小程序码(扫码直接进入专区)
- 需求:/special/zone 专区管理加「二维码」入口,生成该专区的小程序码,用户微信扫码直接进入小程序对应专区。
- 后端(guilixu-java `ShopHomeSectionController.java`):新增 `GET /api/shop/shop-home-section/{id}/qrcode`
- 调微信 `getwxacodeunlimit` 生成无限场景码;`scene=sectionId=xxx``page=pages/shop/section-detail`;按专区 `tenantId``WxMiniappAccessTokenService.getAccessToken(tenantId)` 取 tokenprod 用 `release` 否则 `trial`(与现有 getOrderQRCodeUnlimited 一致)。
- 复用 Hutool `HttpRequest` 调微信,返回 PNG 流;微信出错时返回 JSON 并识别 `application/json`
- 用户端小程序(guilixu-taro `pages/shop/section-detail.tsx`):解析 `useRouter().params.scene`(小程序码扫码透传的 `sectionId=xxx`),兼容原 `?sectionId=` 普通跳转。
- 管理后台(guilixu-admin `views/special/zone/index.vue` + `api/shop/shopZone`):列表操作列加「二维码」按钮 → 弹窗显示小程序码图片;新增 `getSectionQrcode(id)`responseType blob → objectURL,遇 JSON 错误解析 message 并 reject)。
- 部署:① 重新编译部署 guilixu-javashop-api)使新接口生效;② 重新构建前端 admin 与 taro 小程序(section-detail 需重新发布/体验版,因小程序码 page 指向已发布页面)。
- 注:本机无 maven,后端未本地编译;改动完全复用 WxLoginController 既有 getwxacodeunlimit 写法。
- 限制:getwxacodeunlimit 的 page 必须已存在于小程序(pages/shop/section-detail 已在 app.config 的 pages 列表);scene 仅限可见字符、≤32 位,`sectionId=xxx` 满足。
## 专区小程序码报 41030 invalid page 修复
- 现象:后台点「二维码」生成小程序码,微信返回 `{"errcode":41030,"errmsg":"invalid page"}`
- 根因:原代码按 profile 决定 env_version——active=dev 时走 `trial`(体验版)。微信 41030=所请求版本的小程序代码包里**没有该页面**。页面 `pages/shop/section-detail` 在源码 app.config 存在,但体验版小程序没上传含此页面的代码 → 失败。
- 修复:
- 后端(ShopHomeSectionController.getSectionQrcode):去掉按 profile 判断,改为 `envVersion` 请求参数,`@RequestParam(defaultValue="release")``env_version` 直接用该参数(release/trial/develop)。
- 前端(admin):`getSectionQrcode(id, envVersion='release')` 支持传参;弹窗加「正式版/体验版/开发版」RadioGroup(默认正式版),切换即重新生成。
- 关键前提(务必告诉用户):**生成成功 ≠ 扫码能进专区**。
1. 生成码所请求的版本(正式/体验)其代码包必须包含 `pages/shop/section-detail` 页面,否则仍 41030。
2. 扫码能正确进专区,还要求把「能解析 scene 的 section-detail.tsx」发布到**同一版本**:正式版需发版、体验版需上传体验版、开发版需开发者工具预览。
3. 若默认正式版仍 41030,说明线上版本也没有此页面 → 需先发布小程序(该页面虽在 app.config,但可能未上线)。
- 部署:需重新编译部署 guilixu-java + 重新构建发布 taro 小程序(到目标版本)。