refactor(icons): 迁移 views/Company 目录图标到 lucide-react

- @chakra-ui/icons → lucide-react
- react-icons → lucide-react
- IconType → LucideIcon 类型替换
- 涉及 50 个组件文件

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-25 12:24:11 +08:00
parent b2100d6f75
commit 29f6701de3
50 changed files with 271 additions and 283 deletions

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Box, Text, VStack, Icon } from '@chakra-ui/react'; import { Box, Text, VStack, Icon } from '@chakra-ui/react';
import { FaChartLine } from 'react-icons/fa'; import { LineChart } from 'lucide-react';
/** /**
* 预测报告组件 - 占位符 * 预测报告组件 - 占位符
@@ -16,7 +16,7 @@ const ForecastReport = ({ stockCode }) => {
textAlign="center" textAlign="center"
> >
<VStack spacing={4}> <VStack spacing={4}>
<Icon as={FaChartLine} boxSize={12} color="gray.400" /> <Icon as={LineChart} boxSize={12} color="gray.400" />
<Text fontSize="lg" fontWeight="medium" color="gray.600" _dark={{ color: 'gray.400' }}> <Text fontSize="lg" fontWeight="medium" color="gray.600" _dark={{ color: 'gray.400' }}>
预测报告功能开发中 预测报告功能开发中
</Text> </Text>

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Box, Text, VStack, Icon } from '@chakra-ui/react'; import { Box, Text, VStack, Icon } from '@chakra-ui/react';
import { FaChartBar } from 'react-icons/fa'; import { BarChart2 } from 'lucide-react';
/** /**
* 市场数据视图组件 - 占位符 * 市场数据视图组件 - 占位符
@@ -16,7 +16,7 @@ const MarketDataView = ({ stockCode }) => {
textAlign="center" textAlign="center"
> >
<VStack spacing={4}> <VStack spacing={4}>
<Icon as={FaChartBar} boxSize={12} color="gray.400" /> <Icon as={BarChart2} boxSize={12} color="gray.400" />
<Text fontSize="lg" fontWeight="medium" color="gray.600" _dark={{ color: 'gray.400' }}> <Text fontSize="lg" fontWeight="medium" color="gray.600" _dark={{ color: 'gray.400' }}>
市场数据功能开发中 市场数据功能开发中
</Text> </Text>

View File

@@ -22,7 +22,7 @@ import {
ModalFooter, ModalFooter,
useDisclosure, useDisclosure,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { ExternalLinkIcon } from "@chakra-ui/icons"; import { ExternalLink } from "lucide-react";
import { useAnnouncementsData } from "../../hooks/useAnnouncementsData"; import { useAnnouncementsData } from "../../hooks/useAnnouncementsData";
import { THEME } from "../config"; import { THEME } from "../config";
@@ -92,7 +92,7 @@ const AnnouncementsPanel: React.FC<AnnouncementsPanelProps> = ({ stockCode, isAc
)} )}
<IconButton <IconButton
size="sm" size="sm"
icon={<ExternalLinkIcon />} icon={<ExternalLink size={16} />}
variant="ghost" variant="ghost"
color={THEME.goldLight} color={THEME.goldLight}
aria-label="查看原文" aria-label="查看原文"

View File

@@ -11,7 +11,7 @@ import {
SimpleGrid, SimpleGrid,
Center, Center,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { FaSitemap, FaBuilding, FaCheckCircle, FaTimesCircle } from "react-icons/fa"; import { GitBranch, Building2, CheckCircle, XCircle } from "lucide-react";
import { useBranchesData } from "../../hooks/useBranchesData"; import { useBranchesData } from "../../hooks/useBranchesData";
import { THEME } from "../config"; import { THEME } from "../config";
@@ -85,7 +85,7 @@ const BranchesPanel: React.FC<BranchesPanelProps> = ({ stockCode, isActive = tru
border="1px solid" border="1px solid"
borderColor="rgba(212, 175, 55, 0.2)" borderColor="rgba(212, 175, 55, 0.2)"
> >
<Icon as={FaSitemap} boxSize={10} color={THEME.gold} opacity={0.6} /> <Icon as={GitBranch} boxSize={10} color={THEME.gold} opacity={0.6} />
</Box> </Box>
<Text color={THEME.textSecondary} fontSize="sm"> <Text color={THEME.textSecondary} fontSize="sm">
@@ -118,7 +118,7 @@ const BranchesPanel: React.FC<BranchesPanelProps> = ({ stockCode, isActive = tru
borderRadius="md" borderRadius="md"
bg="rgba(212, 175, 55, 0.1)" bg="rgba(212, 175, 55, 0.1)"
> >
<Icon as={FaBuilding} boxSize={3.5} color={THEME.gold} /> <Icon as={Building2} boxSize={3.5} color={THEME.gold} />
</Box> </Box>
<Text <Text
fontWeight="bold" fontWeight="bold"
@@ -134,7 +134,7 @@ const BranchesPanel: React.FC<BranchesPanelProps> = ({ stockCode, isActive = tru
{/* 状态徽章 */} {/* 状态徽章 */}
<Box sx={getStatusBadgeStyles(isActive)}> <Box sx={getStatusBadgeStyles(isActive)}>
<Icon <Icon
as={isActive ? FaCheckCircle : FaTimesCircle} as={isActive ? CheckCircle : XCircle}
boxSize={3} boxSize={3}
/> />
<Text>{branch.business_status}</Text> <Text>{branch.business_status}</Text>

View File

@@ -12,15 +12,15 @@ import {
Icon, Icon,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { import {
FaBuilding, Building2,
FaMapMarkerAlt, MapPin,
FaIdCard, CreditCard,
FaUsers, Users,
FaBalanceScale, Scale,
FaCalculator, Calculator,
FaBriefcase, Briefcase,
FaFileAlt, FileText,
} from "react-icons/fa"; } from "lucide-react";
// 使用统一主题 // 使用统一主题
import { COLORS, GLASS, glassCardStyle } from "@views/Company/theme"; import { COLORS, GLASS, glassCardStyle } from "@views/Company/theme";
@@ -173,27 +173,27 @@ const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode, isActi
<SimpleGrid columns={{ base: 1, lg: 2 }} spacing={4}> <SimpleGrid columns={{ base: 1, lg: 2 }} spacing={4}>
{/* 工商信息卡片 */} {/* 工商信息卡片 */}
<Box {...glassCardStyle} p={4}> <Box {...glassCardStyle} p={4}>
<SectionTitle icon={FaBuilding} title="工商信息" /> <SectionTitle icon={Building2} title="工商信息" />
<VStack spacing={2} align="stretch"> <VStack spacing={2} align="stretch">
<InfoRow <InfoRow
icon={FaIdCard} icon={CreditCard}
label="信用代码" label="信用代码"
value={basicInfo.credit_code} value={basicInfo.credit_code}
isCode isCode
/> />
<InfoRow <InfoRow
icon={FaUsers} icon={Users}
label="公司规模" label="公司规模"
value={basicInfo.company_size} value={basicInfo.company_size}
/> />
<InfoRow <InfoRow
icon={FaMapMarkerAlt} icon={MapPin}
label="注册地址" label="注册地址"
value={basicInfo.reg_address} value={basicInfo.reg_address}
isMultiline isMultiline
/> />
<InfoRow <InfoRow
icon={FaMapMarkerAlt} icon={MapPin}
label="办公地址" label="办公地址"
value={basicInfo.office_address} value={basicInfo.office_address}
isMultiline isMultiline
@@ -203,15 +203,15 @@ const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode, isActi
{/* 服务机构卡片 */} {/* 服务机构卡片 */}
<Box {...glassCardStyle} p={4}> <Box {...glassCardStyle} p={4}>
<SectionTitle icon={FaBalanceScale} title="服务机构" /> <SectionTitle icon={Scale} title="服务机构" />
<VStack spacing={3} align="stretch"> <VStack spacing={3} align="stretch">
<ServiceCard <ServiceCard
icon={FaCalculator} icon={Calculator}
label="会计师事务所" label="会计师事务所"
value={basicInfo.accounting_firm} value={basicInfo.accounting_firm}
/> />
<ServiceCard <ServiceCard
icon={FaBalanceScale} icon={Scale}
label="律师事务所" label="律师事务所"
value={basicInfo.law_firm} value={basicInfo.law_firm}
/> />
@@ -222,12 +222,12 @@ const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode, isActi
{/* 下半部分:主营业务 + 经营范围 */} {/* 下半部分:主营业务 + 经营范围 */}
<SimpleGrid columns={{ base: 1, lg: 2 }} spacing={4}> <SimpleGrid columns={{ base: 1, lg: 2 }} spacing={4}>
<TextSection <TextSection
icon={FaBriefcase} icon={Briefcase}
title="主营业务" title="主营业务"
content={basicInfo.main_business} content={basicInfo.main_business}
/> />
<TextSection <TextSection
icon={FaFileAlt} icon={FileText}
title="经营范围" title="经营范围"
content={basicInfo.business_scope} content={basicInfo.business_scope}
/> />

View File

@@ -24,11 +24,11 @@ import {
Td, Td,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { import {
FaShareAlt, Share2,
FaUserTie, UserRound,
FaSitemap, GitBranch,
FaInfoCircle, Info,
} from 'react-icons/fa'; } from 'lucide-react';
// 深空 FUI 主题配置(与 SubTabContainer 保持一致) // 深空 FUI 主题配置(与 SubTabContainer 保持一致)
const DEEP_SPACE = { const DEEP_SPACE = {
@@ -46,10 +46,10 @@ const DEEP_SPACE = {
// 导航配置(与主组件 config.ts 保持同步) // 导航配置(与主组件 config.ts 保持同步)
const OVERVIEW_TABS = [ const OVERVIEW_TABS = [
{ key: 'shareholder', name: '股权结构', icon: FaShareAlt }, { key: 'shareholder', name: '股权结构', icon: Share2 },
{ key: 'management', name: '管理团队', icon: FaUserTie }, { key: 'management', name: '管理团队', icon: UserRound },
{ key: 'branches', name: '分支机构', icon: FaSitemap }, { key: 'branches', name: '分支机构', icon: GitBranch },
{ key: 'business', name: '工商信息', icon: FaInfoCircle }, { key: 'business', name: '工商信息', icon: Info },
]; ];
/** /**

View File

@@ -10,7 +10,7 @@ import {
Icon, Icon,
SimpleGrid, SimpleGrid,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import type { IconType } from "react-icons"; import type { LucideIcon } from "lucide-react";
import { THEME } from "../../config"; import { THEME } from "../../config";
import ManagementCard from "./ManagementCard"; import ManagementCard from "./ManagementCard";
@@ -19,7 +19,7 @@ import type { ManagementPerson, ManagementCategory } from "./types";
interface CategorySectionProps { interface CategorySectionProps {
category: ManagementCategory; category: ManagementCategory;
people: ManagementPerson[]; people: ManagementPerson[];
icon: IconType; icon: LucideIcon;
color: string; color: string;
} }

View File

@@ -13,10 +13,10 @@ import {
Tag, Tag,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { import {
FaVenusMars, Users as GenderIcon,
FaGraduationCap, GraduationCap,
FaPassport, CreditCard,
} from "react-icons/fa"; } from "lucide-react";
import { THEME } from "../../config"; import { THEME } from "../../config";
import { formatDate } from "../../utils"; import { formatDate } from "../../utils";
@@ -53,7 +53,7 @@ const ManagementCard: React.FC<ManagementCardProps> = ({ person, categoryColor }
</Text> </Text>
{person.gender && ( {person.gender && (
<Icon <Icon
as={FaVenusMars} as={GenderIcon}
color={person.gender === "男" ? "blue.400" : "pink.400"} color={person.gender === "男" ? "blue.400" : "pink.400"}
boxSize={3} boxSize={3}
/> />
@@ -69,7 +69,7 @@ const ManagementCard: React.FC<ManagementCardProps> = ({ person, categoryColor }
<HStack spacing={2} flexWrap="wrap"> <HStack spacing={2} flexWrap="wrap">
{person.education && ( {person.education && (
<Tag size="sm" bg={THEME.tableHoverBg} color={THEME.textSecondary}> <Tag size="sm" bg={THEME.tableHoverBg} color={THEME.textSecondary}>
<Icon as={FaGraduationCap} mr={1} boxSize={3} /> <Icon as={GraduationCap} mr={1} boxSize={3} />
{person.education} {person.education}
</Tag> </Tag>
)} )}
@@ -80,7 +80,7 @@ const ManagementCard: React.FC<ManagementCardProps> = ({ person, categoryColor }
)} )}
{person.nationality && person.nationality !== "中国" && ( {person.nationality && person.nationality !== "中国" && (
<Tag size="sm" bg="orange.600" color="white"> <Tag size="sm" bg="orange.600" color="white">
<Icon as={FaPassport} mr={1} boxSize={3} /> <Icon as={CreditCard} mr={1} boxSize={3} />
{person.nationality} {person.nationality}
</Tag> </Tag>
)} )}

View File

@@ -3,11 +3,11 @@
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import { import {
FaUserTie, UserRound,
FaCrown, Crown,
FaEye, Eye,
FaUsers, Users,
} from "react-icons/fa"; } from "lucide-react";
import { useManagementData } from "../../../hooks/useManagementData"; import { useManagementData } from "../../../hooks/useManagementData";
import { THEME } from "../../config"; import { THEME } from "../../config";
@@ -31,10 +31,10 @@ interface ManagementPanelProps {
* 分类配置映射 * 分类配置映射
*/ */
const CATEGORY_CONFIG: Record<ManagementCategory, CategoryConfig> = { const CATEGORY_CONFIG: Record<ManagementCategory, CategoryConfig> = {
: { icon: FaUserTie, color: THEME.gold }, : { icon: UserRound, color: THEME.gold },
: { icon: FaCrown, color: THEME.goldLight }, : { icon: Crown, color: THEME.goldLight },
: { icon: FaEye, color: "green.400" }, : { icon: Eye, color: "green.400" },
: { icon: FaUsers, color: THEME.textSecondary }, : { icon: Users, color: THEME.textSecondary },
}; };
/** /**

View File

@@ -1,7 +1,7 @@
// src/views/Company/components/CompanyOverview/BasicInfoTab/components/management/types.ts // src/views/Company/components/CompanyOverview/BasicInfoTab/components/management/types.ts
// 管理团队相关类型定义 // 管理团队相关类型定义
import type { IconType } from "react-icons"; import type { LucideIcon } from "lucide-react";
/** /**
* 管理人员信息 * 管理人员信息
@@ -31,6 +31,6 @@ export type CategorizedManagement = Record<ManagementCategory, ManagementPerson[
* 分类配置项 * 分类配置项
*/ */
export interface CategoryConfig { export interface CategoryConfig {
icon: IconType; icon: LucideIcon;
color: string; color: string;
} }

View File

@@ -1,13 +1,7 @@
// src/views/Company/components/CompanyOverview/BasicInfoTab/config.ts // src/views/Company/components/CompanyOverview/BasicInfoTab/config.ts
// Tab 配置 + 黑金主题配置 // Tab 配置 + 黑金主题配置
import { IconType } from "react-icons"; import { LucideIcon, Share2, UserRound, GitBranch, Info } from "lucide-react";
import {
FaShareAlt,
FaUserTie,
FaSitemap,
FaInfoCircle,
} from "react-icons/fa";
// 主题类型定义 // 主题类型定义
export interface Theme { export interface Theme {
@@ -54,7 +48,7 @@ export const THEME: Theme = {
export interface TabConfig { export interface TabConfig {
key: string; key: string;
name: string; name: string;
icon: IconType; icon: LucideIcon;
enabled: boolean; enabled: boolean;
} }
@@ -63,25 +57,25 @@ export const TAB_CONFIG: TabConfig[] = [
{ {
key: "shareholder", key: "shareholder",
name: "股权结构", name: "股权结构",
icon: FaShareAlt, icon: Share2,
enabled: true, enabled: true,
}, },
{ {
key: "management", key: "management",
name: "管理团队", name: "管理团队",
icon: FaUserTie, icon: UserRound,
enabled: true, enabled: true,
}, },
{ {
key: "branches", key: "branches",
name: "分支机构", name: "分支机构",
icon: FaSitemap, icon: GitBranch,
enabled: true, enabled: true,
}, },
{ {
key: "business", key: "business",
name: "工商信息", name: "工商信息",
icon: FaInfoCircle, icon: Info,
enabled: true, enabled: true,
}, },
]; ];

View File

@@ -17,7 +17,7 @@ import {
Tag, Tag,
Icon, Icon,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaArrowUp, FaArrowDown } from 'react-icons/fa'; import { ArrowUp, ArrowDown } from 'lucide-react';
import type { KeyFactorCardProps, ImpactDirection } from '../types'; import type { KeyFactorCardProps, ImpactDirection } from '../types';
// 黑金主题样式常量 // 黑金主题样式常量
@@ -94,7 +94,7 @@ const KeyFactorCard: React.FC<KeyFactorCardProps> = ({ factor }) => {
color={factor.year_on_year > 0 ? 'red.400' : 'green.400'} color={factor.year_on_year > 0 ? 'red.400' : 'green.400'}
> >
<Icon <Icon
as={factor.year_on_year > 0 ? FaArrowUp : FaArrowDown} as={factor.year_on_year > 0 ? ArrowUp : ArrowDown}
mr={1} mr={1}
boxSize={3} boxSize={3}
/> />

View File

@@ -7,7 +7,7 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { HStack, VStack, Box, Text, Icon, Badge } from '@chakra-ui/react'; import { HStack, VStack, Box, Text, Icon, Badge } from '@chakra-ui/react';
import { FaArrowRight } from 'react-icons/fa'; import { ArrowRight } from 'lucide-react';
// 黑金主题配置(使用更亮的金色提高对比度) // 黑金主题配置(使用更亮的金色提高对比度)
const THEME = { const THEME = {
@@ -133,7 +133,7 @@ const ProcessNavigation: React.FC<ProcessNavigationProps> = memo(({
/> />
<Icon <Icon
as={FaArrowRight} as={ArrowRight}
color={THEME.textSecondary} color={THEME.textSecondary}
boxSize={4} boxSize={4}
/> />
@@ -148,7 +148,7 @@ const ProcessNavigation: React.FC<ProcessNavigationProps> = memo(({
/> />
<Icon <Icon
as={FaArrowRight} as={ArrowRight}
color={THEME.textSecondary} color={THEME.textSecondary}
boxSize={4} boxSize={4}
/> />

View File

@@ -20,7 +20,7 @@ import {
SimpleGrid, SimpleGrid,
Button, Button,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaIndustry, FaExpandAlt, FaCompressAlt } from 'react-icons/fa'; import { Factory, Maximize2, Minimize2 } from 'lucide-react';
import type { BusinessSegment } from '../types'; import type { BusinessSegment } from '../types';
// 黑金主题配置 // 黑金主题配置
@@ -52,7 +52,7 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
<Card bg={THEME.cardBg} shadow="md"> <Card bg={THEME.cardBg} shadow="md">
<CardHeader> <CardHeader>
<HStack> <HStack>
<Icon as={FaIndustry} color={THEME.gold} /> <Icon as={Factory} color={THEME.gold} />
<Heading size="sm" color={THEME.textPrimary}></Heading> <Heading size="sm" color={THEME.textPrimary}></Heading>
<Badge bg={THEME.gold} color="gray.900">{businessSegments.length} </Badge> <Badge bg={THEME.gold} color="gray.900">{businessSegments.length} </Badge>
</HStack> </HStack>
@@ -74,7 +74,7 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
size="sm" size="sm"
variant="ghost" variant="ghost"
leftIcon={ leftIcon={
<Icon as={isExpanded ? FaCompressAlt : FaExpandAlt} /> <Icon as={isExpanded ? Minimize2 : Maximize2} />
} }
onClick={() => onToggleSegment(idx)} onClick={() => onToggleSegment(idx)}
color={THEME.gold} color={THEME.gold}

View File

@@ -16,7 +16,7 @@ import {
Badge, Badge,
Icon, Icon,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaChartPie } from 'react-icons/fa'; import { PieChart } from 'lucide-react';
import { BusinessTreeItem } from '../atoms'; import { BusinessTreeItem } from '../atoms';
import type { BusinessStructure } from '../types'; import type { BusinessStructure } from '../types';
@@ -42,7 +42,7 @@ const BusinessStructureCard: React.FC<BusinessStructureCardProps> = ({
<Card bg={THEME.cardBg} shadow="md"> <Card bg={THEME.cardBg} shadow="md">
<CardHeader> <CardHeader>
<HStack> <HStack>
<Icon as={FaChartPie} color={THEME.gold} /> <Icon as={PieChart} color={THEME.gold} />
<Heading size="sm" color={THEME.textPrimary}></Heading> <Heading size="sm" color={THEME.textPrimary}></Heading>
<Badge bg={THEME.gold} color="gray.900">{businessStructure[0]?.report_period}</Badge> <Badge bg={THEME.gold} color="gray.900">{businessStructure[0]?.report_period}</Badge>
</HStack> </HStack>

View File

@@ -33,17 +33,17 @@ import {
useDisclosure, useDisclosure,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { import {
FaTrophy, Trophy,
FaCog, Settings,
FaStar, Star,
FaChartLine, TrendingUp,
FaDollarSign, DollarSign,
FaFlask, FlaskConical,
FaShieldAlt, Shield,
FaRocket, Rocket,
FaUsers, Users,
FaExternalLinkAlt, ExternalLink,
} from 'react-icons/fa'; } from 'lucide-react';
import ReactECharts from 'echarts-for-react'; import ReactECharts from 'echarts-for-react';
import { ScoreBar } from '../atoms'; import { ScoreBar } from '../atoms';
import { getRadarChartOption } from '../utils/chartOptions'; import { getRadarChartOption } from '../utils/chartOptions';
@@ -110,7 +110,7 @@ const CompetitorTags = memo<CompetitorTagsProps>(({ competitors }) => (
color="yellow.500" color="yellow.500"
borderRadius="full" borderRadius="full"
> >
<Icon as={FaUsers} mr={1} /> <Icon as={Users} mr={1} />
<TagLabel>{competitor}</TagLabel> <TagLabel>{competitor}</TagLabel>
</Tag> </Tag>
))} ))}
@@ -127,14 +127,14 @@ interface ScoreSectionProps {
const ScoreSection = memo<ScoreSectionProps>(({ scores }) => ( const ScoreSection = memo<ScoreSectionProps>(({ scores }) => (
<VStack spacing={4} align="stretch"> <VStack spacing={4} align="stretch">
<ScoreBar label="市场地位" score={scores?.market_position} icon={FaTrophy} /> <ScoreBar label="市场地位" score={scores?.market_position} icon={Trophy} />
<ScoreBar label="技术实力" score={scores?.technology} icon={FaCog} /> <ScoreBar label="技术实力" score={scores?.technology} icon={Settings} />
<ScoreBar label="品牌价值" score={scores?.brand} icon={FaStar} /> <ScoreBar label="品牌价值" score={scores?.brand} icon={Star} />
<ScoreBar label="运营效率" score={scores?.operation} icon={FaChartLine} /> <ScoreBar label="运营效率" score={scores?.operation} icon={TrendingUp} />
<ScoreBar label="财务健康" score={scores?.finance} icon={FaDollarSign} /> <ScoreBar label="财务健康" score={scores?.finance} icon={DollarSign} />
<ScoreBar label="创新能力" score={scores?.innovation} icon={FaFlask} /> <ScoreBar label="创新能力" score={scores?.innovation} icon={FlaskConical} />
<ScoreBar label="风险控制" score={scores?.risk} icon={FaShieldAlt} /> <ScoreBar label="风险控制" score={scores?.risk} icon={Shield} />
<ScoreBar label="成长潜力" score={scores?.growth} icon={FaRocket} /> <ScoreBar label="成长潜力" score={scores?.growth} icon={Rocket} />
</VStack> </VStack>
)); ));
@@ -201,7 +201,7 @@ const CompetitiveAnalysisCard: React.FC<CompetitiveAnalysisCardProps> = memo(
<Card {...CARD_STYLES}> <Card {...CARD_STYLES}>
<CardHeader> <CardHeader>
<HStack> <HStack>
<Icon as={FaTrophy} color="yellow.500" /> <Icon as={Trophy} color="yellow.500" />
<Heading size="sm" color="yellow.500"></Heading> <Heading size="sm" color="yellow.500"></Heading>
{competitivePosition.ranking && ( {competitivePosition.ranking && (
<Badge <Badge
@@ -223,7 +223,7 @@ const CompetitiveAnalysisCard: React.FC<CompetitiveAnalysisCardProps> = memo(
size="xs" size="xs"
variant="ghost" variant="ghost"
color="yellow.500" color="yellow.500"
rightIcon={<Icon as={FaExternalLinkAlt} boxSize={3} />} rightIcon={<Icon as={ExternalLink} boxSize={3} />}
onClick={onOpen} onClick={onOpen}
_hover={{ bg: 'rgba(212, 175, 55, 0.1)' }} _hover={{ bg: 'rgba(212, 175, 55, 0.1)' }}
> >
@@ -269,7 +269,7 @@ const CompetitiveAnalysisCard: React.FC<CompetitiveAnalysisCardProps> = memo(
<ModalContent {...MODAL_STYLES.content}> <ModalContent {...MODAL_STYLES.content}>
<ModalHeader {...MODAL_STYLES.header}> <ModalHeader {...MODAL_STYLES.header}>
<HStack> <HStack>
<Icon as={FaTrophy} color="yellow.500" /> <Icon as={Trophy} color="yellow.500" />
<Text></Text> <Text></Text>
</HStack> </HStack>
</ModalHeader> </ModalHeader>

View File

@@ -4,7 +4,7 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { Box, HStack, VStack, Icon, Text } from '@chakra-ui/react'; import { Box, HStack, VStack, Icon, Text } from '@chakra-ui/react';
import { FaUsers } from 'react-icons/fa'; import { Users } from 'lucide-react';
import { THEME, ICON_MAP, HIGHLIGHT_HOVER_STYLES } from '../theme'; import { THEME, ICON_MAP, HIGHLIGHT_HOVER_STYLES } from '../theme';
import type { InvestmentHighlightItem } from '../../../types'; import type { InvestmentHighlightItem } from '../../../types';
@@ -13,7 +13,7 @@ interface HighlightCardProps {
} }
export const HighlightCard = memo<HighlightCardProps>(({ highlight }) => { export const HighlightCard = memo<HighlightCardProps>(({ highlight }) => {
const IconComponent = ICON_MAP[highlight.icon] || FaUsers; const IconComponent = ICON_MAP[highlight.icon] || Users;
return ( return (
<Box <Box

View File

@@ -4,11 +4,11 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { HStack, Icon, Text } from '@chakra-ui/react'; import { HStack, Icon, Text } from '@chakra-ui/react';
import type { IconType } from 'react-icons'; import type { LucideIcon } from 'lucide-react';
import { THEME } from '../theme'; import { THEME } from '../theme';
interface SectionHeaderProps { interface SectionHeaderProps {
icon: IconType; icon: LucideIcon;
title: string; title: string;
color?: string; color?: string;
} }

View File

@@ -15,7 +15,7 @@ import {
Grid, Grid,
GridItem, GridItem,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaCrown, FaStar, FaBriefcase } from 'react-icons/fa'; import { Crown, Star, Briefcase } from 'lucide-react';
import type { import type {
QualitativeAnalysis, QualitativeAnalysis,
InvestmentHighlightItem, InvestmentHighlightItem,
@@ -57,7 +57,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
<Card {...CARD_STYLES}> <Card {...CARD_STYLES}>
<CardBody> <CardBody>
<VStack spacing={4} align="stretch"> <VStack spacing={4} align="stretch">
<SectionHeader icon={FaCrown} title="核心定位" /> <SectionHeader icon={Crown} title="核心定位" />
{corePositioning?.one_line_intro && ( {corePositioning?.one_line_intro && (
<Box <Box
p={4} p={4}
@@ -74,7 +74,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
<Grid templateColumns={GRID_COLUMNS.twoColumnMd} gap={4}> <Grid templateColumns={GRID_COLUMNS.twoColumnMd} gap={4}>
<GridItem> <GridItem>
<Box p={4} bg={THEME.light.cardBg} borderRadius="lg"> <Box p={4} bg={THEME.light.cardBg} borderRadius="lg">
<SectionHeader icon={FaStar} title="投资亮点" /> <SectionHeader icon={Star} title="投资亮点" />
<Text <Text
fontSize="sm" fontSize="sm"
color={THEME.light.subtextColor} color={THEME.light.subtextColor}
@@ -89,7 +89,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
</GridItem> </GridItem>
<GridItem> <GridItem>
<Box p={4} bg={THEME.light.cardBg} borderRadius="lg"> <Box p={4} bg={THEME.light.cardBg} borderRadius="lg">
<SectionHeader icon={FaBriefcase} title="商业模式" /> <SectionHeader icon={Briefcase} title="商业模式" />
<Text <Text
fontSize="sm" fontSize="sm"
color={THEME.light.subtextColor} color={THEME.light.subtextColor}
@@ -126,7 +126,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
<VStack spacing={0} align="stretch"> <VStack spacing={0} align="stretch">
{/* 核心定位区域(深色背景) */} {/* 核心定位区域(深色背景) */}
<Box p={6} bg={THEME.dark.bg}> <Box p={6} bg={THEME.dark.bg}>
<SectionHeader icon={FaCrown} title="核心定位" /> <SectionHeader icon={Crown} title="核心定位" />
{/* 一句话介绍 */} {/* 一句话介绍 */}
{corePositioning?.one_line_intro && ( {corePositioning?.one_line_intro && (
@@ -152,7 +152,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
borderRight={BORDER_RIGHT_RESPONSIVE} borderRight={BORDER_RIGHT_RESPONSIVE}
borderColor="whiteAlpha.100" borderColor="whiteAlpha.100"
> >
<SectionHeader icon={FaStar} title="投资亮点" /> <SectionHeader icon={Star} title="投资亮点" />
<VStack spacing={3} align="stretch"> <VStack spacing={3} align="stretch">
{highlights.length > 0 ? ( {highlights.length > 0 ? (
highlights.map((highlight, idx) => ( highlights.map((highlight, idx) => (
@@ -168,7 +168,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
{/* 商业模式区域 */} {/* 商业模式区域 */}
<GridItem p={6}> <GridItem p={6}>
<SectionHeader icon={FaBriefcase} title="商业模式" /> <SectionHeader icon={Briefcase} title="商业模式" />
<Box <Box
p={4} p={4}
bg={THEME.light.cardBg} bg={THEME.light.cardBg}

View File

@@ -3,14 +3,14 @@
*/ */
import { import {
FaUniversity, University,
FaFire, Flame,
FaUsers, Users,
FaChartLine, TrendingUp,
FaMicrochip, Cpu,
FaShieldAlt, Shield,
} from 'react-icons/fa'; type LucideIcon,
import type { IconType } from 'react-icons'; } from 'lucide-react';
// ==================== 主题常量 ==================== // ==================== 主题常量 ====================
@@ -39,13 +39,13 @@ export const THEME = {
// ==================== 图标映射 ==================== // ==================== 图标映射 ====================
export const ICON_MAP: Record<string, IconType> = { export const ICON_MAP: Record<string, LucideIcon> = {
bank: FaUniversity, bank: University,
fire: FaFire, fire: Flame,
users: FaUsers, users: Users,
'trending-up': FaChartLine, 'trending-up': TrendingUp,
cpu: FaMicrochip, cpu: Cpu,
'shield-check': FaShieldAlt, 'shield-check': Shield,
}; };
// ==================== 样式常量 ==================== // ==================== 样式常量 ====================

View File

@@ -23,7 +23,7 @@ import {
AccordionPanel, AccordionPanel,
AccordionIcon, AccordionIcon,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaBalanceScale } from 'react-icons/fa'; import { Scale } from 'lucide-react';
import { KeyFactorCard } from '../atoms'; import { KeyFactorCard } from '../atoms';
import type { KeyFactors } from '../types'; import type { KeyFactors } from '../types';
@@ -66,7 +66,7 @@ const KeyFactorsCard: React.FC<KeyFactorsCardProps> = ({ keyFactors }) => {
<Card {...CARD_STYLES} h="full"> <Card {...CARD_STYLES} h="full">
<CardHeader> <CardHeader>
<HStack> <HStack>
<Icon as={FaBalanceScale} color="yellow.500" /> <Icon as={Scale} color="yellow.500" />
<Heading size="sm" color={THEME.titleColor}> <Heading size="sm" color={THEME.titleColor}>
</Heading> </Heading>

View File

@@ -19,7 +19,7 @@ import {
GridItem, GridItem,
Center, Center,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaRocket, FaChartBar } from 'react-icons/fa'; import { Rocket, BarChart2 } from 'lucide-react';
import type { Strategy } from '../types'; import type { Strategy } from '../types';
// 样式常量 - 避免每次渲染创建新对象 // 样式常量 - 避免每次渲染创建新对象
@@ -54,7 +54,7 @@ const EmptyState = memo(() => (
<Box {...EMPTY_BOX_STYLES}> <Box {...EMPTY_BOX_STYLES}>
<Center> <Center>
<VStack spacing={3}> <VStack spacing={3}>
<Icon as={FaChartBar} boxSize={10} color="yellow.600" /> <Icon as={BarChart2} boxSize={10} color="yellow.600" />
<Text fontWeight="medium"></Text> <Text fontWeight="medium"></Text>
<Text fontSize="sm" color="gray.500"> <Text fontSize="sm" color="gray.500">
@@ -97,7 +97,7 @@ const StrategyAnalysisCard: React.FC<StrategyAnalysisCardProps> = memo(
<Card {...CARD_STYLES}> <Card {...CARD_STYLES}>
<CardHeader> <CardHeader>
<HStack> <HStack>
<Icon as={FaRocket} color="yellow.500" /> <Icon as={Rocket} color="yellow.500" />
<Heading size="sm" color="yellow.500"></Heading> <Heading size="sm" color="yellow.500"></Heading>
</HStack> </HStack>
</CardHeader> </CardHeader>

View File

@@ -16,7 +16,7 @@ import {
Box, Box,
Icon, Icon,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaHistory } from 'react-icons/fa'; import { History } from 'lucide-react';
import TimelineComponent from '../organisms/TimelineComponent'; import TimelineComponent from '../organisms/TimelineComponent';
import type { DevelopmentTimeline } from '../types'; import type { DevelopmentTimeline } from '../types';
@@ -59,7 +59,7 @@ const TimelineCard: React.FC<TimelineCardProps> = ({ developmentTimeline }) => {
<Card {...CARD_STYLES} h="full"> <Card {...CARD_STYLES} h="full">
<CardHeader> <CardHeader>
<HStack> <HStack>
<Icon as={FaHistory} color="yellow.500" /> <Icon as={History} color="yellow.500" />
<Heading size="sm" color={THEME.titleColor}> <Heading size="sm" color={THEME.titleColor}>
线 线
</Heading> </Heading>

View File

@@ -20,7 +20,7 @@ import {
Box, Box,
Flex, Flex,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaNetworkWired } from 'react-icons/fa'; import { Network } from 'lucide-react';
import ReactECharts from 'echarts-for-react'; import ReactECharts from 'echarts-for-react';
import { import {
ProcessNavigation, ProcessNavigation,
@@ -133,7 +133,7 @@ const ValueChainCard: React.FC<ValueChainCardProps> = memo(({
{/* 头部区域 */} {/* 头部区域 */}
<CardHeader py={0}> <CardHeader py={0}>
<HStack flexWrap="wrap" gap={0}> <HStack flexWrap="wrap" gap={0}>
<Icon as={FaNetworkWired} color={THEME.gold} /> <Icon as={Network} color={THEME.gold} />
<Heading size="sm" color={THEME.textPrimary}> <Heading size="sm" color={THEME.textPrimary}>
</Heading> </Heading>

View File

@@ -12,7 +12,7 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Card, CardBody } from '@chakra-ui/react'; import { Card, CardBody } from '@chakra-ui/react';
import { FaBrain, FaBuilding, FaLink, FaHistory } from 'react-icons/fa'; import { Brain, Building2, Link2, History } from 'lucide-react';
import SubTabContainer, { type SubTabConfig } from '@components/SubTabContainer'; import SubTabContainer, { type SubTabConfig } from '@components/SubTabContainer';
import LoadingState from '../../LoadingState'; import LoadingState from '../../LoadingState';
import { StrategyTab, BusinessTab, ValueChainTab, DevelopmentTab } from './tabs'; import { StrategyTab, BusinessTab, ValueChainTab, DevelopmentTab } from './tabs';
@@ -28,10 +28,10 @@ const THEME = {
* Tab 配置 * Tab 配置
*/ */
const DEEP_ANALYSIS_TABS: SubTabConfig[] = [ const DEEP_ANALYSIS_TABS: SubTabConfig[] = [
{ key: 'strategy', name: '战略分析', icon: FaBrain, component: StrategyTab }, { key: 'strategy', name: '战略分析', icon: Brain, component: StrategyTab },
{ key: 'business', name: '业务结构', icon: FaBuilding, component: BusinessTab }, { key: 'business', name: '业务结构', icon: Building2, component: BusinessTab },
{ key: 'valueChain', name: '产业链', icon: FaLink, component: ValueChainTab }, { key: 'valueChain', name: '产业链', icon: Link2, component: ValueChainTab },
{ key: 'development', name: '发展历程', icon: FaHistory, component: DevelopmentTab }, { key: 'development', name: '发展历程', icon: History, component: DevelopmentTab },
]; ];
/** /**

View File

@@ -22,7 +22,7 @@ import {
Icon, Icon,
Button, Button,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaCheckCircle, FaExclamationCircle } from 'react-icons/fa'; import { CheckCircle, AlertCircle } from 'lucide-react';
import type { TimelineEvent } from '../../types'; import type { TimelineEvent } from '../../types';
interface EventDetailModalProps { interface EventDetailModalProps {
@@ -48,7 +48,7 @@ const EventDetailModal: React.FC<EventDetailModalProps> = ({
<ModalHeader> <ModalHeader>
<HStack> <HStack>
<Icon <Icon
as={isPositive ? FaCheckCircle : FaExclamationCircle} as={isPositive ? CheckCircle : AlertCircle}
color={isPositive ? 'red.500' : 'green.500'} color={isPositive ? 'red.500' : 'green.500'}
boxSize={6} boxSize={6}
/> />

View File

@@ -20,10 +20,10 @@ import {
useDisclosure, useDisclosure,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { import {
FaCalendarAlt, Calendar,
FaArrowUp, ArrowUp,
FaArrowDown, ArrowDown,
} from 'react-icons/fa'; } from 'lucide-react';
import EventDetailModal from './EventDetailModal'; import EventDetailModal from './EventDetailModal';
import type { TimelineComponentProps, TimelineEvent } from '../../types'; import type { TimelineComponentProps, TimelineEvent } from '../../types';
@@ -74,7 +74,7 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ events }) => {
shadow="md" shadow="md"
> >
<Icon <Icon
as={isPositive ? FaArrowUp : FaArrowDown} as={isPositive ? ArrowUp : ArrowDown}
color="white" color="white"
boxSize={3} boxSize={3}
/> />
@@ -108,7 +108,7 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ events }) => {
</Text> </Text>
<HStack spacing={2}> <HStack spacing={2}>
<Icon <Icon
as={FaCalendarAlt} as={Calendar}
boxSize={3} boxSize={3}
color="gray.500" color="gray.500"
/> />

View File

@@ -34,19 +34,19 @@ import {
Tooltip, Tooltip,
Button, Button,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ExternalLinkIcon } from '@chakra-ui/icons';
import { import {
FaBuilding, ExternalLink,
FaHandshake, Building,
FaUserTie, Handshake,
FaIndustry, UserCircle,
FaCog, Factory,
FaNetworkWired, Settings,
FaFlask, Network,
FaStar, FlaskConical,
FaArrowRight, Star,
FaArrowLeft, ArrowRight,
} from 'react-icons/fa'; ArrowLeft,
} from 'lucide-react';
import type { ValueChainNode, RelatedCompany } from '../../types'; import type { ValueChainNode, RelatedCompany } from '../../types';
interface RelatedCompaniesModalProps { interface RelatedCompaniesModalProps {
@@ -64,15 +64,15 @@ interface RelatedCompaniesModalProps {
*/ */
const getNodeTypeIcon = (type: string) => { const getNodeTypeIcon = (type: string) => {
const icons: Record<string, React.ComponentType> = { const icons: Record<string, React.ComponentType> = {
company: FaBuilding, company: Building,
supplier: FaHandshake, supplier: Handshake,
customer: FaUserTie, customer: UserCircle,
product: FaIndustry, product: Factory,
service: FaCog, service: Settings,
channel: FaNetworkWired, channel: Network,
raw_material: FaFlask, raw_material: FlaskConical,
}; };
return icons[type] || FaBuilding; return icons[type] || Building;
}; };
/** /**
@@ -242,7 +242,7 @@ const RelatedCompaniesModal: React.FC<RelatedCompaniesModalProps> = ({
</VStack> </VStack>
<IconButton <IconButton
size="sm" size="sm"
icon={<ExternalLinkIcon />} icon={<ExternalLink size={16} />}
variant="ghost" variant="ghost"
colorScheme="blue" colorScheme="blue"
onClick={() => { onClick={() => {
@@ -287,8 +287,8 @@ const RelatedCompaniesModal: React.FC<RelatedCompaniesModalProps> = ({
<Icon <Icon
as={ as={
rel.role === 'source' rel.role === 'source'
? FaArrowRight ? ArrowRight
: FaArrowLeft : ArrowLeft
} }
color={ color={
rel.role === 'source' rel.role === 'source'
@@ -323,7 +323,7 @@ const RelatedCompaniesModal: React.FC<RelatedCompaniesModalProps> = ({
) : ( ) : (
<Center py={4}> <Center py={4}>
<VStack spacing={2}> <VStack spacing={2}>
<Icon as={FaBuilding} boxSize={8} color="gray.300" /> <Icon as={Building} boxSize={8} color="gray.300" />
<Text fontSize="sm" color="gray.500"> <Text fontSize="sm" color="gray.500">
</Text> </Text>

View File

@@ -22,15 +22,15 @@ import {
ScaleFade, ScaleFade,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { import {
FaBuilding, Building,
FaHandshake, Handshake,
FaUserTie, UserCircle,
FaIndustry, Factory,
FaCog, Settings,
FaNetworkWired, Network,
FaFlask, FlaskConical,
FaStar, Star,
} from 'react-icons/fa'; } from 'lucide-react';
import { logger } from '@utils/logger'; import { logger } from '@utils/logger';
import axios from '@utils/axiosConfig'; import axios from '@utils/axiosConfig';
import RelatedCompaniesModal from './RelatedCompaniesModal'; import RelatedCompaniesModal from './RelatedCompaniesModal';
@@ -71,17 +71,17 @@ const THEME = {
*/ */
const getNodeTypeIcon = (type: string) => { const getNodeTypeIcon = (type: string) => {
const icons: Record<string, React.ComponentType> = { const icons: Record<string, React.ComponentType> = {
company: FaBuilding, company: Building,
supplier: FaHandshake, supplier: Handshake,
customer: FaUserTie, customer: UserCircle,
product: FaIndustry, product: Factory,
service: FaCog, service: Settings,
channel: FaNetworkWired, channel: Network,
raw_material: FaFlask, raw_material: FlaskConical,
regulator: FaBuilding, regulator: Building,
end_user: FaUserTie, end_user: UserCircle,
}; };
return icons[type] || FaBuilding; return icons[type] || Building;
}; };
/** /**
@@ -195,7 +195,7 @@ const ValueChainNodeCard: React.FC<ValueChainNodeCardProps> = memo(({
node.importance_score >= 70 && ( node.importance_score >= 70 && (
<Tooltip label="重要节点"> <Tooltip label="重要节点">
<span> <span>
<Icon as={FaStar} color={THEME.gold} boxSize={4} /> <Icon as={Star} color={THEME.gold} boxSize={4} />
</span> </span>
</Tooltip> </Tooltip>
)} )}

View File

@@ -17,7 +17,7 @@ import {
StatNumber, StatNumber,
StatHelpText, StatHelpText,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { FaCrown } from "react-icons/fa"; import { Crown } from "lucide-react";
import type { ActualControl } from "../../types"; import type { ActualControl } from "../../types";
import { THEME } from "../../BasicInfoTab/config"; import { THEME } from "../../BasicInfoTab/config";
@@ -58,7 +58,7 @@ const ActualControlCard: React.FC<ActualControlCardProps> = ({ actualControl = [
return ( return (
<Box> <Box>
<HStack mb={4}> <HStack mb={4}>
<Icon as={FaCrown} color={THEME.gold} boxSize={5} /> <Icon as={Crown} color={THEME.gold} boxSize={5} />
<Heading size="sm" color={THEME.gold}></Heading> <Heading size="sm" color={THEME.gold}></Heading>
</HStack> </HStack>
<Card bg={THEME.cardBg} borderColor={THEME.border} borderWidth="1px"> <Card bg={THEME.cardBg} borderColor={THEME.border} borderWidth="1px">

View File

@@ -15,7 +15,7 @@ import {
CardHeader, CardHeader,
SimpleGrid, SimpleGrid,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { FaChartPie, FaArrowUp, FaArrowDown } from "react-icons/fa"; import { PieChart, ArrowUp, ArrowDown } from "lucide-react";
import { echarts, type ECharts, type EChartsOption } from '@lib/echarts'; import { echarts, type ECharts, type EChartsOption } from '@lib/echarts';
import type { Concentration } from "../../types"; import type { Concentration } from "../../types";
import { THEME } from "../../BasicInfoTab/config"; import { THEME } from "../../BasicInfoTab/config";
@@ -182,7 +182,7 @@ const ConcentrationCard: React.FC<ConcentrationCardProps> = ({ concentration = [
return ( return (
<Box> <Box>
<HStack mb={4}> <HStack mb={4}>
<Icon as={FaChartPie} color={THEME.gold} boxSize={5} /> <Icon as={PieChart} color={THEME.gold} boxSize={5} />
<Heading size="sm" color={THEME.gold}></Heading> <Heading size="sm" color={THEME.gold}></Heading>
</HStack> </HStack>
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={4}> <SimpleGrid columns={{ base: 1, md: 2 }} spacing={4}>
@@ -208,7 +208,7 @@ const ConcentrationCard: React.FC<ConcentrationCardProps> = ({ concentration = [
colorScheme={item.ratio_change > 0 ? "red" : "green"} colorScheme={item.ratio_change > 0 ? "red" : "green"}
> >
<Icon <Icon
as={item.ratio_change > 0 ? FaArrowUp : FaArrowDown} as={item.ratio_change > 0 ? ArrowUp : ArrowDown}
mr={1} mr={1}
boxSize={3} boxSize={3}
/> />

View File

@@ -5,7 +5,7 @@ import React, { useMemo, memo } from "react";
import { Box, HStack, Heading, Badge, Icon, useBreakpointValue } from "@chakra-ui/react"; import { Box, HStack, Heading, Badge, Icon, useBreakpointValue } from "@chakra-ui/react";
import { Table, Tag, Tooltip, ConfigProvider } from "antd"; import { Table, Tag, Tooltip, ConfigProvider } from "antd";
import type { ColumnsType } from "antd/es/table"; import type { ColumnsType } from "antd/es/table";
import { FaUsers, FaChartLine } from "react-icons/fa"; import { Users, LineChart } from "lucide-react";
import type { Shareholder } from "../../types"; import type { Shareholder } from "../../types";
import { THEME } from "../../BasicInfoTab/config"; import { THEME } from "../../BasicInfoTab/config";
@@ -96,7 +96,7 @@ const ShareholdersTable: React.FC<ShareholdersTableProps> = ({
if (type === "circulation") { if (type === "circulation") {
return { return {
title: title || "十大流通股东", title: title || "十大流通股东",
icon: FaChartLine, icon: LineChart,
iconColor: "purple.500", iconColor: "purple.500",
ratioField: "circulation_share_ratio" as keyof Shareholder, ratioField: "circulation_share_ratio" as keyof Shareholder,
ratioLabel: "流通股比例", ratioLabel: "流通股比例",
@@ -106,7 +106,7 @@ const ShareholdersTable: React.FC<ShareholdersTableProps> = ({
} }
return { return {
title: title || "十大股东", title: title || "十大股东",
icon: FaUsers, icon: Users,
iconColor: "green.500", iconColor: "green.500",
ratioField: "total_share_ratio" as keyof Shareholder, ratioField: "total_share_ratio" as keyof Shareholder,
ratioLabel: "持股比例", ratioLabel: "持股比例",

View File

@@ -3,7 +3,7 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { Center, VStack, Icon, Text } from '@chakra-ui/react'; import { Center, VStack, Icon, Text } from '@chakra-ui/react';
import { FaNewspaper } from 'react-icons/fa'; import { Newspaper } from 'lucide-react';
import type { NewsEmptyStateProps } from '../types'; import type { NewsEmptyStateProps } from '../types';
const NewsEmptyState: React.FC<NewsEmptyStateProps> = ({ const NewsEmptyState: React.FC<NewsEmptyStateProps> = ({
@@ -15,7 +15,7 @@ const NewsEmptyState: React.FC<NewsEmptyStateProps> = ({
<Center h="400px"> <Center h="400px">
<VStack spacing={3}> <VStack spacing={3}>
<Icon <Icon
as={FaNewspaper} as={Newspaper}
boxSize={16} boxSize={16}
color={isBlackGold ? theme.gold : 'gray.300'} color={isBlackGold ? theme.gold : 'gray.300'}
opacity={0.5} opacity={0.5}

View File

@@ -13,7 +13,7 @@ import {
CardBody, CardBody,
Tag, Tag,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaEye, FaFire, FaChartLine } from 'react-icons/fa'; import { Eye, Flame, TrendingUp } from 'lucide-react';
import type { NewsEventCardProps } from '../types'; import type { NewsEventCardProps } from '../types';
import { import {
getEventTypeIcon, getEventTypeIcon,
@@ -117,7 +117,7 @@ const NewsEventCard: React.FC<NewsEventCardProps> = ({
<HStack spacing={3}> <HStack spacing={3}>
{event.view_count !== undefined && ( {event.view_count !== undefined && (
<HStack spacing={1}> <HStack spacing={1}>
<Icon as={FaEye} boxSize={3} color={theme.textMuted} /> <Icon as={Eye} boxSize={3} color={theme.textMuted} />
<Text fontSize="xs" color={theme.textMuted}> <Text fontSize="xs" color={theme.textMuted}>
{event.view_count} {event.view_count}
</Text> </Text>
@@ -125,7 +125,7 @@ const NewsEventCard: React.FC<NewsEventCardProps> = ({
)} )}
{event.hot_score !== undefined && ( {event.hot_score !== undefined && (
<HStack spacing={1}> <HStack spacing={1}>
<Icon as={FaFire} boxSize={3} color={theme.goldLight} /> <Icon as={Flame} boxSize={3} color={theme.goldLight} />
<Text fontSize="xs" color={theme.textMuted}> <Text fontSize="xs" color={theme.textMuted}>
{event.hot_score.toFixed(1)} {event.hot_score.toFixed(1)}
</Text> </Text>
@@ -152,7 +152,7 @@ const NewsEventCard: React.FC<NewsEventCardProps> = ({
<Box pt={2} borderTop="1px" borderColor={theme.cardBorder}> <Box pt={2} borderTop="1px" borderColor={theme.cardBorder}>
<HStack spacing={6} flexWrap="wrap"> <HStack spacing={6} flexWrap="wrap">
<HStack spacing={1}> <HStack spacing={1}>
<Icon as={FaChartLine} boxSize={3} color={theme.textMuted} /> <Icon as={TrendingUp} boxSize={3} color={theme.textMuted} />
<Text fontSize="xs" color={theme.textMuted} fontWeight="medium"> <Text fontSize="xs" color={theme.textMuted} fontWeight="medium">
: :
</Text> </Text>

View File

@@ -3,7 +3,7 @@
import React, { memo, useMemo } from 'react'; import React, { memo, useMemo } from 'react';
import { Box, HStack, Text, Button, Icon } from '@chakra-ui/react'; import { Box, HStack, Text, Button, Icon } from '@chakra-ui/react';
import { FaChevronLeft, FaChevronRight } from 'react-icons/fa'; import { ChevronLeft, ChevronRight } from 'lucide-react';
import type { NewsPaginationProps } from '../types'; import type { NewsPaginationProps } from '../types';
const NewsPagination: React.FC<NewsPaginationProps> = ({ const NewsPagination: React.FC<NewsPaginationProps> = ({
@@ -87,7 +87,7 @@ const NewsPagination: React.FC<NewsPaginationProps> = ({
_hover={{ bg: theme.cardHoverBg, borderColor: theme.gold }} _hover={{ bg: theme.cardHoverBg, borderColor: theme.gold }}
onClick={() => onPageChange(1)} onClick={() => onPageChange(1)}
isDisabled={!has_prev || isLoading} isDisabled={!has_prev || isLoading}
leftIcon={<Icon as={FaChevronLeft} />} leftIcon={<Icon as={ChevronLeft} />}
> >
</Button> </Button>
@@ -128,7 +128,7 @@ const NewsPagination: React.FC<NewsPaginationProps> = ({
_hover={{ bg: theme.cardHoverBg, borderColor: theme.gold }} _hover={{ bg: theme.cardHoverBg, borderColor: theme.gold }}
onClick={() => onPageChange(totalPages)} onClick={() => onPageChange(totalPages)}
isDisabled={!has_next || isLoading} isDisabled={!has_next || isLoading}
rightIcon={<Icon as={FaChevronRight} />} rightIcon={<Icon as={ChevronRight} />}
> >
</Button> </Button>

View File

@@ -3,8 +3,7 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { HStack, Input, InputGroup, InputLeftElement, Button, Text, Icon } from '@chakra-ui/react'; import { HStack, Input, InputGroup, InputLeftElement, Button, Text, Icon } from '@chakra-ui/react';
import { SearchIcon } from '@chakra-ui/icons'; import { Search, Newspaper } from 'lucide-react';
import { FaNewspaper } from 'react-icons/fa';
import type { NewsSearchBarProps } from '../types'; import type { NewsSearchBarProps } from '../types';
const NewsSearchBar: React.FC<NewsSearchBarProps> = ({ const NewsSearchBar: React.FC<NewsSearchBarProps> = ({
@@ -31,7 +30,7 @@ const NewsSearchBar: React.FC<NewsSearchBarProps> = ({
<HStack flex={1} minW="300px"> <HStack flex={1} minW="300px">
<InputGroup> <InputGroup>
<InputLeftElement pointerEvents="none"> <InputLeftElement pointerEvents="none">
<SearchIcon color={theme.textMuted} /> <Search size={16} color={theme.textMuted} />
</InputLeftElement> </InputLeftElement>
<Input <Input
placeholder="搜索相关新闻..." placeholder="搜索相关新闻..."
@@ -60,7 +59,7 @@ const NewsSearchBar: React.FC<NewsSearchBarProps> = ({
{total > 0 && ( {total > 0 && (
<HStack spacing={2}> <HStack spacing={2}>
<Icon as={FaNewspaper} color={theme.gold} /> <Icon as={Newspaper} color={theme.gold} />
<Text fontSize="sm" color={theme.textSecondary}> <Text fontSize="sm" color={theme.textSecondary}>
{' '} {' '}
<Text as="span" fontWeight="bold" color={theme.gold}> <Text as="span" fontWeight="bold" color={theme.gold}>

View File

@@ -1,7 +1,7 @@
// src/views/Company/components/DynamicTracking/NewsEventsTab/types.ts // src/views/Company/components/DynamicTracking/NewsEventsTab/types.ts
// 新闻动态 - 类型定义 // 新闻动态 - 类型定义
import type { IconType } from 'react-icons'; import type { LucideIcon } from 'lucide-react';
/** /**
* 徽章样式配置 * 徽章样式配置

View File

@@ -1,38 +1,38 @@
// src/views/Company/components/DynamicTracking/NewsEventsTab/utils.ts // src/views/Company/components/DynamicTracking/NewsEventsTab/utils.ts
// 新闻动态 - 工具函数 // 新闻动态 - 工具函数
import type { IconType } from 'react-icons'; import type { LucideIcon } from 'lucide-react';
import { import {
FaNewspaper, Newspaper,
FaBullhorn, Megaphone,
FaGavel, Gavel,
FaFlask, FlaskConical,
FaDollarSign, DollarSign,
FaShieldAlt, Shield,
FaFileAlt, FileText,
FaIndustry, Factory,
} from 'react-icons/fa'; } from 'lucide-react';
import type { ThemeConfig, BadgeStyle } from './types'; import type { ThemeConfig, BadgeStyle } from './types';
/** /**
* 事件类型图标映射 * 事件类型图标映射
*/ */
const EVENT_TYPE_ICONS: Record<string, IconType> = { const EVENT_TYPE_ICONS: Record<string, LucideIcon> = {
企业公告: FaBullhorn, 企业公告: Megaphone,
政策: FaGavel, 政策: Gavel,
技术突破: FaFlask, 技术突破: FlaskConical,
企业融资: FaDollarSign, 企业融资: DollarSign,
政策监管: FaShieldAlt, 政策监管: Shield,
政策动态: FaFileAlt, 政策动态: FileText,
行业事件: FaIndustry, 行业事件: Factory,
}; };
/** /**
* 获取事件类型对应的图标 * 获取事件类型对应的图标
*/ */
export const getEventTypeIcon = (eventType?: string): IconType => { export const getEventTypeIcon = (eventType?: string): LucideIcon => {
if (!eventType) return FaNewspaper; if (!eventType) return Newspaper;
return EVENT_TYPE_ICONS[eventType] || FaNewspaper; return EVENT_TYPE_ICONS[eventType] || Newspaper;
}; };
/** /**

View File

@@ -17,7 +17,7 @@ import {
Card, Card,
CardBody, CardBody,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaNewspaper, FaBullhorn, FaCalendarAlt, FaChartBar } from 'react-icons/fa'; import { Newspaper, Megaphone, Calendar, BarChart2 } from 'lucide-react';
// 深空 FUI 主题配置(与 SubTabContainer 保持一致) // 深空 FUI 主题配置(与 SubTabContainer 保持一致)
const DEEP_SPACE = { const DEEP_SPACE = {
@@ -35,10 +35,10 @@ const DEEP_SPACE = {
// 导航配置(与主组件保持同步) // 导航配置(与主组件保持同步)
const TRACKING_TABS = [ const TRACKING_TABS = [
{ key: 'news', name: '新闻动态', icon: FaNewspaper }, { key: 'news', name: '新闻动态', icon: Newspaper },
{ key: 'announcements', name: '公司公告', icon: FaBullhorn }, { key: 'announcements', name: '公司公告', icon: Megaphone },
{ key: 'disclosure', name: '财报披露日程', icon: FaCalendarAlt }, { key: 'disclosure', name: '财报披露日程', icon: Calendar },
{ key: 'forecast', name: '业绩预告', icon: FaChartBar }, { key: 'forecast', name: '业绩预告', icon: BarChart2 },
]; ];
/** /**

View File

@@ -4,7 +4,7 @@
import React, { useState, useEffect, useMemo, useCallback, memo, lazy } from 'react'; import React, { useState, useEffect, useMemo, useCallback, memo, lazy } from 'react';
import { Card, CardBody } from '@chakra-ui/react'; import { Card, CardBody } from '@chakra-ui/react';
import { FaNewspaper, FaBullhorn, FaCalendarAlt, FaChartBar } from 'react-icons/fa'; import { Newspaper, Megaphone, Calendar, BarChart2 } from 'lucide-react';
import SubTabContainer from '@components/SubTabContainer'; import SubTabContainer from '@components/SubTabContainer';
import { import {
@@ -29,28 +29,28 @@ const TRACKING_TABS = [
{ {
key: 'news', key: 'news',
name: '新闻动态', name: '新闻动态',
icon: FaNewspaper, icon: Newspaper,
component: NewsPanel, component: NewsPanel,
fallback: <NewsPanelSkeleton />, fallback: <NewsPanelSkeleton />,
}, },
{ {
key: 'announcements', key: 'announcements',
name: '公司公告', name: '公司公告',
icon: FaBullhorn, icon: Megaphone,
component: AnnouncementsPanel, component: AnnouncementsPanel,
fallback: <AnnouncementsSkeleton />, fallback: <AnnouncementsSkeleton />,
}, },
{ {
key: 'disclosure', key: 'disclosure',
name: '财报披露日程', name: '财报披露日程',
icon: FaCalendarAlt, icon: Calendar,
component: DisclosureSchedulePanel, component: DisclosureSchedulePanel,
fallback: <DisclosureScheduleSkeleton />, fallback: <DisclosureScheduleSkeleton />,
}, },
{ {
key: 'forecast', key: 'forecast',
name: '业绩预告', name: '业绩预告',
icon: FaChartBar, icon: BarChart2,
component: ForecastPanel, component: ForecastPanel,
fallback: <ForecastPanelSkeleton />, fallback: <ForecastPanelSkeleton />,
}, },

View File

@@ -23,7 +23,7 @@ import {
Grid, Grid,
GridItem, GridItem,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ArrowUpIcon, ArrowDownIcon } from '@chakra-ui/icons'; import { ArrowUp, ArrowDown } from 'lucide-react';
import { useToast } from '@chakra-ui/react'; import { useToast } from '@chakra-ui/react';
import ReactECharts from 'echarts-for-react'; import ReactECharts from 'echarts-for-react';
import { logger } from '@utils/logger'; import { logger } from '@utils/logger';
@@ -166,8 +166,8 @@ export const StockComparison: React.FC<StockComparisonProps> = ({
<Td isNumeric color={diffColor}> <Td isNumeric color={diffColor}>
{diff !== null ? ( {diff !== null ? (
<HStack spacing={1} justify="flex-end"> <HStack spacing={1} justify="flex-end">
{diff > 0 && <ArrowUpIcon boxSize={3} />} {diff > 0 && <ArrowUp size={12} />}
{diff < 0 && <ArrowDownIcon boxSize={3} />} {diff < 0 && <ArrowDown size={12} />}
<Text> <Text>
{metric.format === 'percent' {metric.format === 'percent'
? `${Math.abs(diff).toFixed(2)}pp` ? `${Math.abs(diff).toFixed(2)}pp`

View File

@@ -16,7 +16,6 @@ import {
Text, Text,
Icon, Icon,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ExternalLinkIcon } from '@chakra-ui/icons';
import { FileText, TrendingUp, Building2, Newspaper, BookOpen } from 'lucide-react'; import { FileText, TrendingUp, Building2, Newspaper, BookOpen } from 'lucide-react';
import MarkdownRenderer from './MarkdownRenderer'; import MarkdownRenderer from './MarkdownRenderer';
import { formatNumber } from '../utils/formatUtils'; import { formatNumber } from '../utils/formatUtils';

View File

@@ -28,8 +28,7 @@ import {
Flex, Flex,
useDisclosure, useDisclosure,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { SearchIcon, CloseIcon, AddIcon } from '@chakra-ui/icons'; import { Database, TrendingUp, Search, X, Plus } from 'lucide-react';
import { Database, TrendingUp } from 'lucide-react';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import { searchMetrics, fetchMetricData, type MetricSearchResult } from '@services/categoryService'; import { searchMetrics, fetchMetricData, type MetricSearchResult } from '@services/categoryService';
@@ -233,7 +232,7 @@ const MetricOverlaySearch: React.FC<MetricOverlaySearchProps> = ({
{/* Search input */} {/* Search input */}
<InputGroup size="sm" mb={3}> <InputGroup size="sm" mb={3}>
<InputLeftElement pointerEvents="none"> <InputLeftElement pointerEvents="none">
<SearchIcon color={darkGoldTheme.textMuted} /> <Search size={16} color={darkGoldTheme.textMuted} />
</InputLeftElement> </InputLeftElement>
<Input <Input
ref={inputRef} ref={inputRef}
@@ -255,7 +254,7 @@ const MetricOverlaySearch: React.FC<MetricOverlaySearchProps> = ({
<IconButton <IconButton
size="xs" size="xs"
variant="ghost" variant="ghost"
icon={<CloseIcon w="8px" h="8px" />} icon={<X size={12} />}
onClick={() => { onClick={() => {
setSearchQuery(''); setSearchQuery('');
setSearchResults([]); setSearchResults([]);
@@ -318,7 +317,7 @@ const MetricOverlaySearch: React.FC<MetricOverlaySearchProps> = ({
{isAdded ? ( {isAdded ? (
<Badge colorScheme="green" fontSize="10px">Added</Badge> <Badge colorScheme="green" fontSize="10px">Added</Badge>
) : ( ) : (
<AddIcon boxSize={3} color={darkGoldTheme.textMuted} /> <Plus size={12} color={darkGoldTheme.textMuted} />
)} )}
</Flex> </Flex>
</ListItem> </ListItem>

View File

@@ -3,7 +3,7 @@
import React, { memo, useMemo } from 'react'; import React, { memo, useMemo } from 'react';
import { Box, Text, VStack, Center, Icon } from '@chakra-ui/react'; import { Box, Text, VStack, Center, Icon } from '@chakra-ui/react';
import { InfoIcon } from '@chakra-ui/icons'; import { Info } from 'lucide-react';
import ReactECharts from 'echarts-for-react'; import ReactECharts from 'echarts-for-react';
import { darkGoldTheme } from '../../../../constants'; import { darkGoldTheme } from '../../../../constants';
@@ -32,7 +32,7 @@ export interface DailyKLineChartProps {
const EmptyState: React.FC<{ title: string; description: string }> = ({ title, description }) => ( const EmptyState: React.FC<{ title: string; description: string }> = ({ title, description }) => (
<Center h="300px"> <Center h="300px">
<VStack spacing={4}> <VStack spacing={4}>
<Icon as={InfoIcon} color={darkGoldTheme.textMuted} boxSize={12} /> <Icon as={Info} color={darkGoldTheme.textMuted} boxSize={12} />
<VStack spacing={2}> <VStack spacing={2}>
<Text color={darkGoldTheme.textMuted} fontSize="lg">{title}</Text> <Text color={darkGoldTheme.textMuted} fontSize="lg">{title}</Text>
<Text color={darkGoldTheme.textMuted} fontSize="sm" textAlign="center">{description}</Text> <Text color={darkGoldTheme.textMuted} fontSize="sm" textAlign="center">{description}</Text>

View File

@@ -18,8 +18,7 @@ import {
MenuItem, MenuItem,
Tooltip, Tooltip,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { RepeatIcon, ChevronDownIcon, ViewIcon, ViewOffIcon } from '@chakra-ui/icons'; import { BarChart2, TrendingUp, Calendar, LineChart, Activity, Pencil, RefreshCw, ChevronDown, Eye, EyeOff } from 'lucide-react';
import { BarChart2, TrendingUp, Calendar, LineChart, Activity, Pencil } from 'lucide-react';
import { darkGoldTheme, PERIOD_OPTIONS } from '../../../../constants'; import { darkGoldTheme, PERIOD_OPTIONS } from '../../../../constants';
import type { IndicatorType, MainIndicatorType, DrawingType } from '../../../../utils/chartOptions'; import type { IndicatorType, MainIndicatorType, DrawingType } from '../../../../utils/chartOptions';
@@ -155,7 +154,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
leftIcon={showAnalysis ? <ViewOffIcon /> : <ViewIcon />} leftIcon={showAnalysis ? <EyeOff size={14} /> : <Eye size={14} />}
onClick={onToggleAnalysis} onClick={onToggleAnalysis}
{...(showAnalysis ? INACTIVE_BUTTON_STYLE : ACTIVE_BUTTON_STYLE)} {...(showAnalysis ? INACTIVE_BUTTON_STYLE : ACTIVE_BUTTON_STYLE)}
minW="90px" minW="90px"
@@ -171,7 +170,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
as={Button} as={Button}
size="sm" size="sm"
variant="outline" variant="outline"
rightIcon={<ChevronDownIcon />} rightIcon={<ChevronDown size={14} />}
{...INACTIVE_BUTTON_STYLE} {...INACTIVE_BUTTON_STYLE}
minW="90px" minW="90px"
> >
@@ -205,7 +204,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
as={Button} as={Button}
size="sm" size="sm"
variant="outline" variant="outline"
rightIcon={<ChevronDownIcon />} rightIcon={<ChevronDown size={14} />}
leftIcon={<Activity size={14} />} leftIcon={<Activity size={14} />}
{...INACTIVE_BUTTON_STYLE} {...INACTIVE_BUTTON_STYLE}
minW="100px" minW="100px"
@@ -240,7 +239,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
as={Button} as={Button}
size="sm" size="sm"
variant="outline" variant="outline"
rightIcon={<ChevronDownIcon />} rightIcon={<ChevronDown size={14} />}
leftIcon={<Pencil size={14} />} leftIcon={<Pencil size={14} />}
{...(drawingType !== 'NONE' ? ACTIVE_BUTTON_STYLE : INACTIVE_BUTTON_STYLE)} {...(drawingType !== 'NONE' ? ACTIVE_BUTTON_STYLE : INACTIVE_BUTTON_STYLE)}
minW="90px" minW="90px"
@@ -296,7 +295,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
{/* 刷新按钮 */} {/* 刷新按钮 */}
<Button <Button
leftIcon={<RepeatIcon />} leftIcon={<RefreshCw size={14} />}
size="sm" size="sm"
variant="outline" variant="outline"
onClick={onRefreshMinuteData} onClick={onRefreshMinuteData}

View File

@@ -14,7 +14,7 @@ import {
GridItem, GridItem,
Icon, Icon,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { InfoIcon } from '@chakra-ui/icons'; import { Info } from 'lucide-react';
import ReactECharts from 'echarts-for-react'; import ReactECharts from 'echarts-for-react';
// 导入实时行情 Hook 和五档盘口组件 // 导入实时行情 Hook 和五档盘口组件
@@ -38,7 +38,7 @@ export interface MinuteChartWithOrderBookProps {
const EmptyState: React.FC<{ title: string; description: string }> = ({ title, description }) => ( const EmptyState: React.FC<{ title: string; description: string }> = ({ title, description }) => (
<Center h="300px"> <Center h="300px">
<VStack spacing={4}> <VStack spacing={4}>
<Icon as={InfoIcon} color={darkGoldTheme.textMuted} boxSize={12} /> <Icon as={Info} color={darkGoldTheme.textMuted} boxSize={12} />
<VStack spacing={2}> <VStack spacing={2}>
<Text color={darkGoldTheme.textMuted} fontSize="lg">{title}</Text> <Text color={darkGoldTheme.textMuted} fontSize="lg">{title}</Text>
<Text color={darkGoldTheme.textMuted} fontSize="sm" textAlign="center">{description}</Text> <Text color={darkGoldTheme.textMuted} fontSize="sm" textAlign="center">{description}</Text>

View File

@@ -16,8 +16,7 @@ import {
VStack, VStack,
Spinner, Spinner,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { SearchIcon } from '@chakra-ui/icons'; import { BarChart2, Search } from 'lucide-react';
import { BarChart2 } from 'lucide-react';
import { useStockSearch, type Stock } from '../../../hooks/useStockSearch'; import { useStockSearch, type Stock } from '../../../hooks/useStockSearch';
interface CompareStockInputProps { interface CompareStockInputProps {
@@ -106,7 +105,7 @@ const CompareStockInput: React.FC<CompareStockInputProps> = ({
<HStack spacing={2}> <HStack spacing={2}>
<InputGroup size="sm" w="160px"> <InputGroup size="sm" w="160px">
<InputLeftElement pointerEvents="none"> <InputLeftElement pointerEvents="none">
<SearchIcon color={textColor} boxSize={3} /> <Search size={12} color={textColor} />
</InputLeftElement> </InputLeftElement>
<Input <Input
placeholder="对比股票" placeholder="对比股票"

View File

@@ -30,7 +30,7 @@ import {
Spinner, Spinner,
Center, Center,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ArrowUpIcon, ArrowDownIcon } from '@chakra-ui/icons'; import { ArrowUp, ArrowDown } from 'lucide-react';
import ReactECharts from 'echarts-for-react'; import ReactECharts from 'echarts-for-react';
import { COMPARE_METRICS } from '../../FinancialPanorama/constants'; import { COMPARE_METRICS } from '../../FinancialPanorama/constants';
@@ -149,8 +149,8 @@ const StockCompareModal: React.FC<StockCompareModalProps> = ({
<Td isNumeric color={diffColor} fontSize="sm"> <Td isNumeric color={diffColor} fontSize="sm">
{diff !== null ? ( {diff !== null ? (
<HStack spacing={1} justify="flex-end"> <HStack spacing={1} justify="flex-end">
{diff > 0 && <ArrowUpIcon boxSize={3} />} {diff > 0 && <ArrowUp size={12} />}
{diff < 0 && <ArrowDownIcon boxSize={3} />} {diff < 0 && <ArrowDown size={12} />}
<Text> <Text>
{metric.format === 'percent' {metric.format === 'percent'
? `${Math.abs(diff).toFixed(2)}pp` ? `${Math.abs(diff).toFixed(2)}pp`

View File

@@ -1,19 +1,19 @@
// src/views/Company/constants/index.js // src/views/Company/constants/index.js
// 公司详情页面常量配置 // 公司详情页面常量配置
import { FaChartLine, FaMoneyBillWave, FaChartBar, FaInfoCircle, FaBrain, FaNewspaper } from 'react-icons/fa'; import { LineChart, Banknote, BarChart2, Info, Brain, Newspaper } from 'lucide-react';
/** /**
* Tab 配置 * Tab 配置
* @type {Array<{key: string, name: string, icon: React.ComponentType}>} * @type {Array<{key: string, name: string, icon: React.ComponentType}>}
*/ */
export const COMPANY_TABS = [ export const COMPANY_TABS = [
{ key: 'overview', name: '公司档案', icon: FaInfoCircle }, { key: 'overview', name: '公司档案', icon: Info },
{ key: 'analysis', name: '深度分析', icon: FaBrain }, { key: 'analysis', name: '深度分析', icon: Brain },
{ key: 'market', name: '股票行情', icon: FaChartLine }, { key: 'market', name: '股票行情', icon: LineChart },
{ key: 'financial', name: '财务全景', icon: FaMoneyBillWave }, { key: 'financial', name: '财务全景', icon: Banknote },
{ key: 'forecast', name: '盈利预测', icon: FaChartBar }, { key: 'forecast', name: '盈利预测', icon: BarChart2 },
{ key: 'tracking', name: '动态跟踪', icon: FaNewspaper }, { key: 'tracking', name: '动态跟踪', icon: Newspaper },
]; ];
/** /**

View File

@@ -3,7 +3,6 @@
*/ */
import type { ComponentType, ReactNode } from 'react'; import type { ComponentType, ReactNode } from 'react';
import type { IconType } from 'react-icons';
import type { LucideIcon } from 'lucide-react'; import type { LucideIcon } from 'lucide-react';
// ============================================ // ============================================
@@ -34,7 +33,7 @@ export interface CompanyTheme {
export interface TabConfig { export interface TabConfig {
key: string; key: string;
name: string; name: string;
icon: LucideIcon | IconType | ComponentType; icon: LucideIcon | ComponentType;
component: ComponentType<TabComponentProps>; component: ComponentType<TabComponentProps>;
/** 自定义 Suspense fallback如骨架屏 */ /** 自定义 Suspense fallback如骨架屏 */
fallback?: ReactNode; fallback?: ReactNode;