Files
xinlong-shop-taro/.workbuddy/memory/2026-07-15.md
赵忠林 3f1931e420 feat(address): 修复默认地址唯一性并新增用户浏览记录功能
- 后端新增 clearDefault 方法,保存默认地址前清除其他默认状态,避免多默认地址
- 前端地址编辑页保存成功后若为默认,调用 setDefaultAddress 触发后端清理逻辑
- useAddress hook 加入 ensureSingleDefault,前端保证地址数据中只有一个默认地址
- 新增 shop_goods_browse 表及相关实体、Mapper、服务和控制器,实现用户商品浏览记录功能
- 商品详情页接入浏览记录上报,支持登录用户浏览记录服务端同步
- 浏览历史页支持登录用户服务端分页查询,未登录用户使用本地存储兜底
- 浏览历史页支持浏览记录单条删除、清空、上拉加载和下拉刷新功能
- 调整用户中心入口,恢复浏览历史菜单项显示
- 文档和内存文件更新,包括数据库建表 SQL、接口定义和项目编译说明
2026-07-15 12:52:25 +08:00

119 lines
10 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.

## 线下付款下单失败排查
- 文件:`src/pages/shop/checkout.tsx``src/api/shop/shopOrder/index.ts`
- 现象结算页选择线下付款payType=9下单时报错`创建支付订单失败创建微信支付订单失败支付配置中应用ID为null或空`
- 原因:前端传参正确,但后端 `POST /shop/shop-order` 在 payType=9 时仍尝试创建微信支付订单,因未配置 appId 失败
- 前端处理:
- `checkout.tsx` 增加线下付款支付配置类错误的友好提示
- `createOrder` 返回类型放宽为 `WxPayResult | null`,兼容非微信支付场景
- 后端修复(`/Users/gxwebsoft/JAVA/guilixu-java`3 个文件):
1. `OrderBusinessService.java``createOrder()` 中 Integer 比较从 `==` 改为 `.equals()`,避免装箱陷阱导致 payType=8/9 拦截失效;微信支付分支前加日志
2. `ShopOrderServiceImpl.java``createWxOrder()` 方法开头增加 payType 守卫,非微信支付(1/102)直接抛异常,不走 JSAPI 分支
3. `ShopOrderController.java``saveLegacy()` 方法增加 payType 检查,货到付款/线下付款/余额支付跳过 createWxOrder
- 验证Maven compile 成功,无编译错误
- 注意:后端服务需重启才能生效
## 结算页支付方式调整
- 文件:`src/pages/shop/checkout.tsx`
- 注释掉货到付款(id=8)选项,只保留线下付款(id=9)
- 默认支付方式从 8(货到付款) 改为 9(线下付款)
## 门店订单修改金额功能
- 文件:`src/pages/store/orders/index.tsx`
- 新增 OpType `'editPrice'`,在订单卡片操作区增加橙色「修改金额」按钮
- 仅对可操作订单(非已完成/非已关闭)显示
- 弹窗包含当前实付展示、新金额输入digit、修改原因必填 textarea
- 提交调用 `updateShopOrder({ orderId, payPrice, comments })`,金额变更记录追加到 comments
- 复用现有 `updateShopOrder` APIPUT `/shop/shop-order`),无需新增接口
## 修复 VIP 会员价格显示和下单问题
- **根因**`useVipStatus` hook 已定义但从未被任何页面使用,所有页面直接调用 `isVipMember()` 读取同步缓存。该缓存仅在「个人中心」页刷新,导致 VIP 会员访问商品详情/购物车/结算页时缓存为 stale false不显示 dealerPrice
- **修复文件**(共 9 个):
1. `src/api/shop/shopOrder/model/index.ts``OrderGoodsItem` 新增 `price?: string` 字段,下单时传 VIP 单价
2. `src/pages/shop/product-detail.tsx` — 引入 `useVipStatus`,用响应式 `isVip` 替换 `isVipMember()`
3. `src/pages/shop/checkout.tsx` — 引入 `useVipStatus``goodsPrice` useMemo 依赖加 `isVip`;下单时 `OrderGoodsItem``price` 字段
4. `src/pages/shop/index.tsx` — 引入 `useVipStatus`,替换 `isVipMember()`
5. `src/pages/shop/category.tsx` — 引入 `useVipStatus`,替换 `isVipMember()`
6. `src/pages/shop/cart.tsx` — 引入 `useVipStatus`,替换 `isVipMember()`
7. `src/contexts/CartContext.tsx` — CartProvider 引入 `useVipStatus``calcPrice` 用响应式 `isVip`
8. `src/components/business/SkuSelector/index.tsx` — 引入 `useVipStatus`,替换 `isVipMember()`
9. `src/components/common/ProductCard/index.tsx` — 引入 `useVipStatus`,替换 `isVipMember()`
- **原理**`useVipStatus` 在组件挂载时异步调用 `checkAndCacheVipStatus` 查询后端并更新缓存+React statestate 变化触发重渲染,使所有价格显示/计算自动更新为 dealerPrice
- 验证:`npx taro build --type weapp` 构建成功
## 门店订单修改金额 — 修改原因保存字段变更
- 文件:`src/pages/store/orders/index.tsx``src/api/shop/shopOrder/model/index.ts`
- 变更:修改金额时的"修改原因"从追加到 `comments` 字段改为保存到 `merchantRemarks`(商户备注)字段
- `ShopOrder` 接口新增 `merchantRemarks?: string` 字段
- `submitEditPrice``updateShopOrder` 传参从 `comments` 改为 `merchantRemarks`
## 订单备注字段分离buyerRemarks / merchantRemarks / comments
- 文件:`src/api/shop/shopOrder/model/index.ts``src/pages/shop/checkout.tsx``src/pages/store/orders/index.tsx`
- `ShopOrder``OrderCreateRequest` 接口均新增 `buyerRemarks?: string`(买家备注)
- 结算页 `checkout.tsx`:订单备注从 `comments: remarks` 改为 `buyerRemarks: remarks`
- 门店订单列表 `store/orders/index.tsx`:订单卡片新增买家备注展示块(橙色背景,收货信息下方)
- 字段约定:`buyerRemarks`=买家下单备注,`merchantRemarks`=商户修改金额原因,`comments`=系统/其他备注
## 修复线下付款订单状态显示
- 文件:`src/components/common/OrderCard/index.tsx``src/pages/order/list.tsx``src/pages/order/detail.tsx`
- 问题:线下付款(payType=9)下单成功后,订单列表和详情页显示"线下付款·待确认",用户认为状态不对
- 修复内容:
1. OrderCard `getCardStatus`:将线下付款(payType=9)与货到付款(payType=8)统一处理,`!payStatus && !isCod && !isOffline` 才显示"待付款",否则直接按 deliveryStatus 判断,线下付款订单显示"待发货"
2. OrderCard `showCloseButton`:增加 `!order.payStatus` 条件,已付款订单不再显示取消按钮(需到详情页退款)
3. OrderCard 按钮文案:从"关闭订单"改为"取消订单",与详情页一致
4. list.tsx `handleCloseOrder`:弹窗标题改为"确认取消订单"toast 改为"订单已取消"
5. detail.tsx `getOrderDisplayStatus`:线下付款未确认时显示"待发货"蓝色subtitle 保留付款引导文案
6. detail.tsx `getOrderPhase`:保留 `offline_pending` 阶段,底部按钮仍为"取消订单+联系客服"(未确认收款可取消,非退款)
## 修复地址编辑页智能识别 bug
- 文件:`src/pages/user/address-edit.tsx`
- 问题:粘贴带标签的地址文本(如「收件人: 赵忠林 / 手机号码: 137... / 所在地区: 广西... / 详细地址: 大学东路...」)识别后:
1. 姓名识别失败(之前只看文本开头的 2-4 个汉字,姓名不在开头)
2. 详细地址保留了「收件人」「手机号码」「所在地区」「详细地址」等标签文字
- 修复 `parseAddressText`
1. 姓名优先匹配 `(?:收件人|收货人|姓名|联系人)[:]\s*([\u4e00-\u9fa5]{2,4})`,找不到再回退到 `^[\u4e00-\u9fa5]{2,4}`
2. 详细地址提取前先 strip 标签文字(收件人/手机号/所在地区/详细地址 + 中英冒号),再 strip 省市区,最后 strip 零散标签
- 验证:用 Python 模拟Python 是用 JS 同款正则+RegionData解析截图中的输入
- name: 赵忠林 ✓
- phone: 13737128880 ✓
- province/city/region: 广西壮族自治区/南宁市/西乡塘区 ✓
- address: 西乡塘街道大学东路9号瀚林御景3栋1单元1101号房 ✓(街道+详细地址完整保留)
- 项目 type-check (`npx tsc --noEmit`) 无报错
## 修复默认地址唯一性 bug
- 问题:新增/编辑地址时勾选"设为默认"后,后端直接保存 `isDefault=true`,不清除其他地址的默认状态,导致出现多个默认地址
- 后端修复(`/Users/gxwebsoft/JAVA/guilixu-java`3 个文件):
1. `ShopUserAddressService.java` — 新增 `clearDefault(userId, excludeId)` 接口方法
2. `ShopUserAddressServiceImpl.java` — 实现 `clearDefault`:查询该用户所有 `isDefault=true` 的地址(可排除指定 id批量设为 false
3. `ShopUserAddressController.java``save()` 新增时若 `isDefault=true` 先调 `clearDefault(userId, null)``update()` 编辑时若 `isDefault=true` 先调 `clearDefault(userId, id)` 排除当前地址
- 前端修复(`src/pages/user/address-edit.tsx`
- 保存成功后若 `isDefault=true`,再调一次 `setDefaultAddress(savedId)` 触发后端清理逻辑(双重保险)
- 新增时从返回结果中提取 savedId
- 修复 `getShopUserAddress` 返回值类型断言(`as ShopUserAddress`
- 前端渲染兜底(`src/hooks/useAddress.ts`
- `loadAddresses` 中加 `ensureSingleDefault` 工具函数:若后端返回多个 `isDefault=true`,只保留 createTime 最早的为默认,其余置 false
- 后端 Maven 编译命令:`"/Applications/IntelliJ IDEA Ultimate.app/Contents/plugins/maven/lib/maven3/bin/mvn" compile`guilixu 的 mvnw 损坏,用 IntelliJ 自带 Maven
- 编译结果:成功无报错
- 注意:之前误改了 paopao-java 和 websopy-java 两个项目(已废弃),正确后端是 guilixu-java
## 用户商品浏览记录功能(全栈实现)
- 需求:后台记录用户浏览商品的痕迹
- 方案:去重累加模式(同一用户+商品只留一条visit_count 累加5分钟内去重防刷
- 后端(`/Users/gxwebsoft/JAVA/guilixu-java`7 个文件 + 1 SQL
1. `sql/shop_goods_browse.sql` — 建表 SQL含3个索引uk_user_goods 唯一 / idx_user_time / idx_goods_time
2. `ShopGoodsBrowse.java` — Entity参照 ShopGoodsFavorite 范式,含 visitCount/lastVisitTime/browseSource + 关联商品快照字段)
3. `ShopGoodsBrowseParam.java` — 查询参数merchantId 用 Long 与 BaseParam 一致,含 startTime/endTime 时间范围)
4. `ShopGoodsBrowseMapper.java` + XML — Mapper关联 shop_goods 表查询商品名称/图片/价格)
5. `ShopGoodsBrowseService.java` + Impl — Service核心 recordBrowse 去重累加逻辑查已有→5分钟内忽略/超过则累加→首次插入)
6. `ShopGoodsBrowseController.java` — ControllerPOST 上报 / GET page 我的足迹 / DELETE 删单条 / DELETE 清空 / GET admin/page 后台查询)
- 前端(`xinlong-shop-taro`4 个文件):
1. `src/api/shop/shopGoodsBrowse/model/index.ts` — ShopGoodsBrowse + ShopGoodsBrowseParam 类型
2. `src/api/shop/shopGoodsBrowse/index.ts` — reportBrowse(静默)/pageBrowseHistory/deleteBrowseRecord/clearBrowseHistory
3. `src/pages/shop/product-detail.tsx` — addToHistory() 已登录时异步调 reportBrowse 上报
4. `src/pages/user/history-list/index.tsx` — 改为服务端分页(登录)/ 本地兜底(未登录),支持删除单条、清空、上拉加载
5. `src/pages/user/user.tsx` — 恢复浏览历史入口(取消注释)
- 编译验证:后端 Maven compile 成功;前端 tsc --noEmit 无新增类型错误
- 编译踩坑BaseController.success() 有 success(IPage<T>) 重载,泛型方法返回类型用 ApiResult<?> 避免 fail() 分支类型不兼容
- 待执行:数据库需手动执行 `shop_goods_browse.sql` 建表
- 后续可选:后台管理页面(`/Users/gxwebsoft/VUE/guilixu-admin`Vue3+AntD Vue