import { resolveFileUrl } from '@/utils/image' import { formatPrice } from '@/utils/format' import { CART_INVALID_NONE, CART_INVALID_OUT_OF_STOCK, CART_INVALID_OFF_SHELF, CART_INVALID_SHOP_CLOSED, CART_INVALID_CATEGORY_HIDDEN, CART_INVALID_GOODS_DELETED, CART_INVALID_SHOP_DELETED } from '@/constants/cart' import { SHOP_STATUS_CLOSED } from '@/constants/shop' import { parseCartSpecText } from '@/utils/cartSpec' const GOODS_PLACEHOLDER = '/static/logo.png' const INVALID_LABEL_MAP = { [CART_INVALID_OUT_OF_STOCK]: '缺货', [CART_INVALID_OFF_SHELF]: '已下架', [CART_INVALID_SHOP_CLOSED]: '休息中', [CART_INVALID_CATEGORY_HIDDEN]: '不可购买', [CART_INVALID_GOODS_DELETED]: '已失效', [CART_INVALID_SHOP_DELETED]: '店铺失效' } export function getCartInvalidLabel(invalidType, invalidMsg) { if (!invalidType || invalidType === CART_INVALID_NONE) return '' return invalidMsg || INVALID_LABEL_MAP[invalidType] || '不可购买' } function mapCartItem(row) { if (!row) return null const invalidType = row.invalidType || CART_INVALID_NONE const purchasable = !!row.purchasable && invalidType === CART_INVALID_NONE return { cartItemId: row.cartItemId, goodsId: row.goodsId, goodsName: row.goodsName || '', mainPic: row.mainPic || '', displayPic: resolveFileUrl(row.mainPic) || GOODS_PLACEHOLDER, specText: (row.specText || '').trim() || '默认', specList: parseCartSpecText(row.specText), salePrice: row.salePrice, priceText: formatPrice(row.salePrice), quantity: Number(row.quantity) || 1, subtotal: row.subtotal, subtotalText: formatPrice(row.subtotal), checked: !!row.checked, purchasable, invalidType, invalidMsg: row.invalidMsg || '', invalidLabel: getCartInvalidLabel(invalidType, row.invalidMsg) } } function mapShopGroup(group) { if (!group) return null return { shopId: group.shopId, shopName: group.shopName || '', shopStatus: group.shopStatus, isClosed: String(group.shopStatus) === SHOP_STATUS_CLOSED, items: (group.items || []).map(mapCartItem).filter(Boolean) } } function mapCheckedSummary(summary) { const s = summary || {} const amount = s.checkedAmount return { checkedCount: Number(s.checkedCount) || 0, checkedQuantity: Number(s.checkedQuantity) || 0, checkedAmount: amount, checkedAmountText: formatPrice(amount) } } /** 扁平 items[] 按店铺分组(保持接口 cart_item_id 倒序下的店组顺序) */ function groupCartItemsByShop(flatItems) { const groups = [] const groupIndex = new Map() for (const row of flatItems || []) { const item = mapCartItem(row) if (!item) continue const shopId = row.shopId let group if (groupIndex.has(shopId)) { group = groups[groupIndex.get(shopId)] } else { group = { shopId, shopName: row.shopName || '', shopStatus: row.shopStatus, isClosed: String(row.shopStatus) === SHOP_STATUS_CLOSED, items: [] } groupIndex.set(shopId, groups.length) groups.push(group) } group.items.push(item) } return groups } /** 列表接口 data → 页面模型 */ export function mapCartList(data) { if (!data) { return { groups: [], checkedSummary: mapCheckedSummary(null) } } const groups = Array.isArray(data.groups) && data.groups.length ? data.groups.map(mapShopGroup).filter(Boolean) : groupCartItemsByShop(data.items || []) return { groups, checkedSummary: mapCheckedSummary(data.checkedSummary) } } /** 是否存在失效行 */ export function hasInvalidCartItems(groups) { return countInvalidCartItems(groups) > 0 } /** 失效商品件数(清理失效前展示) */ export function countInvalidCartItems(groups) { if (!Array.isArray(groups)) return 0 let count = 0 groups.forEach((g) => { ;(g.items || []).forEach((item) => { if (!item.purchasable) count += 1 }) }) return count } /** 当前勾选的可购行 shopId 集合 */ export function getCheckedShopIds(groups) { const ids = new Set() if (!Array.isArray(groups)) return ids groups.forEach((g) => { ;(g.items || []).forEach((item) => { if (item.checked && item.purchasable) { ids.add(g.shopId) } }) }) return ids } /** 已勾选且可购的 cartItemId */ export function getCheckedPurchasableIds(groups) { const ids = [] if (!Array.isArray(groups)) return ids groups.forEach((g) => { ;(g.items || []).forEach((item) => { if (item.checked && item.purchasable) { ids.push(item.cartItemId) } }) }) return ids } /** 全部可购行 */ export function getAllPurchasableItems(groups) { const list = [] if (!Array.isArray(groups)) return list groups.forEach((g) => { ;(g.items || []).forEach((item) => { if (item.purchasable) { list.push({ ...item, shopId: g.shopId }) } }) }) return list }