🎨 refactor(model-pricing/header): unify header design, extract SearchActions, and improve skeleton

- Extract SearchActions.jsx and replace inline renderSearchActions in PricingVendorIntro.jsx for reuse
- Refactor PricingVendorIntro.jsx:
  - Introduce renderHeaderCard(), tagStyle, getCoverStyle(), and MAX_VISIBLE_AVATARS constant
  - Standardize vendor header cover (gradient + background image) and tag contrast
  - Use border instead of ring for vendor badges; unify visuals and remove Tailwind ring dependency
  - Rotate vendors every 2s only when filterVendor === 'all' and vendor count > 3
  - Remove unused imports; keep prop surface minimal; pass setShowFilterModal downward only
- Refactor PricingVendorIntroSkeleton.jsx:
  - Add getCoverStyle() and rect() helpers; rebuild skeleton to match final UI
  - Replace invalid Skeleton.Input usage; add missing keys; unify colors/borders/radius
- Update PricingTopSection.jsx:
  - Manage filter modal locally; drop redundant prop passing
- Update PricingVendorIntroWithSkeleton.jsx:
  - Align prop interface; forward only required props and keep useMinimumLoadingTime
- Add: web/src/components/table/model-pricing/layout/header/SearchActions.jsx
- Lint: all files pass; no dark:* classes present in this scope

Files touched:
- web/src/components/table/model-pricing/layout/header/PricingTopSection.jsx
- web/src/components/table/model-pricing/layout/header/PricingVendorIntro.jsx
- web/src/components/table/model-pricing/layout/header/PricingVendorIntroWithSkeleton.jsx
- web/src/components/table/model-pricing/layout/header/PricingVendorIntroSkeleton.jsx
- web/src/components/table/model-pricing/layout/header/SearchActions.jsx (new)
This commit is contained in:
t0ng7u
2025-08-23 21:11:40 +08:00
parent fc4d593301
commit b10f28e5c6
7 changed files with 362 additions and 202 deletions

View File

@@ -17,9 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import React, { useMemo, useState } from 'react';
import { Input, Button } from '@douyinfe/semi-ui';
import { IconSearch, IconCopy, IconFilter } from '@douyinfe/semi-icons';
import React, { useState } from 'react';
import PricingFilterModal from '../../modal/PricingFilterModal';
import PricingVendorIntroWithSkeleton from './PricingVendorIntroWithSkeleton';
@@ -30,7 +28,6 @@ const PricingTopSection = ({
handleCompositionStart,
handleCompositionEnd,
isMobile,
sidebarProps,
filterVendor,
models,
filteredModels,
@@ -40,69 +37,30 @@ const PricingTopSection = ({
}) => {
const [showFilterModal, setShowFilterModal] = useState(false);
const SearchAndActions = useMemo(() => (
<div className="flex items-center gap-4 w-full">
{/* 搜索框 */}
<div className="flex-1">
<Input
prefix={<IconSearch />}
placeholder={t('模糊搜索模型名称')}
value={searchValue}
onCompositionStart={handleCompositionStart}
onCompositionEnd={handleCompositionEnd}
onChange={handleChange}
showClear
/>
</div>
{/* 操作按钮 */}
<Button
theme='outline'
type='primary'
icon={<IconCopy />}
onClick={() => copyText(selectedRowKeys)}
disabled={selectedRowKeys.length === 0}
className="!bg-blue-500 hover:!bg-blue-600 text-white"
>
{t('复制')}
</Button>
{/* 移动端筛选按钮 */}
{isMobile && (
<Button
theme="outline"
type='tertiary'
icon={<IconFilter />}
onClick={() => setShowFilterModal(true)}
>
{t('筛选')}
</Button>
)}
</div>
), [selectedRowKeys, t, handleCompositionStart, handleCompositionEnd, handleChange, copyText, isMobile, searchValue]);
return (
<>
{/* 供应商介绍区域(桌面端显示 */}
{!isMobile && (
<PricingVendorIntroWithSkeleton
loading={loading}
filterVendor={filterVendor}
models={filteredModels}
allModels={models}
t={t}
/>
)}
{/* 搜索和操作区域 */}
{SearchAndActions}
{/* 供应商介绍区域(包含搜索功能 */}
<PricingVendorIntroWithSkeleton
loading={loading}
filterVendor={filterVendor}
models={filteredModels}
allModels={models}
t={t}
selectedRowKeys={selectedRowKeys}
copyText={copyText}
handleChange={handleChange}
handleCompositionStart={handleCompositionStart}
handleCompositionEnd={handleCompositionEnd}
isMobile={isMobile}
searchValue={searchValue}
setShowFilterModal={setShowFilterModal}
/>
{/* 移动端筛选Modal */}
{isMobile && (
<PricingFilterModal
visible={showFilterModal}
onClose={() => setShowFilterModal(false)}
sidebarProps={sidebarProps}
t={t}
/>
)}