🏗️ refactor: Replace model categories with vendor-based filtering and optimize data structure
- **Backend Changes:** - Refactor pricing API to return separate vendors array with ID-based model references - Remove redundant vendor_name/vendor_icon fields from pricing records, use vendor_id only - Add vendor_description to pricing response for frontend display - Maintain 1-minute cache protection for pricing endpoint security - **Frontend Data Flow:** - Update useModelPricingData hook to build vendorsMap from API response - Enhance model records with vendor info during data processing - Pass vendorsMap through component hierarchy for consistent vendor data access - **UI Component Replacements:** - Replace PricingCategories with PricingVendors component for vendor-based filtering - Replace PricingCategoryIntro with PricingVendorIntro in header section - Remove all model category related components and logic - **Header Improvements:** - Implement vendor intro with real backend data (name, icon, description) - Add text collapsible feature (2-line limit with expand/collapse functionality) - Support carousel animation for "All Vendors" view with vendor icon rotation - **Model Detail Modal Enhancements:** - Update ModelHeader to use real vendor icons via getLobeHubIcon() - Move tags from header to ModelBasicInfo content area to avoid SideSheet title width constraints - Display only custom tags from backend with stringToColor() for consistent styling - Use Space component with wrap property for proper tag layout - **Table View Optimizations:** - Integrate RenderUtils for description and tags columns - Implement renderLimitedItems for tags (max 3 visible, +x popover for overflow) - Use renderDescription for text truncation with tooltip support - **Filter Logic Updates:** - Vendor filter shows disabled options instead of hiding when no models match - Include "Unknown Vendor" category for models without vendor information - Remove all hardcoded vendor descriptions, use real backend data - **Code Quality:** - Fix import paths after component relocation - Remove unused model category utilities and hardcoded mappings - Ensure consistent vendor data usage across all pricing views - Maintain backward compatibility with existing pricing calculation logic This refactor provides a more scalable vendor-based architecture while eliminating data redundancy and improving user experience with real-time backend data integration.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright (C) 2025 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Card, Skeleton } from '@douyinfe/semi-ui';
|
||||
|
||||
const PricingVendorIntroSkeleton = ({
|
||||
isAllVendors = false
|
||||
}) => {
|
||||
const placeholder = (
|
||||
<div className='mb-4'>
|
||||
<Card className="!rounded-2xl" bodyStyle={{ padding: '16px' }}>
|
||||
<div className="flex items-start space-x-3 md:space-x-4">
|
||||
{/* 供应商图标骨架 */}
|
||||
<div className="flex-shrink-0 min-w-16 h-16 rounded-2xl bg-white shadow-md flex items-center justify-center px-2">
|
||||
{isAllVendors ? (
|
||||
<div className="flex items-center">
|
||||
{Array.from({ length: 4 }).map((_, index) => (
|
||||
<Skeleton.Avatar
|
||||
key={index}
|
||||
active
|
||||
size="default"
|
||||
style={{
|
||||
width: 32,
|
||||
height: 32,
|
||||
marginRight: index < 3 ? -8 : 0,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<Skeleton.Avatar active size="large" style={{ width: 40, height: 40, borderRadius: 8 }} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 供应商信息骨架 */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-3 mb-2">
|
||||
<Skeleton.Title active style={{ width: 120, height: 24, marginBottom: 0 }} />
|
||||
<Skeleton.Button active size="small" style={{ width: 80, height: 20, borderRadius: 12 }} />
|
||||
</div>
|
||||
<Skeleton.Paragraph
|
||||
active
|
||||
rows={2}
|
||||
style={{ marginBottom: 0 }}
|
||||
title={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<Skeleton loading={true} active placeholder={placeholder}></Skeleton>
|
||||
);
|
||||
};
|
||||
|
||||
export default PricingVendorIntroSkeleton;
|
||||
Reference in New Issue
Block a user