diff --git a/src/api/shop/shopOrder/model/index.ts b/src/api/shop/shopOrder/model/index.ts index 557f33e..b8afaa1 100644 --- a/src/api/shop/shopOrder/model/index.ts +++ b/src/api/shop/shopOrder/model/index.ts @@ -1,5 +1,5 @@ import type { PageParam } from '@/api/index'; -import {OrderGoods} from "@/api/system/orderGoods/model"; +import type { ShopOrderGoods } from '@/api/shop/shopOrderGoods/model'; /** * 订单 @@ -156,7 +156,7 @@ export interface ShopOrder { // 是否已收到赠品 hasTakeGift?: string; // 订单商品项 - orderGoods?: OrderGoods[]; + orderGoods?: ShopOrderGoods[]; } /** diff --git a/src/rider/orders/index.tsx b/src/rider/orders/index.tsx index e228e13..80b53a5 100644 --- a/src/rider/orders/index.tsx +++ b/src/rider/orders/index.tsx @@ -241,6 +241,14 @@ export default function RiderOrders() { const flow2Done = o.deliveryStatus === 20 || o.deliveryStatus === 30 const flow3Done = !!o.sendEndTime const flow4Done = o.orderStatus === 1 + // 直接使用订单分页接口返回的 orderGoods + const goodsList = o.orderGoods || [] + const goodsNameList = goodsList + .map(g => g?.goodsName || (g as any)?.goodsTitle || (g as any)?.title || (g as any)?.name) + .filter(Boolean) as string[] + const goodsSummary = goodsNameList.length + ? `${goodsNameList.slice(0, 3).join('、')}${goodsList.length > 3 ? ` 等${goodsList.length}件` : ''}` + : (o.title || '-') const autoConfirmAt = o.sendEndTime ? dayjs(o.sendEndTime).add(AUTO_CONFIRM_RECEIVE_HOURS_FALLBACK, 'hour') @@ -278,6 +286,10 @@ export default function RiderOrders() { 数量: {o.totalNum ?? '-'} + + 商品: + {goodsSummary} + {o.sendEndTime && ( 送达时间: diff --git a/src/user/order/components/OrderList.tsx b/src/user/order/components/OrderList.tsx index 7aff881..cdb0985 100644 --- a/src/user/order/components/OrderList.tsx +++ b/src/user/order/components/OrderList.tsx @@ -7,7 +7,6 @@ import dayjs from "dayjs"; import {pageShopOrder, updateShopOrder, createOrder} from "@/api/shop/shopOrder"; import {ShopOrder, ShopOrderParam} from "@/api/shop/shopOrder/model"; import {listShopOrderGoods} from "@/api/shop/shopOrderGoods"; -import {ShopOrderGoods} from "@/api/shop/shopOrderGoods/model"; import {copyText} from "@/utils/common"; import PaymentCountdown from "@/components/PaymentCountdown"; import {PaymentType} from "@/utils/payment"; @@ -78,36 +77,6 @@ const tabs = [ } ] -// 扩展订单接口,包含商品信息 -interface OrderWithGoods extends ShopOrder { - // 避免与 ShopOrder.orderGoods (OrderGoods[]) 冲突:这里使用单独字段保存接口返回的商品明细 - orderGoodsList?: ShopOrderGoods[]; -} - -// 后端订单分页接口通常已返回 orderGoods(订单商品明细)。 -// 这里把各种可能的字段名做一次归一化,避免再为每个订单额外请求一次“订单商品”接口。 -const normalizeOrderGoodsList = (order: any): ShopOrderGoods[] => { - const raw = - order?.orderGoods || - order?.orderGoodsList || - order?.goodsList || - order?.goods || - []; - if (!Array.isArray(raw)) return []; - - return raw.map((g: any) => ({ - ...g, - goodsId: g?.goodsId ?? g?.itemId ?? g?.goods_id, - skuId: g?.skuId ?? g?.sku_id, - // 当接口只返回了最小字段时,用订单标题兜底,避免列表出现空白商品名 - goodsName: g?.goodsName ?? g?.goodsTitle ?? g?.title ?? g?.name ?? order?.title ?? '商品', - image: g?.image ?? g?.goodsImage ?? g?.cover ?? g?.pic, - spec: g?.spec ?? g?.specInfo ?? g?.spec_name, - totalNum: g?.totalNum ?? g?.quantity ?? g?.num ?? g?.count, - price: g?.price ?? g?.payPrice ?? g?.goodsPrice ?? g?.unitPrice - })); -}; - interface OrderListProps { onReload?: () => void; searchParams?: ShopOrderParam; @@ -122,7 +91,7 @@ interface OrderListProps { } function OrderList(props: OrderListProps) { - const [list, setList] = useState([]) + const [list, setList] = useState([]) const pageRef = useRef(1) const [hasMore, setHasMore] = useState(true) const [payingOrderId, setPayingOrderId] = useState(null) @@ -254,20 +223,17 @@ function OrderList(props: OrderListProps) { const res = await pageShopOrder(searchConditions); if (res?.list && res?.list.length > 0) { - // 订单分页接口已返回 orderGoods:直接读取并归一化,避免 N+1 请求导致列表加载慢 - const ordersWithGoods: OrderWithGoods[] = res.list.map((order: any) => ({ - ...order, - orderGoodsList: normalizeOrderGoodsList(order) - })); + // 订单分页接口已返回 orderGoods:列表直接使用该字段 + const incoming = res.list as ShopOrder[]; // 使用函数式更新避免依赖 list setList(prevList => { - const newList = resetPage ? ordersWithGoods : (prevList || []).concat(ordersWithGoods); + const newList = resetPage ? incoming : (prevList || []).concat(incoming); return newList; }); // 正确判断是否还有更多数据 - const hasMoreData = res.list.length >= 10; // 假设每页10条数据 + const hasMoreData = incoming.length >= 10; // 假设每页10条数据 setHasMore(hasMoreData); } else { setList(prevList => resetPage ? [] : prevList); @@ -377,9 +343,9 @@ function OrderList(props: OrderListProps) { }; // 再次购买 (已完成状态) - const buyAgain = (order: OrderWithGoods) => { + const buyAgain = (order: ShopOrder) => { console.log('再次购买:', order); - const goodsId = order.orderGoodsList?.[0]?.goodsId + const goodsId = order.orderGoods?.[0]?.goodsId if (!goodsId) { Taro.showToast({ title: '订单商品信息缺失', @@ -437,7 +403,7 @@ function OrderList(props: OrderListProps) { }; // 立即支付 - const payOrder = async (order: OrderWithGoods) => { + const payOrder = async (order: ShopOrder) => { try { if (!order.orderId || !order.orderNo) { Taro.showToast({ @@ -480,8 +446,8 @@ function OrderList(props: OrderListProps) { Taro.showLoading({title: '发起支付...'}); - // 构建商品数据:优先使用列表已加载的商品信息;缺失时再补拉一次,避免goodsItems为空导致后端拒绝/再次支付失败 - let orderGoods = order.orderGoodsList || []; + // 构建商品数据:优先使用订单分页接口返回的 orderGoods;缺失时再补拉一次,避免goodsItems为空导致后端拒绝/再次支付失败 + let orderGoods = order.orderGoods || []; if (!orderGoods.length) { try { orderGoods = (await listShopOrderGoods({orderId: order.orderId})) || []; @@ -492,13 +458,13 @@ function OrderList(props: OrderListProps) { } const goodsItems = orderGoods - .filter(g => !!g.goodsId) + .filter(g => !!(g as any).goodsId || !!(g as any).itemId) .map(goods => ({ - goodsId: goods.goodsId as number, - quantity: goods.totalNum || 1, + goodsId: (goods.goodsId ?? (goods as any).itemId) as number, + quantity: ((goods as any).quantity ?? goods.totalNum ?? 1) as number, // 若后端按SKU计算价格/库存,补齐SKU/规格信息更安全 - skuId: (goods as any).skuId, - specInfo: (goods as any).spec || (goods as any).specInfo + skuId: (goods as any).skuId ?? (goods as any).sku_id, + specInfo: (goods as any).specInfo ?? (goods as any).spec })); if (!goodsItems.length) { @@ -753,8 +719,8 @@ function OrderList(props: OrderListProps) { {/* 商品信息 */} - {item.orderGoodsList && item.orderGoodsList.length > 0 ? ( - item.orderGoodsList.map((goods, goodsIndex) => ( + {item.orderGoods && item.orderGoods.length > 0 ? ( + item.orderGoods.map((goods, goodsIndex) => ( - {goods.goodsName} - {goods.spec && 规格:{goods.spec}} - 数量:{goods.totalNum} + + {goods.goodsName || (goods as any).goodsTitle || (goods as any).title || item.title || '订单商品'} + + {(goods.spec || (goods as any).specInfo) && ( + 规格:{goods.spec || (goods as any).specInfo} + )} + 数量:{(goods as any).quantity ?? goods.totalNum} - ¥{goods.price} + ¥{goods.price || (goods as any).payPrice} )) ) : ( diff --git a/src/utils/orderGoods.ts b/src/utils/orderGoods.ts new file mode 100644 index 0000000..ad12e37 --- /dev/null +++ b/src/utils/orderGoods.ts @@ -0,0 +1,32 @@ +import type { ShopOrderGoods } from '@/api/shop/shopOrderGoods/model'; + +/** + * Normalize order goods data returned by the order/page API. + * + * In practice different backends may return different field names (orderGoods/orderGoodsList/goodsList...), + * and the item fields can also differ (goodsName/title/name, totalNum/quantity, etc.). + * + * We normalize them to ShopOrderGoods so list pages can render without doing N+1 requests per order. + */ +export const normalizeOrderGoodsList = (order: any): ShopOrderGoods[] => { + const raw = + order?.orderGoods || + order?.orderGoodsList || + order?.goodsList || + order?.goods || + []; + if (!Array.isArray(raw)) return []; + + return raw.map((g: any) => ({ + ...g, + goodsId: g?.goodsId ?? g?.itemId ?? g?.goods_id, + skuId: g?.skuId ?? g?.sku_id, + // When the API returns minimal fields, fall back to order title to avoid blank names. + goodsName: g?.goodsName ?? g?.goodsTitle ?? g?.title ?? g?.name ?? order?.title ?? '商品', + image: g?.image ?? g?.goodsImage ?? g?.cover ?? g?.pic, + spec: g?.spec ?? g?.specInfo ?? g?.spec_name, + totalNum: g?.totalNum ?? g?.quantity ?? g?.num ?? g?.count, + price: g?.price ?? g?.payPrice ?? g?.goodsPrice ?? g?.unitPrice + })); +}; +