import { PageContainer } from '@ant-design/pro-components'; import { request } from '@umijs/max'; import { Card, Col, Image, Layout, Row, Select, Space, Typography, message, } from 'antd'; import React, { useEffect, useState } from 'react'; const { Sider, Content } = Layout; const { Title, Text } = Typography; const { Option } = Select; // Define interfaces interface Brand { id: number; name: string; shortName?: string; image?: string; } interface Attribute { id: number; name: string; title: string; } interface AttributeValue { id: number; name: string; title: string; titleCN?: string; value?: string; image?: string; } interface Product { id: number; sku: string; name: string; image?: string; brandId: number; brandName: string; attributes: { [key: string]: any }; } const BrandSpace: React.FC = () => { // State management const [brands, setBrands] = useState([]); const [selectedBrand, setSelectedBrand] = useState(null); const [attributes, setAttributes] = useState([]); const [selectedAttribute, setSelectedAttribute] = useState( null, ); const [attributeValues, setAttributeValues] = useState([]); const [selectedAttributeValue, setSelectedAttributeValue] = useState< number | null >(null); const [products, setProducts] = useState([]); const [loading, setLoading] = useState(false); const [attributeValuesLoading, setAttributeValuesLoading] = useState(false); // Fetch brands list const fetchBrands = async () => { try { const response = await request('/dict/items', { params: { dictId: 'brand' }, // Assuming brand is a dict }); const brandList = Array.isArray(response) ? response : response?.data || []; setBrands(brandList); // Set default brand to "yoone" if exists const defaultBrand = brandList.find((brand) => brand.name === 'yoone'); if (defaultBrand) { setSelectedBrand(defaultBrand.id); } } catch (error) { console.error('Failed to fetch brands:', error); message.error('获取品牌列表失败'); } }; // Fetch attributes list const fetchAttributes = async () => { try { // Get all dicts that are attributes (excluding non-attribute dicts) const response = await request('/dict/list'); const dictList = Array.isArray(response) ? response : response?.data || []; // Filter out non-attribute dicts (assuming attributes are specific dicts) const attributeDicts = dictList.filter((dict: any) => ['strength', 'flavor', 'humidity', 'size', 'version'].includes( dict.name, ), ); setAttributes(attributeDicts); // Set default attribute to strength if exists const defaultAttribute = attributeDicts.find( (attr) => attr.name === 'strength', ); if (defaultAttribute) { setSelectedAttribute(defaultAttribute.name); } } catch (error) { console.error('Failed to fetch attributes:', error); message.error('获取属性列表失败'); } }; // Fetch attribute values based on selected attribute const fetchAttributeValues = async (attributeName: string) => { setAttributeValuesLoading(true); try { const response = await request('/dict/items', { params: { dictId: attributeName }, }); const values = Array.isArray(response) ? response : response?.data || []; setAttributeValues(values); } catch (error) { console.error('Failed to fetch attribute values:', error); message.error('获取属性值列表失败'); // Clear attribute values on error setAttributeValues([]); } finally { setAttributeValuesLoading(false); } }; // Fetch products based on filters const fetchProducts = async () => { if (!selectedBrand) return; setLoading(true); try { const params: any = { brandId: selectedBrand, }; // Add attribute filter if selected if (selectedAttribute) { // If attribute value is selected, filter by both attribute and value if (selectedAttributeValue) { params[selectedAttribute] = selectedAttributeValue; } else { // If only attribute is selected, filter by attribute presence params[selectedAttribute] = 'hasValue'; } } const response = await request('/product/list', { params, }); const productList = response?.data?.items || []; setProducts(productList); } catch (error) { console.error('Failed to fetch products:', error); message.error('获取产品列表失败'); // Clear products on error setProducts([]); } finally { setLoading(false); } }; // Initial data fetch useEffect(() => { fetchBrands(); fetchAttributes(); }, []); // Fetch attribute values when attribute changes useEffect(() => { if (selectedAttribute) { fetchAttributeValues(selectedAttribute); setSelectedAttributeValue(null); // Reset selected value when attribute changes } }, [selectedAttribute]); // Fetch products when filters change useEffect(() => { fetchProducts(); }, [selectedBrand, selectedAttribute, selectedAttributeValue]); // Handle brand selection change const handleBrandChange = (value: number) => { setSelectedBrand(value); }; // Handle attribute selection change const handleAttributeChange = (value: string) => { setSelectedAttribute(value); }; // Handle attribute value selection change const handleAttributeValueChange = (value: number) => { setSelectedAttributeValue(value); }; return ( {/* Top Brand Selection */}
选择品牌
{/* Left Attribute Selection */}
选择属性 {selectedAttribute && ( <> 属性值 )} {/* Filter Summary */} {selectedBrand && (
当前筛选条件:
品牌: {brands.find((b) => b.id === selectedBrand)?.name}
{selectedAttribute && (
{ attributes.find((a) => a.name === selectedAttribute) ?.title } : {selectedAttributeValue ? attributeValues.find( (v) => v.id === selectedAttributeValue, )?.titleCN || attributeValues.find( (v) => v.id === selectedAttributeValue, )?.title : '所有值'}
)}
)}
{/* Main Content - Product List */}
产品列表 <Text type="secondary" style={{ fontSize: 16, marginLeft: 8 }}> ({products.length} 个产品) </Text>
{loading ? (
加载中...
) : attributeValues.length > 0 ? (
{attributeValues.map((attributeValue) => { // Filter products for this attribute value if(!Array.isArray(products)){ console.log('products',products) return null } const attributeValueProducts = selectedAttribute ? (products || []).filter((product) => product.attributes && product.attributes[selectedAttribute] === attributeValue.id ) : []; return ( {attributeValue.image && ( )} {attributeValue.titleCN || attributeValue.title || attributeValue.name} } style={{ width: 300 }} > {attributeValueProducts.length > 0 ? (
{attributeValueProducts.map((product) => (
{product.name}
{product.sku}
{product.name}
¥{product.price || '--'}
))}
) : (
暂无产品
)}
); })}
) : (
暂无属性值或产品
)}
); }; export default BrandSpace;