Files
xinlong-shop-taro/.workbuddy/memory/2026-07-14.md
赵忠林 93a46bdae7 fix(shop-cart): 修复购物车后端查询及前后端字段名对齐问题
- 修复后端ShopCartMapper SQL,关联查询商品和SKU信息,返回完整商品详情字段
- 新增ShopCart实体非持久化字段,映射商品名称、图片、价格、库存等
- 调整后端Controller列表方法,自动过滤当前登录用户购物车数据
- 前端ShopCart接口新增salePrice、dealerPrice字段,CartContext映射新增字段
- 修正购物车数量和选中状态字段名,前端与后端统一使用cartNum和selected
- 统一更新购物车数量、选中状态的接口调用参数,避免因字段不匹配导致更新失败
- 购物车及结算页价格显示逻辑优先使用后端扁平dealerPrice字段,兼容VIP价格显示
- 各购物车相关页面调整添加购物车参数,确保字段名一致和正确传递
2026-07-14 01:14:15 +08:00

6.9 KiB
Raw Blame History

购物车功能修复2026-07-14

问题

购物车页面pages/shop/cart商品显示异常

  • 商品名称/图片/价格信息缺失
  • 加入购物车后无法正确显示

根因

CartContext.refresh() 方法在将后端 API 返回的购物车项映射为前端 CartItem 时,遗漏了 product(商品详情)和 skuSKU 详情)嵌套对象的映射。导致页面中 item.product?.name/image/priceitem.sku?.price/image 均为 undefinedUI 只能显示硬编码的默认值。

修改

  1. src/contexts/CartContext.tsx(核心修复)

    • refresh()mappedItems 映射中补充 productsku 字段
    • 使用 (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.listRelselectListRelSQL 只 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.xmlselectSqlSELECT a.*, g.name AS goods_name, g.image AS goods_image, g.price AS price, g.sale_price AS sale_priceLEFT 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.tsfavoriteId 改为 id(后端实际返回 id);新增 price?: string|numbersalePrice 改为 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. updateCartNumPUT /shop/shop-cart/{id} + {quantity}PUT /shop/shop-cart + {id, num}
  2. updateCartCheckedPUT /shop/shop-cart/{id} + {selected}PUT /shop/shop-cart + {id, checked}(同时修正字段名 selectedchecked 与 model 一致)
  3. updateCartAllCheckedPUT /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) 非持久化字段:goodsNamegoodsImageskuPriceskuSpecstocksalePricedealerPrice;补充 TableField import
  2. ShopCartMapper.xmlSQL 改为 LEFT JOIN shop_goods g ON a.goods_id = g.goods_id + LEFT JOIN shop_goods_sku s ON a.sku_id = s.idSELECT 别名映射到新字段(COALESCE(s.price, g.price) AS sku_priceCOALESCE(s.stock, g.stock) AS stock);同时修复 userId/goodsId/merchantIdLIKE 改为 =(原 LIKE 会导致 userId=1 匹配到 10/11/21 等)
  3. ShopCartController.javalist() 方法自动按当前登录用户过滤(param.setUserId(loginUser.getUserId().longValue())

前端修改

  1. src/api/shop/shopCart/model/index.tsShopCart 接口新增 salePricedealerPrice 字段
  2. src/contexts/CartContext.tsxCartItem 新增 salePricedealerPricerefresh() 映射这两个字段;calcPrice() VIP 优先用扁平 i.dealerPrice(之前只看 i.product?.dealerPrice
  3. 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.tsShopCart.numcartNum;新增 selected 字段;AddToCartParam.numcartNumUpdateCartNumParam.numcartNum
  2. src/api/shop/shopCart/index.tsupdateCartNum{id, cartNum}updateCartChecked{id, selected}
  3. src/contexts/CartContext.tsxrefresh()item.cartNumitem.selectedaddItem()cartNumupdateQuantity 调用 {id, cartNum}
  4. src/pages/shop/index.tsx + src/pages/shop/category.tsxaddToCart 参数 numcartNum