interface CategoryChild { id: number; name: string; parentId: number; parentName: string; tag: string; productNum: number; children: CategoryChild[]; } interface Category { id: number; name: string; tag: string; productNum: number; children: CategoryChild[]; } interface ProductItem { id: number; name: string; psd_img_url: string; thumbImgUrl: string; currentPrice: number; color_str: string[]; } interface ProductPage { totalCount: number; items: ProductItem[]; page: number; size: number; } interface CountryGroup { id: number; name: string; products: CategoryChild[]; } const COUNTRY_NAME_MAP: Record = { '美国工厂直发': '美国', '日本本地工厂直发': '日本', '墨西哥工厂本地直发': '墨西哥', '巴西本地工厂直发': '巴西', '中东本地工厂直发': '中东', '欧洲波兰工厂直发': '波兰', '欧洲西班牙工厂直发': '西班牙', '欧洲德国工厂本地直发': '德国', '欧洲意大利工厂直发': '意大利', '英国本地直发': '英国', '加拿大本地工厂直发': '加拿大', '澳大利亚本地工厂直发': '澳大利亚', '韩国本地直发': '韩国', }; export function usePodProducts() { const categories = ref([]); const countryGroups = ref([]); const activeCountryIdx = ref(0); const productImages = ref>(new Map()); const loading = ref(true); const loadingProducts = ref(false); const countryPage = ref(0); const visibleCountryCount = 6; const fetchCategories = async () => { try { loading.value = true; const data = await $fetch('/api/pod/categories', { method: 'POST', }); categories.value = data; countryGroups.value = data.map((cat) => ({ id: cat.id, name: COUNTRY_NAME_MAP[cat.name] ?? cat.name, products: cat.children, })); if (countryGroups.value.length > 0) { await fetchProductsForCountry(0); } } catch (error) { console.error('Failed to fetch categories:', error); } finally { loading.value = false; } }; const fetchProductsForCountry = async (idx: number) => { const group = countryGroups.value[idx]; if (!group) return; loadingProducts.value = true; try { const children = group.products.slice(0, 10); const promises = children.map((child) => $fetch(`/api/pod/products/${child.id}`).then((res) => ({ id: child.id, name: child.name, image: res.items?.[0]?.psd_img_url ?? res.items?.[0]?.thumbImgUrl ?? '', })).catch(() => ({ id: child.id, name: child.name, image: '', })), ); const results = await Promise.all(promises); const newMap = new Map(productImages.value); for (const r of results) { newMap.set(r.id, r.image); } productImages.value = newMap; } catch (error) { console.error('Failed to fetch products:', error); } finally { loadingProducts.value = false; } }; const selectCountry = (idx: number) => { activeCountryIdx.value = idx; countryPage.value = Math.floor(idx / visibleCountryCount); fetchProductsForCountry(idx); }; const visibleCountries = computed(() => { const start = countryPage.value * visibleCountryCount; return countryGroups.value.slice(start, start + visibleCountryCount); }); const canPrevCountry = computed(() => countryPage.value > 0); const canNextCountry = computed( () => (countryPage.value + 1) * visibleCountryCount < countryGroups.value.length, ); const currentProducts = computed(() => { const group = countryGroups.value[activeCountryIdx.value]; if (!group) return []; return group.products.slice(0, 10).map((p) => ({ id: p.id, name: p.name, image: productImages.value.get(p.id) ?? '', })); }); return { categories, countryGroups, activeCountryIdx, productImages, loading, loadingProducts, countryPage, visibleCountryCount, visibleCountries, canPrevCountry, canNextCountry, currentProducts, fetchCategories, selectCountry, }; }