Files
xinlong-shop-taro/.workbuddy/memory/2026-07-14.md
赵忠林 fd03ed80fd refactor(user): 禁用 loginByOpenId 静默登录并优化登录状态控制
- 移除 UserContext 和 useUser 中的 loginByOpenId 调用及相关降级逻辑
- 无本地 token 时保持未登录状态,不再自动触发静默登录
- 清理无用导入 TenantId 和 loginByOpenId
- 订单列表页增加登录校验,未登录用户跳转登录页并阻止渲染订单
- 商城首页价格改为 Price 组件,未登录游客显示登录遮罩,单位仅登录后可见
2026-07-14 01:36:58 +08:00

119 lines
8.3 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-07-14
### 问题
购物车页面pages/shop/cart商品显示异常
- 商品名称/图片/价格信息缺失
- 加入购物车后无法正确显示
### 根因
`CartContext.refresh()` 方法在将后端 API 返回的购物车项映射为前端 `CartItem` 时,**遗漏了 `product`(商品详情)和 `sku`SKU 详情)嵌套对象的映射**。导致页面中 `item.product?.name/image/price``item.sku?.price/image` 均为 `undefined`UI 只能显示硬编码的默认值。
### 修改
1. **`src/contexts/CartContext.tsx`**(核心修复)
- `refresh()``mappedItems` 映射中补充 `product``sku` 字段
- 使用 `(item as any).product` / `(item as any).sku` 获取后端返回的嵌套对象
2. **`src/utils/image.ts`**(增强健壮性)
- 新增 `ensureFullUrl()` 辅助函数:相对路径自动补全 OSS 域名 `https://oss.wsdns.cn`
- `getCompressedImageUrl()` 内部调用 `ensureFullUrl` 确保 URL 完整性
3. **`src/pages/shop/cart.tsx`**(补充图片回退源)
- 图片 `src` 回退链增加 `(item.sku as any)?.image`
- 完整回退链:`goodsImage -> product.image -> sku.image -> ''`
## 收藏列表图片/价格不显示修复2026-07-14
### 问题
`pages/user/favorite-list/index` 收藏列表:商品图片、价格、名称均空白。
### 根因
后端 `/api/shop/goods/favorite/list`(前端 `/shop/goods/favorite/list`)走 `ShopGoodsFavoriteServiceImpl.listRel``selectListRel`SQL 只 `SELECT a.*` 未关联商品表,返回字段仅 `id/userId/goodsId/merchantId/tenantId/createTime`,不含商品信息。前端依赖 `goodsImage/goodsName/price/salePrice` 均为 undefined。
### 修改方案1后端返回商品信息
1. **后端** `guilixu-java`
- `ShopGoodsFavorite.java`:新增 4 个 `@TableField(exist=false)` 非持久化字段 `goodsName(String)``goodsImage(String)``price(BigDecimal)``salePrice(BigDecimal)`,并补 `BigDecimal`/`TableField` import。
- `ShopGoodsFavoriteMapper.xml``selectSql``SELECT a.*, g.name AS goods_name, g.image AS goods_image, g.price AS price, g.sale_price AS sale_price``LEFT JOIN shop_goods g ON a.goods_id = g.goods_id`(已确认 `map-underscore-to-camel-case: true`,别名可映射)。
- 注意:本机无 maven 无法编译,改动为常规 MyBatis/MP 写法,需用户自行编译部署。
2. **前端**
- `src/api/shop/shopGoodsFavorite/model.ts``favoriteId` 改为 `id`(后端实际返回 `id`);新增 `price?: string|number``salePrice` 改为 `string|number`
- `pages/user/favorite-list/index.tsx`:图片用 `item.goodsImage`;价格改为优先 `item.price`(到手价),`salePrice` 作为划线价(`salePrice > price` 时显示);`key` 改用 `item.id ?? item.goodsId`(原 `favoriteId` 始终 undefined 会导致 key 重复)。
- 注:`src/pages/favorite-list.tsx` 为未注册路由的重复文件,未改动。
### 遗留(非本次范围,供参考)
adapter `/list` 接口忽略分页,一次返回全部收藏;前端 `listShopGoodsFavorite({page,limit:20})` 的无限滚动在收藏>20条时会重复追加。如需彻底解决建议改前端走 `/page` 接口或后端 `/list` 支持分页。
## 购物车更新 API 请求方式修复2026-07-14
### 问题
`PUT /api/shop/shop-cart/{id}` 返回 `HttpRequestMethodNotSupportedException: Request method 'PUT' not supported`
### 根因
`src/api/shop/shopCart/index.ts` 中 3 个函数用了非标准 URL 模式 `PUT /shop/shop-cart/{id}`,而项目所有其他 APIshopOrder、shopArticle 等)的更新操作统一走 `PUT /shop/shop-cart`(基础 URLid 放 body
### 修改
1. `updateCartNum``PUT /shop/shop-cart/{id}` + `{quantity}``PUT /shop/shop-cart` + `{id, num}`
2. `updateCartChecked``PUT /shop/shop-cart/{id}` + `{selected}``PUT /shop/shop-cart` + `{id, checked}`(同时修正字段名 `selected``checked` 与 model 一致)
3. `updateCartAllChecked``PUT /shop/shop-cart/selected` + `{selected}``POST /shop/shop-cart/selected` + `{checked}`(改用 POST自定义批量操作更可能支持 POSTCartContext 已有静默 catch 兜底)
## 购物车后端 SQL 关联查询修复2026-07-14
### 问题
`GET /api/shop/shop-cart` 返回的数据没有商品图片、价格等信息。前端 `CartContext.refresh()` 已映射 `goodsName/goodsImage/skuPrice/skuSpec/stock` 等字段,但后端根本没返回这些字段。
### 根因
后端 `ShopCartMapper.xml` 的 SQL 只做 `SELECT a.* FROM shop_cart a`,没有 JOIN 商品表和 SKU 表。
### 后端修改(`guilixu-java` 项目)
1. **`ShopCart.java`**:新增 7 个 `@TableField(exist = false)` 非持久化字段:`goodsName``goodsImage``skuPrice``skuSpec``stock``salePrice``dealerPrice`;补充 `TableField` import
2. **`ShopCartMapper.xml`**SQL 改为 `LEFT JOIN shop_goods g ON a.goods_id = g.goods_id` + `LEFT JOIN shop_goods_sku s ON a.sku_id = s.id`SELECT 别名映射到新字段(`COALESCE(s.price, g.price) AS sku_price``COALESCE(s.stock, g.stock) AS stock`);同时修复 `userId/goodsId/merchantId``LIKE` 改为 `=`(原 LIKE 会导致 userId=1 匹配到 10/11/21 等)
3. **`ShopCartController.java`**`list()` 方法自动按当前登录用户过滤(`param.setUserId(loginUser.getUserId().longValue())`
### 前端修改
4. **`src/api/shop/shopCart/model/index.ts`**`ShopCart` 接口新增 `salePrice``dealerPrice` 字段
5. **`src/contexts/CartContext.tsx`**`CartItem` 新增 `salePrice``dealerPrice``refresh()` 映射这两个字段;`calcPrice()` VIP 优先用扁平 `i.dealerPrice`(之前只看 `i.product?.dealerPrice`
6. **`src/pages/shop/cart.tsx`** + **`src/pages/shop/checkout.tsx`**:价格显示逻辑同步更新,优先使用扁平 `item.dealerPrice` / `item.salePrice`
## 购物车前后端字段名对齐修复2026-07-14
### 问题
修改购物车数量时后端报 `UPDATE shop_cart WHERE id=?`SET 子句为空MyBatis-Plus 找不到要更新的字段。
### 根因
前后端字段名不匹配:
- 前端发送 `num`,后端实体字段是 `cartNum` → Jackson 反序列化时 `cartNum` 为 null → 空 UPDATE
- 前端发送 `checked`,后端实体字段是 `selected` → 同样不匹配
- 列表返回 `cartNum`,前端读 `item.num` → 数量永远为默认值 1
### 修改文件
1. **`src/api/shop/shopCart/model/index.ts`**`ShopCart.num``cartNum`;新增 `selected` 字段;`AddToCartParam.num``cartNum``UpdateCartNumParam.num``cartNum`
2. **`src/api/shop/shopCart/index.ts`**`updateCartNum``{id, cartNum}``updateCartChecked``{id, selected}`
3. **`src/contexts/CartContext.tsx`**`refresh()``item.cartNum``item.selected``addItem()``cartNum``updateQuantity` 调用 `{id, cartNum}`
4. **`src/pages/shop/index.tsx`** + **`src/pages/shop/category.tsx`**`addToCart` 参数 `num``cartNum`
## 禁用 loginByOpenId 静默登录2026-07-14
### 改动
- **`src/contexts/UserContext.tsx`**:移除"情况3"静默登录块(`Taro.login` + `loginByOpenId`),无 token 时直接保持未登录状态;清理 `loginByOpenId``TenantId` 无用导入
- **`src/hooks/useUser.ts`**:移除降级方案中的 `loginByOpenId` 调用,仅从 storage 读取;清理 `loginByOpenId``TenantId` 无用导入
- `src/api/layout/index.ts``loginByOpenId` 函数定义保留,仅不再被调用
## 商城分类页价格登录可见2026-07-14
### 改动
- **`src/pages/shop/index.tsx`**:价格显示从手写 `Text` 改为 `Price` 组件 + `loginMask` 属性(与首页一致),游客看到"登录后查看价格"VIP 划线价逻辑保留在 `original` prop 中;单位 `unitName` 仅登录后显示
## 订单列表页未登录可查看订单 Bug 修复2026-07-14
### 问题
`pages/order/list` 未登录用户也能看到订单数据。
### 根因
页面缺少登录校验——`useEffect` 直接调用 `loadOrders`,未登录时 `user?.userId``undefined`,后端未按用户过滤直接返回了订单。
### 修改
- **`src/pages/order/list.tsx`**:采用项目标准模式 A与 commission.tsx 等页面一致):
1.`useUser()` 获取 `isLoggedIn`
2. `useEffect` 中加 `if (!isLoggedIn)` 守卫 → `Taro.navigateTo('/passport/login')` + return
3. render 中 `if (!isLoggedIn) return null`