|
|
@@ -36,8 +36,8 @@
|
|
|
<!-- 领取优惠券弹窗 -->
|
|
|
<CouponModal v-model:open="couponModalOpen" :coupon-list="couponList" @close="handleCouponClose" />
|
|
|
|
|
|
- <!-- 购物车弹窗:按接口格式展示 items(cuisineName/cuisineImage/quantity/unitPrice/subtotalAmount/remark) -->
|
|
|
- <CartModal v-model:open="cartModalOpen" :cart-list="displayCartList"
|
|
|
+ <!-- 购物车弹窗:按接口格式展示 items(含 tags 从 foodList 补全) -->
|
|
|
+ <CartModal v-model:open="cartModalOpen" :cart-list="displayCartListWithTags"
|
|
|
@increase="handleIncrease" @decrease="handleDecrease" @clear="handleCartClear"
|
|
|
@order-click="handleOrderClick" @close="handleCartClose" />
|
|
|
|
|
|
@@ -133,6 +133,36 @@ const displayCartList = computed(() => {
|
|
|
return base;
|
|
|
});
|
|
|
|
|
|
+// 将 tags 统一为 [{ text, type }] 格式(与 FoodCard 一致)
|
|
|
+function normalizeTags(raw) {
|
|
|
+ if (raw == null) return [];
|
|
|
+ let arr = [];
|
|
|
+ if (Array.isArray(raw)) arr = raw;
|
|
|
+ else if (typeof raw === 'string') {
|
|
|
+ const t = raw.trim();
|
|
|
+ if (t.startsWith('[')) { try { arr = JSON.parse(t); if (!Array.isArray(arr)) arr = []; } catch { arr = t ? [t] : []; } }
|
|
|
+ else arr = t ? t.split(/[,,、\s]+/).map(s => s.trim()).filter(Boolean) : [];
|
|
|
+ } else if (raw && typeof raw === 'object') arr = Array.isArray(raw.list) ? raw.list : Array.isArray(raw.items) ? raw.items : [];
|
|
|
+ return arr.map((item) => {
|
|
|
+ if (item == null) return { text: '', type: '' };
|
|
|
+ if (typeof item === 'string') return { text: item, type: '' };
|
|
|
+ if (typeof item === 'number') return { text: String(item), type: '' };
|
|
|
+ return { text: item.text ?? item.tagName ?? item.name ?? item.label ?? item.title ?? '', type: item.type ?? item.tagType ?? '' };
|
|
|
+ }).filter((t) => t.text !== '' && t.text != null);
|
|
|
+}
|
|
|
+
|
|
|
+// 购物车展示列表(含标签):从 foodList 补全 cart 项缺失的 tags
|
|
|
+const displayCartListWithTags = computed(() => {
|
|
|
+ return displayCartList.value.map((item) => {
|
|
|
+ const tags = item?.tags ?? item?.tagList ?? item?.tagNames;
|
|
|
+ if (tags != null && (Array.isArray(tags) ? tags.length > 0 : true)) return item;
|
|
|
+ const food = findFoodByCartItem(item);
|
|
|
+ const fromFood = food?.tags ?? food?.tagList ?? food?.tagNames ?? food?.labels ?? food?.tag;
|
|
|
+ const normalized = normalizeTags(fromFood);
|
|
|
+ return normalized.length > 0 ? { ...item, tags: normalized } : item;
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
// 行小计:接口项用 subtotalAmount,否则 数量×单价(与 BottomActionBar/CartModal 一致)
|
|
|
const getItemLinePrice = (item) => {
|
|
|
if (item?.subtotalAmount != null) return Number(item.subtotalAmount);
|
|
|
@@ -607,7 +637,7 @@ const handleOrderClick = () => {
|
|
|
const totalAmount = displayTotalAmount.value;
|
|
|
const dishTotal = Math.max(0, Number(totalAmount) - Number(utensilFee));
|
|
|
const cartPayload = {
|
|
|
- list: displayCartList.value,
|
|
|
+ list: displayCartListWithTags.value,
|
|
|
totalAmount,
|
|
|
dishTotal,
|
|
|
totalQuantity: displayTotalQuantity.value,
|