Files
xinlong-shop-taro/.workbuddy/memory/2026-07-14.md
赵忠林 f878ea146e feat(order): 在待发货订单列表增加关闭订单功能
- 在 OrderCard 组件中新增 onCloseOrder 可选回调属性
- 待发货且未取消的订单显示“关闭订单”按钮
- 点击按钮阻止事件冒泡,避免触发卡片跳转
- 列表页实现 handleCloseOrder,弹窗确认后调用 updateShopOrder
- 关闭订单后显示成功提示并刷新当前列表数据
- 复用订单详情页取消订单的状态更新逻辑,保持一致性
2026-07-14 22:25:33 +08:00

324 lines
22 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`**
1.`useUser()` 获取 `isLoggedIn`
2. `useEffect` 中未登录时调用 `requireLogin({ action: 'viewOrder', redirect: '/pages/order/list', content: '登录后才能查看订单,是否前往登录?' })` 弹窗引导,而不是直接跳转
3. render 中 `if (!isLoggedIn) return null` 兜底,避免未登录时渲染订单内容
- **`src/passport/login.tsx`**:登录成功后的 `tabBarUrls` 白名单补全 `pages/order/list`,确保从订单入口登录后能 `switchTab` 回订单页
## 我的页面未登录可点击需登录功能 Bug 修复2026-07-14
### 问题
`pages/user/user` 未登录时,点击「我的订单」下的按钮(待付款/待发货/待收货/已完成、「全部订单」、以及菜单中的「升级VIP会员」「我的钱包」「收货地址」「我的收藏」都能直接跳转页面。
### 修改
- **`src/pages/user/user.tsx`**
1. 导入 `requireLogin` from `@/utils/login-guard`
2. 给需要登录的菜单项加 `requireAuth: true` 标记升级VIP会员/门店中心/我的钱包/收货地址/我的收藏)
3. 新增 `handleMenuClick(item)``requireAuth` 项调用 `requireLogin` 弹窗拦截,已登录才 `navigateTo`
4. 新增 `handleOrderTabClick(status)``handleViewAllOrders()`:订单入口 `requireLogin` 拦截,并加 `redirect: '/pages/order/list'` 让登录后回跳订单页
5. 未登录时需登录的菜单项和订单按钮加 `opacity-50` 视觉降级
6. 「帮助中心」「设置」不需要登录,保持原样
## 订单列表页登录后仍看到别人订单 Bug 修复2026-07-14
### 问题
`pages/order/list` 刚登录成功后仍能看到别人的订单,刷新重进后才正常。
### 根因
`loadOrders``useCallback` 依赖数组为 `[updateTabState]`,未包含 `user`,导致**闭包过期**——登录后 `isLoggedIn``true` 触发 effect 调用 `loadOrders`,但闭包中的 `user` 仍是初始渲染时的 `null``userId: user?.userId` 传了 `undefined`,后端未按用户过滤返回了全部订单。
### 修改
- **`src/pages/order/list.tsx`**
1. 新增 `userIdRef``useRef(user?.userId)`),每渲染同步 `userIdRef.current = user?.userId`,避免闭包过期
2. `loadOrders` 开头从 `userIdRef.current` 取 userId`if (!userId) return` 硬拦截——没有当前登录用户 userId 就禁止加载
3. `useEffect` 中增加 `if (!user?.userId) return` 判断,已登录但 userId 还没拿到时等待下次渲染
4. `useEffect` 依赖数组加 `user?.userId`userId 变化时重新触发加载
## 商城列表页浮动购物车按钮2026-07-14
### 需求
`pages/shop/index` 页面右下角添加浮动购物车按钮,显示购物车商品数量角标。
### 实现
- **`src/pages/shop/index.tsx`**
1.`useCartContext()` 额外解构 `totalCount`
2. 页面末尾添加 fixed 定位浮动按钮绿色圆形48px`bottom:80px right:16px`(避开 tabBar
3. `totalCount > 0` 时右上角显示红色角标,超过 99 显示 `99+`
4. 点击 `Taro.navigateTo` 跳转购物车页cart 非 tabBar 页)
5. 数量实时更新:`addItem` 内部调 `refresh()``totalCount` 派生值自动重渲染
## 购物车页面进入不刷新 Bug 修复2026-07-14
### 问题
从商品列表页/分类页加入购物车后,进入购物车页面,新加的商品不显示,只有之前已在购物车里的商品。
### 根因
1. **购物车页面缺少 `useDidShow`**`cart.tsx` 仅在 `useEffect([isLoggedIn])` 中调用 `refresh()`,登录状态不变时不会重新拉取数据。从其他页面返回购物车时,页面不刷新。
2. **商品列表页/分类页直接调 API 加购**`shop/index.tsx``shop/category.tsx` 直接调用 `addToCart` API未通过 `CartContext.addItem`,导致 CartContext 状态不同步(`addItem` 内部会调 `refresh()`)。
### 修改
1. **`src/pages/shop/cart.tsx`**:导入 `useDidShow`,添加 `useDidShow(() => { if (isLoggedIn) refresh() })`,页面每次显示时从服务端拉取最新购物车数据
2. **`src/pages/shop/index.tsx`**:导入 `useCartContext``handleAddToCart` 改用 `addItem(product, undefined, product.step || 1)` 代替直接调 `addToCart` API移除 `addToCart` 导入
3. **`src/pages/shop/category.tsx`**:同上,改用 `useCartContext``addItem`
### 需求
首页顶部搜索栏右侧铃铛图标,门店店员有新订单时能收到提醒。
### 改动
- **`src/pages/index/index.tsx`**
1. 导入 `useNewOrderDetector``getMyClerk``pageShopOrder``useDidShow``useCallback``useRef`
2. 登录后调 `getMyClerk()` 检测店员身份,存 `isClerk` state + `isClerkRef` refref 用于轮询回调中读取最新值,避免闭包过期)
3. `useDidShow` 时也刷新店员身份
4. 接入 `useNewOrderDetector`30秒轮询 `pageShopOrder({page:1,limit:5})``fetchLatestOrders` 内用 `isClerkRef.current` 网关——非店员直接返回空数组(不建 baseline无副作用
5. 新订单回调:`Taro.vibrateShort` 震动 + `Taro.showToast` 提示"您有 N 条新订单"
6. 铃铛角标从静态红点改为动态:`newOrderCount > 0` 显示数字角标(>99 显示 99+`=== 0` 时显示小圆点
7. 点击处理:店员 → `navigateTo` 门店订单页(有新订单时先 `clearUnread()`);普通用户 → 通知页
### 设计要点
- `isClerkRef` 解决 hooks 闭包过期问题——`fetchLatestOrders``useCallback` 依赖空数组,但通过 ref 读取最新店员状态
- 非店员时 `fetchLatestOrders` 返回 `[]`hook 内 `doCheck``list.length === 0` 时 return`knownOrderIdsRef` 保持 `null` 不建 baseline店员身份确认后首次真实请求才建 baseline不会误报
- `useNewOrderDetector` 内部已处理 `useDidShow`/`useDidHide` 生命周期tabBar 页切走自动停轮询
## 商品分类页浮动购物车图标优化2026-07-14
### 问题
商品分类页pages/shop/index右下角绿色圆形浮动购物车按钮使用 emoji `🛒` 作为图标,在绿色背景上对比度不足、线条不清晰。
### 修改
1. 新增白色线条购物车 SVG 图标:`src/assets/icons/cart.svg`
2. 导出 base64 数据 URI 常量:`src/assets/icons/index.ts``CART_ICON_WHITE`
3. `src/pages/shop/index.tsx` 浮动购物车按钮改用 `Image` 组件加载 `CART_ICON_WHITE`28×28px`mode='aspectFit'`),图标更清晰
## 商品详情页出现孤立 "0" 排查修复2026-07-14
### 问题
`pages/shop/product-detail` 价格区域下方出现一个不归属任何标签的孤立 `0`
### 根因
`src/pages/shop/product-detail.tsx` 中赚取积分行的条件渲染写成:
```tsx
{product.gainIntegral && Number(product.gainIntegral) > 0 && (...)}
```
当后端返回 `gainIntegral` 为数字 `0`JSX 短路与运算直接返回 `0`React 会把它渲染成一个纯文本节点。这就是页面上那个孤立的 `0`
### 修改
- **`src/pages/shop/product-detail.tsx`**
- 去掉条件里的 `product.gainIntegral &&`,改成 `{Number(product.gainIntegral) > 0 && (...)}`,避免 `0` 泄漏。
- 顺手把配送区域 `goodsWeight` 的同类写法也改成 `{Number(product.goodsWeight) > 0 && (...)}`,防止重量为 0 时同样泄漏。
- 另按用户要求「是 0 就不显示」,把销量行也改为 `{Number(product.sales) > 0 && (...)}`,销量为 0 时整条「销量: 0」不渲染。
## 订单列表页下单后不自动刷新修复2026-07-14
### 问题
`pages/order/list` 下单后从 checkout 页 `Taro.switchTab` 跳过来,订单列表不刷新,看不到新订单。
### 根因
订单列表页是 tabBar 页,`switchTab` 不会重新挂载组件。`useEffect` 依赖 `[tabIndex, isLoggedIn, user?.userId]`,这些值不变就不会重新触发;且 effect 内有 `if (!tabStates[tabIndex].initialized)` 守卫,页面已初始化过就直接跳过。
### 修改
- **`src/pages/order/list.tsx`**:新增 `Taro.useDidShow` 生命周期钩子
-`isFirstShow` ref 跳过首次显示(由 `useEffect` 处理初始加载)
- 后续每次显示时:标记所有 tab 为 `initialized: false`(切 tab 时会重新加载),并立即 `loadOrders(tabIndex, 1)` 刷新当前 tab
- 与之前购物车页 `useDidShow` 刷新是同一模式
## 商品详情页底部购物车角标2026-07-14
### 需求
`pages/shop/product-detail` 底部操作栏的购物车入口需要显示当前购物车商品数量角标。
### 修改
- **`src/pages/shop/product-detail.tsx`**
1.`useCartContext` 额外解构 `totalCount``refresh`
2. 引入 `useDidShow`,页面显示时(已登录)调 `refresh()` 拉取最新购物车,保证角标准确
3. 购物车图标外包一层 `relative` 容器,`totalCount > 0` 时右上角显示红色圆角角标(>99 显示 `99+`),样式与商城列表页浮动购物车角标一致
## 在线客服功能修复2026-07-14
### 问题
`pages/user/customer-service/index` 在线客服功能使用不了,用户已在微信后台添加客服人员。
### 根因(多个问题叠加)
1. **`openType="contact"` 按钮缺少关键属性**:缺少 `sessionFrom`(会话来源标识)、`onContact`(客服回调)、`showMessageCard`/`sendMessageTitle`(客服消息卡片),且按钮被 Tailwind `border-0` 类可能干扰原生渲染
2. **开发者工具限制**`open-type="contact"` 在微信开发者工具中不生效,只能在真机上使用,页面缺少提示
3. **自定义聊天系统消息发送缺失 `conversationId`**`addShopChatMessage` 调用未传 `conversationId`,消息无法关联到会话;`ShopChatMessage` 模型本身也缺少该字段
4. **消息发送缺失 `formUserId`**:发送人 ID 未设置
5. **`conv.lastMessage` 字段不存在**`ShopChatConversation` 模型只有 `content` 字段,代码引用了不存在的 `lastMessage`
6. **`useReachBottom` 用错场景**:页面使用 `ScrollView` 组件,`useReachBottom` 是页面级滚动钩子,对 ScrollView 无效,应改用 `onScrollToLower`
7. **`scrollToBottom` ref 设了但从未使用**:死代码
### 修改
1. **`src/api/shop/shopChatMessage/model/index.ts`**
- `ShopChatMessage` 接口新增 `conversationId?: number`
- `ShopChatMessageParam` 接口新增 `conversationId?: number`
2. **`src/pages/user/customer-service/index.tsx`**(全面修复):
- 微信客服按钮补全 `sessionFrom="customer_service"``onContact``showMessageCard``sendMessageTitle`
- 按钮样式从 Tailwind 类改为 inline style避免 `border-0` 干扰原生按钮),显式设置 `border: 'none'`
- 添加"需真机预览测试"提示文字
- `addShopChatMessage` 调用补全 `conversationId``formUserId`(从 `Taro.getStorageSync('UserId')` 获取)
- `conv.lastMessage` 全部改为 `conv.content`
- 会话列表更新 `lastMessage: text` 改为 `content: text`
- 移除 `useReachBottom`,改用 ScrollView `onScrollToLower` + `lowerThreshold={50}`
- 移除未使用的 `scrollToBottom` ref
- `pageShopChatMessage` 参数去掉 `as any` 断言(模型已支持 `conversationId`
- 新增 `getCurrentUserId()` 辅助函数
- `handleScrollToLower` 增加 `showHistory` 条件守卫(仅展开历史时才加载更多)
3. **`src/components/NavBar/index.tsx`**(关键修复,导致白屏):
- Taro 4.1.11 没有 `useNavigate` hook原代码 `import { useNavigate } from '@tarojs/taro'` 运行时为 `undefined`
- 改为 `import Taro from '@tarojs/taro'`,回退逻辑用 `Taro.navigateBack({ delta: 1 })`
4. **删除未注册的死代码**
- `src/pages/customer-service.tsx`(重复且仍引用 `useReachBottom`,干扰编译/热更新)
- `src/pages/customer-service.config.ts`
### 验证
- 全局搜索确认无其他 `useNavigate``useReachBottom` 引用
- TypeScript 检查修改文件无错误
### 客服功能简化21:00
- 用户反馈客服功能太复杂用不了,改为直接用微信原生 `open-type="contact"` 按钮
- `src/pages/shop/product-detail.tsx`:客服图标从 `View + onClick navigateTo` 改为 `Button openType="contact" sessionFrom="product_detail"`
- 删除了 `handleContactService` 函数和跳转到 `/pages/user/customer-service/index` 的逻辑
- **注意:`open-type="contact"` 必须真机预览测试,开发者工具中点击无反应**
- `pages/user/customer-service/index` 页面保留但不再从商品详情页跳转
## 地址编辑页识别按钮点不中修复2026-07-14
### 问题
`pages/user/address-edit` 智能识别区的「识别」按钮点击无反应。
### 根因
按钮使用 `absolute right-2 bottom-2` 定位叠在 `Textarea` 上方。微信小程序中 `Textarea` 是原生组件,层级高于普通 `View`,会遮挡 `absolute` 叠加的按钮,`z-index` 也无效,导致按钮点击事件被 Textarea 拦截。
### 修改
- **`src/pages/user/address-edit.tsx`**:识别区布局从 `relative` + `absolute` 叠加改为 flex 纵向布局——Textarea 在上,识别按钮 `flex justify-end mt-2` 在下方右对齐。去掉 `relative` class按钮不再叠加在 Textarea 上。
## 订单列表页待发货增加关闭订单功能2026-07-14
### 需求
`pages/order/list` 待发货状态的订单卡片需要支持客户关闭订单。
### 实现
1. **`src/components/common/OrderCard/index.tsx`**
- 新增可选 prop `onCloseOrder?: (order: ShopOrder) => void`
-`deliveryStatus === 10`(未发货)且订单未取消/未取消中时,在卡片底部显示「关闭订单」按钮
- 点击按钮阻止事件冒泡,避免触发卡片跳转详情
2. **`src/pages/order/list.tsx`**
- 导入 `updateShopOrder``OrderStatus`
- 实现 `handleCloseOrder`:弹窗确认后调用 `updateShopOrder({ ...order, orderStatus: OrderStatus.Cancelled })`,成功后 toast 并刷新当前 tab
-`OrderCard` 传入 `onCloseOrder` 回调
### 说明
复用订单详情页已有的取消订单逻辑(通过 `updateShopOrder``orderStatus` 改为 2