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:
@@ -1,6 +1,6 @@
|
||||
import React from '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"
|
||||
>
|
||||
<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>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from '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"
|
||||
>
|
||||
<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>
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
ModalFooter,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react";
|
||||
import { ExternalLinkIcon } from "@chakra-ui/icons";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
|
||||
import { useAnnouncementsData } from "../../hooks/useAnnouncementsData";
|
||||
import { THEME } from "../config";
|
||||
@@ -92,7 +92,7 @@ const AnnouncementsPanel: React.FC<AnnouncementsPanelProps> = ({ stockCode, isAc
|
||||
)}
|
||||
<IconButton
|
||||
size="sm"
|
||||
icon={<ExternalLinkIcon />}
|
||||
icon={<ExternalLink size={16} />}
|
||||
variant="ghost"
|
||||
color={THEME.goldLight}
|
||||
aria-label="查看原文"
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
SimpleGrid,
|
||||
Center,
|
||||
} 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 { THEME } from "../config";
|
||||
@@ -85,7 +85,7 @@ const BranchesPanel: React.FC<BranchesPanelProps> = ({ stockCode, isActive = tru
|
||||
border="1px solid"
|
||||
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>
|
||||
<Text color={THEME.textSecondary} fontSize="sm">
|
||||
暂无分支机构信息
|
||||
@@ -118,7 +118,7 @@ const BranchesPanel: React.FC<BranchesPanelProps> = ({ stockCode, isActive = tru
|
||||
borderRadius="md"
|
||||
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>
|
||||
<Text
|
||||
fontWeight="bold"
|
||||
@@ -134,7 +134,7 @@ const BranchesPanel: React.FC<BranchesPanelProps> = ({ stockCode, isActive = tru
|
||||
{/* 状态徽章 */}
|
||||
<Box sx={getStatusBadgeStyles(isActive)}>
|
||||
<Icon
|
||||
as={isActive ? FaCheckCircle : FaTimesCircle}
|
||||
as={isActive ? CheckCircle : XCircle}
|
||||
boxSize={3}
|
||||
/>
|
||||
<Text>{branch.business_status}</Text>
|
||||
|
||||
@@ -12,15 +12,15 @@ import {
|
||||
Icon,
|
||||
} from "@chakra-ui/react";
|
||||
import {
|
||||
FaBuilding,
|
||||
FaMapMarkerAlt,
|
||||
FaIdCard,
|
||||
FaUsers,
|
||||
FaBalanceScale,
|
||||
FaCalculator,
|
||||
FaBriefcase,
|
||||
FaFileAlt,
|
||||
} from "react-icons/fa";
|
||||
Building2,
|
||||
MapPin,
|
||||
CreditCard,
|
||||
Users,
|
||||
Scale,
|
||||
Calculator,
|
||||
Briefcase,
|
||||
FileText,
|
||||
} from "lucide-react";
|
||||
|
||||
// 使用统一主题
|
||||
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}>
|
||||
{/* 工商信息卡片 */}
|
||||
<Box {...glassCardStyle} p={4}>
|
||||
<SectionTitle icon={FaBuilding} title="工商信息" />
|
||||
<SectionTitle icon={Building2} title="工商信息" />
|
||||
<VStack spacing={2} align="stretch">
|
||||
<InfoRow
|
||||
icon={FaIdCard}
|
||||
icon={CreditCard}
|
||||
label="信用代码"
|
||||
value={basicInfo.credit_code}
|
||||
isCode
|
||||
/>
|
||||
<InfoRow
|
||||
icon={FaUsers}
|
||||
icon={Users}
|
||||
label="公司规模"
|
||||
value={basicInfo.company_size}
|
||||
/>
|
||||
<InfoRow
|
||||
icon={FaMapMarkerAlt}
|
||||
icon={MapPin}
|
||||
label="注册地址"
|
||||
value={basicInfo.reg_address}
|
||||
isMultiline
|
||||
/>
|
||||
<InfoRow
|
||||
icon={FaMapMarkerAlt}
|
||||
icon={MapPin}
|
||||
label="办公地址"
|
||||
value={basicInfo.office_address}
|
||||
isMultiline
|
||||
@@ -203,15 +203,15 @@ const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode, isActi
|
||||
|
||||
{/* 服务机构卡片 */}
|
||||
<Box {...glassCardStyle} p={4}>
|
||||
<SectionTitle icon={FaBalanceScale} title="服务机构" />
|
||||
<SectionTitle icon={Scale} title="服务机构" />
|
||||
<VStack spacing={3} align="stretch">
|
||||
<ServiceCard
|
||||
icon={FaCalculator}
|
||||
icon={Calculator}
|
||||
label="会计师事务所"
|
||||
value={basicInfo.accounting_firm}
|
||||
/>
|
||||
<ServiceCard
|
||||
icon={FaBalanceScale}
|
||||
icon={Scale}
|
||||
label="律师事务所"
|
||||
value={basicInfo.law_firm}
|
||||
/>
|
||||
@@ -222,12 +222,12 @@ const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode, isActi
|
||||
{/* 下半部分:主营业务 + 经营范围 */}
|
||||
<SimpleGrid columns={{ base: 1, lg: 2 }} spacing={4}>
|
||||
<TextSection
|
||||
icon={FaBriefcase}
|
||||
icon={Briefcase}
|
||||
title="主营业务"
|
||||
content={basicInfo.main_business}
|
||||
/>
|
||||
<TextSection
|
||||
icon={FaFileAlt}
|
||||
icon={FileText}
|
||||
title="经营范围"
|
||||
content={basicInfo.business_scope}
|
||||
/>
|
||||
|
||||
@@ -24,11 +24,11 @@ import {
|
||||
Td,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
FaShareAlt,
|
||||
FaUserTie,
|
||||
FaSitemap,
|
||||
FaInfoCircle,
|
||||
} from 'react-icons/fa';
|
||||
Share2,
|
||||
UserRound,
|
||||
GitBranch,
|
||||
Info,
|
||||
} from 'lucide-react';
|
||||
|
||||
// 深空 FUI 主题配置(与 SubTabContainer 保持一致)
|
||||
const DEEP_SPACE = {
|
||||
@@ -46,10 +46,10 @@ const DEEP_SPACE = {
|
||||
|
||||
// 导航配置(与主组件 config.ts 保持同步)
|
||||
const OVERVIEW_TABS = [
|
||||
{ key: 'shareholder', name: '股权结构', icon: FaShareAlt },
|
||||
{ key: 'management', name: '管理团队', icon: FaUserTie },
|
||||
{ key: 'branches', name: '分支机构', icon: FaSitemap },
|
||||
{ key: 'business', name: '工商信息', icon: FaInfoCircle },
|
||||
{ key: 'shareholder', name: '股权结构', icon: Share2 },
|
||||
{ key: 'management', name: '管理团队', icon: UserRound },
|
||||
{ key: 'branches', name: '分支机构', icon: GitBranch },
|
||||
{ key: 'business', name: '工商信息', icon: Info },
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
Icon,
|
||||
SimpleGrid,
|
||||
} from "@chakra-ui/react";
|
||||
import type { IconType } from "react-icons";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
|
||||
import { THEME } from "../../config";
|
||||
import ManagementCard from "./ManagementCard";
|
||||
@@ -19,7 +19,7 @@ import type { ManagementPerson, ManagementCategory } from "./types";
|
||||
interface CategorySectionProps {
|
||||
category: ManagementCategory;
|
||||
people: ManagementPerson[];
|
||||
icon: IconType;
|
||||
icon: LucideIcon;
|
||||
color: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,10 @@ import {
|
||||
Tag,
|
||||
} from "@chakra-ui/react";
|
||||
import {
|
||||
FaVenusMars,
|
||||
FaGraduationCap,
|
||||
FaPassport,
|
||||
} from "react-icons/fa";
|
||||
Users as GenderIcon,
|
||||
GraduationCap,
|
||||
CreditCard,
|
||||
} from "lucide-react";
|
||||
|
||||
import { THEME } from "../../config";
|
||||
import { formatDate } from "../../utils";
|
||||
@@ -53,7 +53,7 @@ const ManagementCard: React.FC<ManagementCardProps> = ({ person, categoryColor }
|
||||
</Text>
|
||||
{person.gender && (
|
||||
<Icon
|
||||
as={FaVenusMars}
|
||||
as={GenderIcon}
|
||||
color={person.gender === "男" ? "blue.400" : "pink.400"}
|
||||
boxSize={3}
|
||||
/>
|
||||
@@ -69,7 +69,7 @@ const ManagementCard: React.FC<ManagementCardProps> = ({ person, categoryColor }
|
||||
<HStack spacing={2} flexWrap="wrap">
|
||||
{person.education && (
|
||||
<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}
|
||||
</Tag>
|
||||
)}
|
||||
@@ -80,7 +80,7 @@ const ManagementCard: React.FC<ManagementCardProps> = ({ person, categoryColor }
|
||||
)}
|
||||
{person.nationality && person.nationality !== "中国" && (
|
||||
<Tag size="sm" bg="orange.600" color="white">
|
||||
<Icon as={FaPassport} mr={1} boxSize={3} />
|
||||
<Icon as={CreditCard} mr={1} boxSize={3} />
|
||||
{person.nationality}
|
||||
</Tag>
|
||||
)}
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
import React, { useMemo } from "react";
|
||||
import {
|
||||
FaUserTie,
|
||||
FaCrown,
|
||||
FaEye,
|
||||
FaUsers,
|
||||
} from "react-icons/fa";
|
||||
UserRound,
|
||||
Crown,
|
||||
Eye,
|
||||
Users,
|
||||
} from "lucide-react";
|
||||
|
||||
import { useManagementData } from "../../../hooks/useManagementData";
|
||||
import { THEME } from "../../config";
|
||||
@@ -31,10 +31,10 @@ interface ManagementPanelProps {
|
||||
* 分类配置映射
|
||||
*/
|
||||
const CATEGORY_CONFIG: Record<ManagementCategory, CategoryConfig> = {
|
||||
高管: { icon: FaUserTie, color: THEME.gold },
|
||||
董事: { icon: FaCrown, color: THEME.goldLight },
|
||||
监事: { icon: FaEye, color: "green.400" },
|
||||
其他: { icon: FaUsers, color: THEME.textSecondary },
|
||||
高管: { icon: UserRound, color: THEME.gold },
|
||||
董事: { icon: Crown, color: THEME.goldLight },
|
||||
监事: { icon: Eye, color: "green.400" },
|
||||
其他: { icon: Users, color: THEME.textSecondary },
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// 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 {
|
||||
icon: IconType;
|
||||
icon: LucideIcon;
|
||||
color: string;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
// src/views/Company/components/CompanyOverview/BasicInfoTab/config.ts
|
||||
// Tab 配置 + 黑金主题配置
|
||||
|
||||
import { IconType } from "react-icons";
|
||||
import {
|
||||
FaShareAlt,
|
||||
FaUserTie,
|
||||
FaSitemap,
|
||||
FaInfoCircle,
|
||||
} from "react-icons/fa";
|
||||
import { LucideIcon, Share2, UserRound, GitBranch, Info } from "lucide-react";
|
||||
|
||||
// 主题类型定义
|
||||
export interface Theme {
|
||||
@@ -54,7 +48,7 @@ export const THEME: Theme = {
|
||||
export interface TabConfig {
|
||||
key: string;
|
||||
name: string;
|
||||
icon: IconType;
|
||||
icon: LucideIcon;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
@@ -63,25 +57,25 @@ export const TAB_CONFIG: TabConfig[] = [
|
||||
{
|
||||
key: "shareholder",
|
||||
name: "股权结构",
|
||||
icon: FaShareAlt,
|
||||
icon: Share2,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
key: "management",
|
||||
name: "管理团队",
|
||||
icon: FaUserTie,
|
||||
icon: UserRound,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
key: "branches",
|
||||
name: "分支机构",
|
||||
icon: FaSitemap,
|
||||
icon: GitBranch,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
key: "business",
|
||||
name: "工商信息",
|
||||
icon: FaInfoCircle,
|
||||
icon: Info,
|
||||
enabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
Tag,
|
||||
Icon,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaArrowUp, FaArrowDown } from 'react-icons/fa';
|
||||
import { ArrowUp, ArrowDown } from 'lucide-react';
|
||||
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'}
|
||||
>
|
||||
<Icon
|
||||
as={factor.year_on_year > 0 ? FaArrowUp : FaArrowDown}
|
||||
as={factor.year_on_year > 0 ? ArrowUp : ArrowDown}
|
||||
mr={1}
|
||||
boxSize={3}
|
||||
/>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import React, { memo } from '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 = {
|
||||
@@ -133,7 +133,7 @@ const ProcessNavigation: React.FC<ProcessNavigationProps> = memo(({
|
||||
/>
|
||||
|
||||
<Icon
|
||||
as={FaArrowRight}
|
||||
as={ArrowRight}
|
||||
color={THEME.textSecondary}
|
||||
boxSize={4}
|
||||
/>
|
||||
@@ -148,7 +148,7 @@ const ProcessNavigation: React.FC<ProcessNavigationProps> = memo(({
|
||||
/>
|
||||
|
||||
<Icon
|
||||
as={FaArrowRight}
|
||||
as={ArrowRight}
|
||||
color={THEME.textSecondary}
|
||||
boxSize={4}
|
||||
/>
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
SimpleGrid,
|
||||
Button,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaIndustry, FaExpandAlt, FaCompressAlt } from 'react-icons/fa';
|
||||
import { Factory, Maximize2, Minimize2 } from 'lucide-react';
|
||||
import type { BusinessSegment } from '../types';
|
||||
|
||||
// 黑金主题配置
|
||||
@@ -52,7 +52,7 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
|
||||
<Card bg={THEME.cardBg} shadow="md">
|
||||
<CardHeader>
|
||||
<HStack>
|
||||
<Icon as={FaIndustry} color={THEME.gold} />
|
||||
<Icon as={Factory} color={THEME.gold} />
|
||||
<Heading size="sm" color={THEME.textPrimary}>业务板块详情</Heading>
|
||||
<Badge bg={THEME.gold} color="gray.900">{businessSegments.length} 个板块</Badge>
|
||||
</HStack>
|
||||
@@ -74,7 +74,7 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
leftIcon={
|
||||
<Icon as={isExpanded ? FaCompressAlt : FaExpandAlt} />
|
||||
<Icon as={isExpanded ? Minimize2 : Maximize2} />
|
||||
}
|
||||
onClick={() => onToggleSegment(idx)}
|
||||
color={THEME.gold}
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
Badge,
|
||||
Icon,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaChartPie } from 'react-icons/fa';
|
||||
import { PieChart } from 'lucide-react';
|
||||
import { BusinessTreeItem } from '../atoms';
|
||||
import type { BusinessStructure } from '../types';
|
||||
|
||||
@@ -42,7 +42,7 @@ const BusinessStructureCard: React.FC<BusinessStructureCardProps> = ({
|
||||
<Card bg={THEME.cardBg} shadow="md">
|
||||
<CardHeader>
|
||||
<HStack>
|
||||
<Icon as={FaChartPie} color={THEME.gold} />
|
||||
<Icon as={PieChart} color={THEME.gold} />
|
||||
<Heading size="sm" color={THEME.textPrimary}>业务结构分析</Heading>
|
||||
<Badge bg={THEME.gold} color="gray.900">{businessStructure[0]?.report_period}</Badge>
|
||||
</HStack>
|
||||
|
||||
@@ -33,17 +33,17 @@ import {
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
FaTrophy,
|
||||
FaCog,
|
||||
FaStar,
|
||||
FaChartLine,
|
||||
FaDollarSign,
|
||||
FaFlask,
|
||||
FaShieldAlt,
|
||||
FaRocket,
|
||||
FaUsers,
|
||||
FaExternalLinkAlt,
|
||||
} from 'react-icons/fa';
|
||||
Trophy,
|
||||
Settings,
|
||||
Star,
|
||||
TrendingUp,
|
||||
DollarSign,
|
||||
FlaskConical,
|
||||
Shield,
|
||||
Rocket,
|
||||
Users,
|
||||
ExternalLink,
|
||||
} from 'lucide-react';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import { ScoreBar } from '../atoms';
|
||||
import { getRadarChartOption } from '../utils/chartOptions';
|
||||
@@ -110,7 +110,7 @@ const CompetitorTags = memo<CompetitorTagsProps>(({ competitors }) => (
|
||||
color="yellow.500"
|
||||
borderRadius="full"
|
||||
>
|
||||
<Icon as={FaUsers} mr={1} />
|
||||
<Icon as={Users} mr={1} />
|
||||
<TagLabel>{competitor}</TagLabel>
|
||||
</Tag>
|
||||
))}
|
||||
@@ -127,14 +127,14 @@ interface ScoreSectionProps {
|
||||
|
||||
const ScoreSection = memo<ScoreSectionProps>(({ scores }) => (
|
||||
<VStack spacing={4} align="stretch">
|
||||
<ScoreBar label="市场地位" score={scores?.market_position} icon={FaTrophy} />
|
||||
<ScoreBar label="技术实力" score={scores?.technology} icon={FaCog} />
|
||||
<ScoreBar label="品牌价值" score={scores?.brand} icon={FaStar} />
|
||||
<ScoreBar label="运营效率" score={scores?.operation} icon={FaChartLine} />
|
||||
<ScoreBar label="财务健康" score={scores?.finance} icon={FaDollarSign} />
|
||||
<ScoreBar label="创新能力" score={scores?.innovation} icon={FaFlask} />
|
||||
<ScoreBar label="风险控制" score={scores?.risk} icon={FaShieldAlt} />
|
||||
<ScoreBar label="成长潜力" score={scores?.growth} icon={FaRocket} />
|
||||
<ScoreBar label="市场地位" score={scores?.market_position} icon={Trophy} />
|
||||
<ScoreBar label="技术实力" score={scores?.technology} icon={Settings} />
|
||||
<ScoreBar label="品牌价值" score={scores?.brand} icon={Star} />
|
||||
<ScoreBar label="运营效率" score={scores?.operation} icon={TrendingUp} />
|
||||
<ScoreBar label="财务健康" score={scores?.finance} icon={DollarSign} />
|
||||
<ScoreBar label="创新能力" score={scores?.innovation} icon={FlaskConical} />
|
||||
<ScoreBar label="风险控制" score={scores?.risk} icon={Shield} />
|
||||
<ScoreBar label="成长潜力" score={scores?.growth} icon={Rocket} />
|
||||
</VStack>
|
||||
));
|
||||
|
||||
@@ -201,7 +201,7 @@ const CompetitiveAnalysisCard: React.FC<CompetitiveAnalysisCardProps> = memo(
|
||||
<Card {...CARD_STYLES}>
|
||||
<CardHeader>
|
||||
<HStack>
|
||||
<Icon as={FaTrophy} color="yellow.500" />
|
||||
<Icon as={Trophy} color="yellow.500" />
|
||||
<Heading size="sm" color="yellow.500">竞争地位分析</Heading>
|
||||
{competitivePosition.ranking && (
|
||||
<Badge
|
||||
@@ -223,7 +223,7 @@ const CompetitiveAnalysisCard: React.FC<CompetitiveAnalysisCardProps> = memo(
|
||||
size="xs"
|
||||
variant="ghost"
|
||||
color="yellow.500"
|
||||
rightIcon={<Icon as={FaExternalLinkAlt} boxSize={3} />}
|
||||
rightIcon={<Icon as={ExternalLink} boxSize={3} />}
|
||||
onClick={onOpen}
|
||||
_hover={{ bg: 'rgba(212, 175, 55, 0.1)' }}
|
||||
>
|
||||
@@ -269,7 +269,7 @@ const CompetitiveAnalysisCard: React.FC<CompetitiveAnalysisCardProps> = memo(
|
||||
<ModalContent {...MODAL_STYLES.content}>
|
||||
<ModalHeader {...MODAL_STYLES.header}>
|
||||
<HStack>
|
||||
<Icon as={FaTrophy} color="yellow.500" />
|
||||
<Icon as={Trophy} color="yellow.500" />
|
||||
<Text>行业排名详情</Text>
|
||||
</HStack>
|
||||
</ModalHeader>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import React, { memo } from '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 type { InvestmentHighlightItem } from '../../../types';
|
||||
|
||||
@@ -13,7 +13,7 @@ interface HighlightCardProps {
|
||||
}
|
||||
|
||||
export const HighlightCard = memo<HighlightCardProps>(({ highlight }) => {
|
||||
const IconComponent = ICON_MAP[highlight.icon] || FaUsers;
|
||||
const IconComponent = ICON_MAP[highlight.icon] || Users;
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
import React, { memo } from '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';
|
||||
|
||||
interface SectionHeaderProps {
|
||||
icon: IconType;
|
||||
icon: LucideIcon;
|
||||
title: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
Grid,
|
||||
GridItem,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaCrown, FaStar, FaBriefcase } from 'react-icons/fa';
|
||||
import { Crown, Star, Briefcase } from 'lucide-react';
|
||||
import type {
|
||||
QualitativeAnalysis,
|
||||
InvestmentHighlightItem,
|
||||
@@ -57,7 +57,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
|
||||
<Card {...CARD_STYLES}>
|
||||
<CardBody>
|
||||
<VStack spacing={4} align="stretch">
|
||||
<SectionHeader icon={FaCrown} title="核心定位" />
|
||||
<SectionHeader icon={Crown} title="核心定位" />
|
||||
{corePositioning?.one_line_intro && (
|
||||
<Box
|
||||
p={4}
|
||||
@@ -74,7 +74,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
|
||||
<Grid templateColumns={GRID_COLUMNS.twoColumnMd} gap={4}>
|
||||
<GridItem>
|
||||
<Box p={4} bg={THEME.light.cardBg} borderRadius="lg">
|
||||
<SectionHeader icon={FaStar} title="投资亮点" />
|
||||
<SectionHeader icon={Star} title="投资亮点" />
|
||||
<Text
|
||||
fontSize="sm"
|
||||
color={THEME.light.subtextColor}
|
||||
@@ -89,7 +89,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
|
||||
</GridItem>
|
||||
<GridItem>
|
||||
<Box p={4} bg={THEME.light.cardBg} borderRadius="lg">
|
||||
<SectionHeader icon={FaBriefcase} title="商业模式" />
|
||||
<SectionHeader icon={Briefcase} title="商业模式" />
|
||||
<Text
|
||||
fontSize="sm"
|
||||
color={THEME.light.subtextColor}
|
||||
@@ -126,7 +126,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
|
||||
<VStack spacing={0} align="stretch">
|
||||
{/* 核心定位区域(深色背景) */}
|
||||
<Box p={6} bg={THEME.dark.bg}>
|
||||
<SectionHeader icon={FaCrown} title="核心定位" />
|
||||
<SectionHeader icon={Crown} title="核心定位" />
|
||||
|
||||
{/* 一句话介绍 */}
|
||||
{corePositioning?.one_line_intro && (
|
||||
@@ -152,7 +152,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
|
||||
borderRight={BORDER_RIGHT_RESPONSIVE}
|
||||
borderColor="whiteAlpha.100"
|
||||
>
|
||||
<SectionHeader icon={FaStar} title="投资亮点" />
|
||||
<SectionHeader icon={Star} title="投资亮点" />
|
||||
<VStack spacing={3} align="stretch">
|
||||
{highlights.length > 0 ? (
|
||||
highlights.map((highlight, idx) => (
|
||||
@@ -168,7 +168,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
|
||||
|
||||
{/* 商业模式区域 */}
|
||||
<GridItem p={6}>
|
||||
<SectionHeader icon={FaBriefcase} title="商业模式" />
|
||||
<SectionHeader icon={Briefcase} title="商业模式" />
|
||||
<Box
|
||||
p={4}
|
||||
bg={THEME.light.cardBg}
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
FaUniversity,
|
||||
FaFire,
|
||||
FaUsers,
|
||||
FaChartLine,
|
||||
FaMicrochip,
|
||||
FaShieldAlt,
|
||||
} from 'react-icons/fa';
|
||||
import type { IconType } from 'react-icons';
|
||||
University,
|
||||
Flame,
|
||||
Users,
|
||||
TrendingUp,
|
||||
Cpu,
|
||||
Shield,
|
||||
type LucideIcon,
|
||||
} from 'lucide-react';
|
||||
|
||||
// ==================== 主题常量 ====================
|
||||
|
||||
@@ -39,13 +39,13 @@ export const THEME = {
|
||||
|
||||
// ==================== 图标映射 ====================
|
||||
|
||||
export const ICON_MAP: Record<string, IconType> = {
|
||||
bank: FaUniversity,
|
||||
fire: FaFire,
|
||||
users: FaUsers,
|
||||
'trending-up': FaChartLine,
|
||||
cpu: FaMicrochip,
|
||||
'shield-check': FaShieldAlt,
|
||||
export const ICON_MAP: Record<string, LucideIcon> = {
|
||||
bank: University,
|
||||
fire: Flame,
|
||||
users: Users,
|
||||
'trending-up': TrendingUp,
|
||||
cpu: Cpu,
|
||||
'shield-check': Shield,
|
||||
};
|
||||
|
||||
// ==================== 样式常量 ====================
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
AccordionPanel,
|
||||
AccordionIcon,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaBalanceScale } from 'react-icons/fa';
|
||||
import { Scale } from 'lucide-react';
|
||||
import { KeyFactorCard } from '../atoms';
|
||||
import type { KeyFactors } from '../types';
|
||||
|
||||
@@ -66,7 +66,7 @@ const KeyFactorsCard: React.FC<KeyFactorsCardProps> = ({ keyFactors }) => {
|
||||
<Card {...CARD_STYLES} h="full">
|
||||
<CardHeader>
|
||||
<HStack>
|
||||
<Icon as={FaBalanceScale} color="yellow.500" />
|
||||
<Icon as={Scale} color="yellow.500" />
|
||||
<Heading size="sm" color={THEME.titleColor}>
|
||||
关键因素
|
||||
</Heading>
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
GridItem,
|
||||
Center,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaRocket, FaChartBar } from 'react-icons/fa';
|
||||
import { Rocket, BarChart2 } from 'lucide-react';
|
||||
import type { Strategy } from '../types';
|
||||
|
||||
// 样式常量 - 避免每次渲染创建新对象
|
||||
@@ -54,7 +54,7 @@ const EmptyState = memo(() => (
|
||||
<Box {...EMPTY_BOX_STYLES}>
|
||||
<Center>
|
||||
<VStack spacing={3}>
|
||||
<Icon as={FaChartBar} boxSize={10} color="yellow.600" />
|
||||
<Icon as={BarChart2} boxSize={10} color="yellow.600" />
|
||||
<Text fontWeight="medium">战略数据更新中</Text>
|
||||
<Text fontSize="sm" color="gray.500">
|
||||
战略方向和具体举措数据将在近期更新
|
||||
@@ -97,7 +97,7 @@ const StrategyAnalysisCard: React.FC<StrategyAnalysisCardProps> = memo(
|
||||
<Card {...CARD_STYLES}>
|
||||
<CardHeader>
|
||||
<HStack>
|
||||
<Icon as={FaRocket} color="yellow.500" />
|
||||
<Icon as={Rocket} color="yellow.500" />
|
||||
<Heading size="sm" color="yellow.500">战略分析</Heading>
|
||||
</HStack>
|
||||
</CardHeader>
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
Box,
|
||||
Icon,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaHistory } from 'react-icons/fa';
|
||||
import { History } from 'lucide-react';
|
||||
import TimelineComponent from '../organisms/TimelineComponent';
|
||||
import type { DevelopmentTimeline } from '../types';
|
||||
|
||||
@@ -59,7 +59,7 @@ const TimelineCard: React.FC<TimelineCardProps> = ({ developmentTimeline }) => {
|
||||
<Card {...CARD_STYLES} h="full">
|
||||
<CardHeader>
|
||||
<HStack>
|
||||
<Icon as={FaHistory} color="yellow.500" />
|
||||
<Icon as={History} color="yellow.500" />
|
||||
<Heading size="sm" color={THEME.titleColor}>
|
||||
发展时间线
|
||||
</Heading>
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
Box,
|
||||
Flex,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaNetworkWired } from 'react-icons/fa';
|
||||
import { Network } from 'lucide-react';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import {
|
||||
ProcessNavigation,
|
||||
@@ -133,7 +133,7 @@ const ValueChainCard: React.FC<ValueChainCardProps> = memo(({
|
||||
{/* 头部区域 */}
|
||||
<CardHeader py={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>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
import React, { useMemo } from '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 LoadingState from '../../LoadingState';
|
||||
import { StrategyTab, BusinessTab, ValueChainTab, DevelopmentTab } from './tabs';
|
||||
@@ -28,10 +28,10 @@ const THEME = {
|
||||
* Tab 配置
|
||||
*/
|
||||
const DEEP_ANALYSIS_TABS: SubTabConfig[] = [
|
||||
{ key: 'strategy', name: '战略分析', icon: FaBrain, component: StrategyTab },
|
||||
{ key: 'business', name: '业务结构', icon: FaBuilding, component: BusinessTab },
|
||||
{ key: 'valueChain', name: '产业链', icon: FaLink, component: ValueChainTab },
|
||||
{ key: 'development', name: '发展历程', icon: FaHistory, component: DevelopmentTab },
|
||||
{ key: 'strategy', name: '战略分析', icon: Brain, component: StrategyTab },
|
||||
{ key: 'business', name: '业务结构', icon: Building2, component: BusinessTab },
|
||||
{ key: 'valueChain', name: '产业链', icon: Link2, component: ValueChainTab },
|
||||
{ key: 'development', name: '发展历程', icon: History, component: DevelopmentTab },
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
Icon,
|
||||
Button,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaCheckCircle, FaExclamationCircle } from 'react-icons/fa';
|
||||
import { CheckCircle, AlertCircle } from 'lucide-react';
|
||||
import type { TimelineEvent } from '../../types';
|
||||
|
||||
interface EventDetailModalProps {
|
||||
@@ -48,7 +48,7 @@ const EventDetailModal: React.FC<EventDetailModalProps> = ({
|
||||
<ModalHeader>
|
||||
<HStack>
|
||||
<Icon
|
||||
as={isPositive ? FaCheckCircle : FaExclamationCircle}
|
||||
as={isPositive ? CheckCircle : AlertCircle}
|
||||
color={isPositive ? 'red.500' : 'green.500'}
|
||||
boxSize={6}
|
||||
/>
|
||||
|
||||
@@ -20,10 +20,10 @@ import {
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
FaCalendarAlt,
|
||||
FaArrowUp,
|
||||
FaArrowDown,
|
||||
} from 'react-icons/fa';
|
||||
Calendar,
|
||||
ArrowUp,
|
||||
ArrowDown,
|
||||
} from 'lucide-react';
|
||||
import EventDetailModal from './EventDetailModal';
|
||||
import type { TimelineComponentProps, TimelineEvent } from '../../types';
|
||||
|
||||
@@ -74,7 +74,7 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ events }) => {
|
||||
shadow="md"
|
||||
>
|
||||
<Icon
|
||||
as={isPositive ? FaArrowUp : FaArrowDown}
|
||||
as={isPositive ? ArrowUp : ArrowDown}
|
||||
color="white"
|
||||
boxSize={3}
|
||||
/>
|
||||
@@ -108,7 +108,7 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ events }) => {
|
||||
</Text>
|
||||
<HStack spacing={2}>
|
||||
<Icon
|
||||
as={FaCalendarAlt}
|
||||
as={Calendar}
|
||||
boxSize={3}
|
||||
color="gray.500"
|
||||
/>
|
||||
|
||||
@@ -34,19 +34,19 @@ import {
|
||||
Tooltip,
|
||||
Button,
|
||||
} from '@chakra-ui/react';
|
||||
import { ExternalLinkIcon } from '@chakra-ui/icons';
|
||||
import {
|
||||
FaBuilding,
|
||||
FaHandshake,
|
||||
FaUserTie,
|
||||
FaIndustry,
|
||||
FaCog,
|
||||
FaNetworkWired,
|
||||
FaFlask,
|
||||
FaStar,
|
||||
FaArrowRight,
|
||||
FaArrowLeft,
|
||||
} from 'react-icons/fa';
|
||||
ExternalLink,
|
||||
Building,
|
||||
Handshake,
|
||||
UserCircle,
|
||||
Factory,
|
||||
Settings,
|
||||
Network,
|
||||
FlaskConical,
|
||||
Star,
|
||||
ArrowRight,
|
||||
ArrowLeft,
|
||||
} from 'lucide-react';
|
||||
import type { ValueChainNode, RelatedCompany } from '../../types';
|
||||
|
||||
interface RelatedCompaniesModalProps {
|
||||
@@ -64,15 +64,15 @@ interface RelatedCompaniesModalProps {
|
||||
*/
|
||||
const getNodeTypeIcon = (type: string) => {
|
||||
const icons: Record<string, React.ComponentType> = {
|
||||
company: FaBuilding,
|
||||
supplier: FaHandshake,
|
||||
customer: FaUserTie,
|
||||
product: FaIndustry,
|
||||
service: FaCog,
|
||||
channel: FaNetworkWired,
|
||||
raw_material: FaFlask,
|
||||
company: Building,
|
||||
supplier: Handshake,
|
||||
customer: UserCircle,
|
||||
product: Factory,
|
||||
service: Settings,
|
||||
channel: Network,
|
||||
raw_material: FlaskConical,
|
||||
};
|
||||
return icons[type] || FaBuilding;
|
||||
return icons[type] || Building;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -242,7 +242,7 @@ const RelatedCompaniesModal: React.FC<RelatedCompaniesModalProps> = ({
|
||||
</VStack>
|
||||
<IconButton
|
||||
size="sm"
|
||||
icon={<ExternalLinkIcon />}
|
||||
icon={<ExternalLink size={16} />}
|
||||
variant="ghost"
|
||||
colorScheme="blue"
|
||||
onClick={() => {
|
||||
@@ -287,8 +287,8 @@ const RelatedCompaniesModal: React.FC<RelatedCompaniesModalProps> = ({
|
||||
<Icon
|
||||
as={
|
||||
rel.role === 'source'
|
||||
? FaArrowRight
|
||||
: FaArrowLeft
|
||||
? ArrowRight
|
||||
: ArrowLeft
|
||||
}
|
||||
color={
|
||||
rel.role === 'source'
|
||||
@@ -323,7 +323,7 @@ const RelatedCompaniesModal: React.FC<RelatedCompaniesModalProps> = ({
|
||||
) : (
|
||||
<Center py={4}>
|
||||
<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>
|
||||
|
||||
@@ -22,15 +22,15 @@ import {
|
||||
ScaleFade,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
FaBuilding,
|
||||
FaHandshake,
|
||||
FaUserTie,
|
||||
FaIndustry,
|
||||
FaCog,
|
||||
FaNetworkWired,
|
||||
FaFlask,
|
||||
FaStar,
|
||||
} from 'react-icons/fa';
|
||||
Building,
|
||||
Handshake,
|
||||
UserCircle,
|
||||
Factory,
|
||||
Settings,
|
||||
Network,
|
||||
FlaskConical,
|
||||
Star,
|
||||
} from 'lucide-react';
|
||||
import { logger } from '@utils/logger';
|
||||
import axios from '@utils/axiosConfig';
|
||||
import RelatedCompaniesModal from './RelatedCompaniesModal';
|
||||
@@ -71,17 +71,17 @@ const THEME = {
|
||||
*/
|
||||
const getNodeTypeIcon = (type: string) => {
|
||||
const icons: Record<string, React.ComponentType> = {
|
||||
company: FaBuilding,
|
||||
supplier: FaHandshake,
|
||||
customer: FaUserTie,
|
||||
product: FaIndustry,
|
||||
service: FaCog,
|
||||
channel: FaNetworkWired,
|
||||
raw_material: FaFlask,
|
||||
regulator: FaBuilding,
|
||||
end_user: FaUserTie,
|
||||
company: Building,
|
||||
supplier: Handshake,
|
||||
customer: UserCircle,
|
||||
product: Factory,
|
||||
service: Settings,
|
||||
channel: Network,
|
||||
raw_material: FlaskConical,
|
||||
regulator: Building,
|
||||
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 && (
|
||||
<Tooltip label="重要节点">
|
||||
<span>
|
||||
<Icon as={FaStar} color={THEME.gold} boxSize={4} />
|
||||
<Icon as={Star} color={THEME.gold} boxSize={4} />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
StatNumber,
|
||||
StatHelpText,
|
||||
} from "@chakra-ui/react";
|
||||
import { FaCrown } from "react-icons/fa";
|
||||
import { Crown } from "lucide-react";
|
||||
import type { ActualControl } from "../../types";
|
||||
import { THEME } from "../../BasicInfoTab/config";
|
||||
|
||||
@@ -58,7 +58,7 @@ const ActualControlCard: React.FC<ActualControlCardProps> = ({ actualControl = [
|
||||
return (
|
||||
<Box>
|
||||
<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>
|
||||
</HStack>
|
||||
<Card bg={THEME.cardBg} borderColor={THEME.border} borderWidth="1px">
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
CardHeader,
|
||||
SimpleGrid,
|
||||
} 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 type { Concentration } from "../../types";
|
||||
import { THEME } from "../../BasicInfoTab/config";
|
||||
@@ -182,7 +182,7 @@ const ConcentrationCard: React.FC<ConcentrationCardProps> = ({ concentration = [
|
||||
return (
|
||||
<Box>
|
||||
<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>
|
||||
</HStack>
|
||||
<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"}
|
||||
>
|
||||
<Icon
|
||||
as={item.ratio_change > 0 ? FaArrowUp : FaArrowDown}
|
||||
as={item.ratio_change > 0 ? ArrowUp : ArrowDown}
|
||||
mr={1}
|
||||
boxSize={3}
|
||||
/>
|
||||
|
||||
@@ -5,7 +5,7 @@ import React, { useMemo, memo } from "react";
|
||||
import { Box, HStack, Heading, Badge, Icon, useBreakpointValue } from "@chakra-ui/react";
|
||||
import { Table, Tag, Tooltip, ConfigProvider } from "antd";
|
||||
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 { THEME } from "../../BasicInfoTab/config";
|
||||
|
||||
@@ -96,7 +96,7 @@ const ShareholdersTable: React.FC<ShareholdersTableProps> = ({
|
||||
if (type === "circulation") {
|
||||
return {
|
||||
title: title || "十大流通股东",
|
||||
icon: FaChartLine,
|
||||
icon: LineChart,
|
||||
iconColor: "purple.500",
|
||||
ratioField: "circulation_share_ratio" as keyof Shareholder,
|
||||
ratioLabel: "流通股比例",
|
||||
@@ -106,7 +106,7 @@ const ShareholdersTable: React.FC<ShareholdersTableProps> = ({
|
||||
}
|
||||
return {
|
||||
title: title || "十大股东",
|
||||
icon: FaUsers,
|
||||
icon: Users,
|
||||
iconColor: "green.500",
|
||||
ratioField: "total_share_ratio" as keyof Shareholder,
|
||||
ratioLabel: "持股比例",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React, { memo } from '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';
|
||||
|
||||
const NewsEmptyState: React.FC<NewsEmptyStateProps> = ({
|
||||
@@ -15,7 +15,7 @@ const NewsEmptyState: React.FC<NewsEmptyStateProps> = ({
|
||||
<Center h="400px">
|
||||
<VStack spacing={3}>
|
||||
<Icon
|
||||
as={FaNewspaper}
|
||||
as={Newspaper}
|
||||
boxSize={16}
|
||||
color={isBlackGold ? theme.gold : 'gray.300'}
|
||||
opacity={0.5}
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
CardBody,
|
||||
Tag,
|
||||
} 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 {
|
||||
getEventTypeIcon,
|
||||
@@ -117,7 +117,7 @@ const NewsEventCard: React.FC<NewsEventCardProps> = ({
|
||||
<HStack spacing={3}>
|
||||
{event.view_count !== undefined && (
|
||||
<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}>
|
||||
{event.view_count}
|
||||
</Text>
|
||||
@@ -125,7 +125,7 @@ const NewsEventCard: React.FC<NewsEventCardProps> = ({
|
||||
)}
|
||||
{event.hot_score !== undefined && (
|
||||
<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}>
|
||||
{event.hot_score.toFixed(1)}
|
||||
</Text>
|
||||
@@ -152,7 +152,7 @@ const NewsEventCard: React.FC<NewsEventCardProps> = ({
|
||||
<Box pt={2} borderTop="1px" borderColor={theme.cardBorder}>
|
||||
<HStack spacing={6} flexWrap="wrap">
|
||||
<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>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React, { memo, useMemo } from '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';
|
||||
|
||||
const NewsPagination: React.FC<NewsPaginationProps> = ({
|
||||
@@ -87,7 +87,7 @@ const NewsPagination: React.FC<NewsPaginationProps> = ({
|
||||
_hover={{ bg: theme.cardHoverBg, borderColor: theme.gold }}
|
||||
onClick={() => onPageChange(1)}
|
||||
isDisabled={!has_prev || isLoading}
|
||||
leftIcon={<Icon as={FaChevronLeft} />}
|
||||
leftIcon={<Icon as={ChevronLeft} />}
|
||||
>
|
||||
首页
|
||||
</Button>
|
||||
@@ -128,7 +128,7 @@ const NewsPagination: React.FC<NewsPaginationProps> = ({
|
||||
_hover={{ bg: theme.cardHoverBg, borderColor: theme.gold }}
|
||||
onClick={() => onPageChange(totalPages)}
|
||||
isDisabled={!has_next || isLoading}
|
||||
rightIcon={<Icon as={FaChevronRight} />}
|
||||
rightIcon={<Icon as={ChevronRight} />}
|
||||
>
|
||||
末页
|
||||
</Button>
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
import React, { memo } from 'react';
|
||||
import { HStack, Input, InputGroup, InputLeftElement, Button, Text, Icon } from '@chakra-ui/react';
|
||||
import { SearchIcon } from '@chakra-ui/icons';
|
||||
import { FaNewspaper } from 'react-icons/fa';
|
||||
import { Search, Newspaper } from 'lucide-react';
|
||||
import type { NewsSearchBarProps } from '../types';
|
||||
|
||||
const NewsSearchBar: React.FC<NewsSearchBarProps> = ({
|
||||
@@ -31,7 +30,7 @@ const NewsSearchBar: React.FC<NewsSearchBarProps> = ({
|
||||
<HStack flex={1} minW="300px">
|
||||
<InputGroup>
|
||||
<InputLeftElement pointerEvents="none">
|
||||
<SearchIcon color={theme.textMuted} />
|
||||
<Search size={16} color={theme.textMuted} />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
placeholder="搜索相关新闻..."
|
||||
@@ -60,7 +59,7 @@ const NewsSearchBar: React.FC<NewsSearchBarProps> = ({
|
||||
|
||||
{total > 0 && (
|
||||
<HStack spacing={2}>
|
||||
<Icon as={FaNewspaper} color={theme.gold} />
|
||||
<Icon as={Newspaper} color={theme.gold} />
|
||||
<Text fontSize="sm" color={theme.textSecondary}>
|
||||
共找到{' '}
|
||||
<Text as="span" fontWeight="bold" color={theme.gold}>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// src/views/Company/components/DynamicTracking/NewsEventsTab/types.ts
|
||||
// 新闻动态 - 类型定义
|
||||
|
||||
import type { IconType } from 'react-icons';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
|
||||
/**
|
||||
* 徽章样式配置
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
// src/views/Company/components/DynamicTracking/NewsEventsTab/utils.ts
|
||||
// 新闻动态 - 工具函数
|
||||
|
||||
import type { IconType } from 'react-icons';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
import {
|
||||
FaNewspaper,
|
||||
FaBullhorn,
|
||||
FaGavel,
|
||||
FaFlask,
|
||||
FaDollarSign,
|
||||
FaShieldAlt,
|
||||
FaFileAlt,
|
||||
FaIndustry,
|
||||
} from 'react-icons/fa';
|
||||
Newspaper,
|
||||
Megaphone,
|
||||
Gavel,
|
||||
FlaskConical,
|
||||
DollarSign,
|
||||
Shield,
|
||||
FileText,
|
||||
Factory,
|
||||
} from 'lucide-react';
|
||||
import type { ThemeConfig, BadgeStyle } from './types';
|
||||
|
||||
/**
|
||||
* 事件类型图标映射
|
||||
*/
|
||||
const EVENT_TYPE_ICONS: Record<string, IconType> = {
|
||||
企业公告: FaBullhorn,
|
||||
政策: FaGavel,
|
||||
技术突破: FaFlask,
|
||||
企业融资: FaDollarSign,
|
||||
政策监管: FaShieldAlt,
|
||||
政策动态: FaFileAlt,
|
||||
行业事件: FaIndustry,
|
||||
const EVENT_TYPE_ICONS: Record<string, LucideIcon> = {
|
||||
企业公告: Megaphone,
|
||||
政策: Gavel,
|
||||
技术突破: FlaskConical,
|
||||
企业融资: DollarSign,
|
||||
政策监管: Shield,
|
||||
政策动态: FileText,
|
||||
行业事件: Factory,
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取事件类型对应的图标
|
||||
*/
|
||||
export const getEventTypeIcon = (eventType?: string): IconType => {
|
||||
if (!eventType) return FaNewspaper;
|
||||
return EVENT_TYPE_ICONS[eventType] || FaNewspaper;
|
||||
export const getEventTypeIcon = (eventType?: string): LucideIcon => {
|
||||
if (!eventType) return Newspaper;
|
||||
return EVENT_TYPE_ICONS[eventType] || Newspaper;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
Card,
|
||||
CardBody,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaNewspaper, FaBullhorn, FaCalendarAlt, FaChartBar } from 'react-icons/fa';
|
||||
import { Newspaper, Megaphone, Calendar, BarChart2 } from 'lucide-react';
|
||||
|
||||
// 深空 FUI 主题配置(与 SubTabContainer 保持一致)
|
||||
const DEEP_SPACE = {
|
||||
@@ -35,10 +35,10 @@ const DEEP_SPACE = {
|
||||
|
||||
// 导航配置(与主组件保持同步)
|
||||
const TRACKING_TABS = [
|
||||
{ key: 'news', name: '新闻动态', icon: FaNewspaper },
|
||||
{ key: 'announcements', name: '公司公告', icon: FaBullhorn },
|
||||
{ key: 'disclosure', name: '财报披露日程', icon: FaCalendarAlt },
|
||||
{ key: 'forecast', name: '业绩预告', icon: FaChartBar },
|
||||
{ key: 'news', name: '新闻动态', icon: Newspaper },
|
||||
{ key: 'announcements', name: '公司公告', icon: Megaphone },
|
||||
{ key: 'disclosure', name: '财报披露日程', icon: Calendar },
|
||||
{ key: 'forecast', name: '业绩预告', icon: BarChart2 },
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import React, { useState, useEffect, useMemo, useCallback, memo, lazy } from '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 {
|
||||
@@ -29,28 +29,28 @@ const TRACKING_TABS = [
|
||||
{
|
||||
key: 'news',
|
||||
name: '新闻动态',
|
||||
icon: FaNewspaper,
|
||||
icon: Newspaper,
|
||||
component: NewsPanel,
|
||||
fallback: <NewsPanelSkeleton />,
|
||||
},
|
||||
{
|
||||
key: 'announcements',
|
||||
name: '公司公告',
|
||||
icon: FaBullhorn,
|
||||
icon: Megaphone,
|
||||
component: AnnouncementsPanel,
|
||||
fallback: <AnnouncementsSkeleton />,
|
||||
},
|
||||
{
|
||||
key: 'disclosure',
|
||||
name: '财报披露日程',
|
||||
icon: FaCalendarAlt,
|
||||
icon: Calendar,
|
||||
component: DisclosureSchedulePanel,
|
||||
fallback: <DisclosureScheduleSkeleton />,
|
||||
},
|
||||
{
|
||||
key: 'forecast',
|
||||
name: '业绩预告',
|
||||
icon: FaChartBar,
|
||||
icon: BarChart2,
|
||||
component: ForecastPanel,
|
||||
fallback: <ForecastPanelSkeleton />,
|
||||
},
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
Grid,
|
||||
GridItem,
|
||||
} from '@chakra-ui/react';
|
||||
import { ArrowUpIcon, ArrowDownIcon } from '@chakra-ui/icons';
|
||||
import { ArrowUp, ArrowDown } from 'lucide-react';
|
||||
import { useToast } from '@chakra-ui/react';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import { logger } from '@utils/logger';
|
||||
@@ -166,8 +166,8 @@ export const StockComparison: React.FC<StockComparisonProps> = ({
|
||||
<Td isNumeric color={diffColor}>
|
||||
{diff !== null ? (
|
||||
<HStack spacing={1} justify="flex-end">
|
||||
{diff > 0 && <ArrowUpIcon boxSize={3} />}
|
||||
{diff < 0 && <ArrowDownIcon boxSize={3} />}
|
||||
{diff > 0 && <ArrowUp size={12} />}
|
||||
{diff < 0 && <ArrowDown size={12} />}
|
||||
<Text>
|
||||
{metric.format === 'percent'
|
||||
? `${Math.abs(diff).toFixed(2)}pp`
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
Text,
|
||||
Icon,
|
||||
} from '@chakra-ui/react';
|
||||
import { ExternalLinkIcon } from '@chakra-ui/icons';
|
||||
import { FileText, TrendingUp, Building2, Newspaper, BookOpen } from 'lucide-react';
|
||||
import MarkdownRenderer from './MarkdownRenderer';
|
||||
import { formatNumber } from '../utils/formatUtils';
|
||||
|
||||
@@ -28,8 +28,7 @@ import {
|
||||
Flex,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
import { SearchIcon, CloseIcon, AddIcon } from '@chakra-ui/icons';
|
||||
import { Database, TrendingUp } from 'lucide-react';
|
||||
import { Database, TrendingUp, Search, X, Plus } from 'lucide-react';
|
||||
import debounce from 'lodash/debounce';
|
||||
|
||||
import { searchMetrics, fetchMetricData, type MetricSearchResult } from '@services/categoryService';
|
||||
@@ -233,7 +232,7 @@ const MetricOverlaySearch: React.FC<MetricOverlaySearchProps> = ({
|
||||
{/* Search input */}
|
||||
<InputGroup size="sm" mb={3}>
|
||||
<InputLeftElement pointerEvents="none">
|
||||
<SearchIcon color={darkGoldTheme.textMuted} />
|
||||
<Search size={16} color={darkGoldTheme.textMuted} />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
ref={inputRef}
|
||||
@@ -255,7 +254,7 @@ const MetricOverlaySearch: React.FC<MetricOverlaySearchProps> = ({
|
||||
<IconButton
|
||||
size="xs"
|
||||
variant="ghost"
|
||||
icon={<CloseIcon w="8px" h="8px" />}
|
||||
icon={<X size={12} />}
|
||||
onClick={() => {
|
||||
setSearchQuery('');
|
||||
setSearchResults([]);
|
||||
@@ -318,7 +317,7 @@ const MetricOverlaySearch: React.FC<MetricOverlaySearchProps> = ({
|
||||
{isAdded ? (
|
||||
<Badge colorScheme="green" fontSize="10px">Added</Badge>
|
||||
) : (
|
||||
<AddIcon boxSize={3} color={darkGoldTheme.textMuted} />
|
||||
<Plus size={12} color={darkGoldTheme.textMuted} />
|
||||
)}
|
||||
</Flex>
|
||||
</ListItem>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React, { memo, useMemo } from '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 { darkGoldTheme } from '../../../../constants';
|
||||
@@ -32,7 +32,7 @@ export interface DailyKLineChartProps {
|
||||
const EmptyState: React.FC<{ title: string; description: string }> = ({ title, description }) => (
|
||||
<Center h="300px">
|
||||
<VStack spacing={4}>
|
||||
<Icon as={InfoIcon} color={darkGoldTheme.textMuted} boxSize={12} />
|
||||
<Icon as={Info} color={darkGoldTheme.textMuted} boxSize={12} />
|
||||
<VStack spacing={2}>
|
||||
<Text color={darkGoldTheme.textMuted} fontSize="lg">{title}</Text>
|
||||
<Text color={darkGoldTheme.textMuted} fontSize="sm" textAlign="center">{description}</Text>
|
||||
|
||||
@@ -18,8 +18,7 @@ import {
|
||||
MenuItem,
|
||||
Tooltip,
|
||||
} from '@chakra-ui/react';
|
||||
import { RepeatIcon, ChevronDownIcon, ViewIcon, ViewOffIcon } from '@chakra-ui/icons';
|
||||
import { BarChart2, TrendingUp, Calendar, LineChart, Activity, Pencil } from 'lucide-react';
|
||||
import { BarChart2, TrendingUp, Calendar, LineChart, Activity, Pencil, RefreshCw, ChevronDown, Eye, EyeOff } from 'lucide-react';
|
||||
|
||||
import { darkGoldTheme, PERIOD_OPTIONS } from '../../../../constants';
|
||||
import type { IndicatorType, MainIndicatorType, DrawingType } from '../../../../utils/chartOptions';
|
||||
@@ -155,7 +154,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
leftIcon={showAnalysis ? <ViewOffIcon /> : <ViewIcon />}
|
||||
leftIcon={showAnalysis ? <EyeOff size={14} /> : <Eye size={14} />}
|
||||
onClick={onToggleAnalysis}
|
||||
{...(showAnalysis ? INACTIVE_BUTTON_STYLE : ACTIVE_BUTTON_STYLE)}
|
||||
minW="90px"
|
||||
@@ -171,7 +170,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
|
||||
as={Button}
|
||||
size="sm"
|
||||
variant="outline"
|
||||
rightIcon={<ChevronDownIcon />}
|
||||
rightIcon={<ChevronDown size={14} />}
|
||||
{...INACTIVE_BUTTON_STYLE}
|
||||
minW="90px"
|
||||
>
|
||||
@@ -205,7 +204,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
|
||||
as={Button}
|
||||
size="sm"
|
||||
variant="outline"
|
||||
rightIcon={<ChevronDownIcon />}
|
||||
rightIcon={<ChevronDown size={14} />}
|
||||
leftIcon={<Activity size={14} />}
|
||||
{...INACTIVE_BUTTON_STYLE}
|
||||
minW="100px"
|
||||
@@ -240,7 +239,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
|
||||
as={Button}
|
||||
size="sm"
|
||||
variant="outline"
|
||||
rightIcon={<ChevronDownIcon />}
|
||||
rightIcon={<ChevronDown size={14} />}
|
||||
leftIcon={<Pencil size={14} />}
|
||||
{...(drawingType !== 'NONE' ? ACTIVE_BUTTON_STYLE : INACTIVE_BUTTON_STYLE)}
|
||||
minW="90px"
|
||||
@@ -296,7 +295,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
|
||||
|
||||
{/* 刷新按钮 */}
|
||||
<Button
|
||||
leftIcon={<RepeatIcon />}
|
||||
leftIcon={<RefreshCw size={14} />}
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={onRefreshMinuteData}
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
GridItem,
|
||||
Icon,
|
||||
} from '@chakra-ui/react';
|
||||
import { InfoIcon } from '@chakra-ui/icons';
|
||||
import { Info } from 'lucide-react';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
|
||||
// 导入实时行情 Hook 和五档盘口组件
|
||||
@@ -38,7 +38,7 @@ export interface MinuteChartWithOrderBookProps {
|
||||
const EmptyState: React.FC<{ title: string; description: string }> = ({ title, description }) => (
|
||||
<Center h="300px">
|
||||
<VStack spacing={4}>
|
||||
<Icon as={InfoIcon} color={darkGoldTheme.textMuted} boxSize={12} />
|
||||
<Icon as={Info} color={darkGoldTheme.textMuted} boxSize={12} />
|
||||
<VStack spacing={2}>
|
||||
<Text color={darkGoldTheme.textMuted} fontSize="lg">{title}</Text>
|
||||
<Text color={darkGoldTheme.textMuted} fontSize="sm" textAlign="center">{description}</Text>
|
||||
|
||||
@@ -16,8 +16,7 @@ import {
|
||||
VStack,
|
||||
Spinner,
|
||||
} from '@chakra-ui/react';
|
||||
import { SearchIcon } from '@chakra-ui/icons';
|
||||
import { BarChart2 } from 'lucide-react';
|
||||
import { BarChart2, Search } from 'lucide-react';
|
||||
import { useStockSearch, type Stock } from '../../../hooks/useStockSearch';
|
||||
|
||||
interface CompareStockInputProps {
|
||||
@@ -106,7 +105,7 @@ const CompareStockInput: React.FC<CompareStockInputProps> = ({
|
||||
<HStack spacing={2}>
|
||||
<InputGroup size="sm" w="160px">
|
||||
<InputLeftElement pointerEvents="none">
|
||||
<SearchIcon color={textColor} boxSize={3} />
|
||||
<Search size={12} color={textColor} />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
placeholder="对比股票"
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
Spinner,
|
||||
Center,
|
||||
} from '@chakra-ui/react';
|
||||
import { ArrowUpIcon, ArrowDownIcon } from '@chakra-ui/icons';
|
||||
import { ArrowUp, ArrowDown } from 'lucide-react';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
|
||||
import { COMPARE_METRICS } from '../../FinancialPanorama/constants';
|
||||
@@ -149,8 +149,8 @@ const StockCompareModal: React.FC<StockCompareModalProps> = ({
|
||||
<Td isNumeric color={diffColor} fontSize="sm">
|
||||
{diff !== null ? (
|
||||
<HStack spacing={1} justify="flex-end">
|
||||
{diff > 0 && <ArrowUpIcon boxSize={3} />}
|
||||
{diff < 0 && <ArrowDownIcon boxSize={3} />}
|
||||
{diff > 0 && <ArrowUp size={12} />}
|
||||
{diff < 0 && <ArrowDown size={12} />}
|
||||
<Text>
|
||||
{metric.format === 'percent'
|
||||
? `${Math.abs(diff).toFixed(2)}pp`
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// 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 配置
|
||||
* @type {Array<{key: string, name: string, icon: React.ComponentType}>}
|
||||
*/
|
||||
export const COMPANY_TABS = [
|
||||
{ key: 'overview', name: '公司档案', icon: FaInfoCircle },
|
||||
{ key: 'analysis', name: '深度分析', icon: FaBrain },
|
||||
{ key: 'market', name: '股票行情', icon: FaChartLine },
|
||||
{ key: 'financial', name: '财务全景', icon: FaMoneyBillWave },
|
||||
{ key: 'forecast', name: '盈利预测', icon: FaChartBar },
|
||||
{ key: 'tracking', name: '动态跟踪', icon: FaNewspaper },
|
||||
{ key: 'overview', name: '公司档案', icon: Info },
|
||||
{ key: 'analysis', name: '深度分析', icon: Brain },
|
||||
{ key: 'market', name: '股票行情', icon: LineChart },
|
||||
{ key: 'financial', name: '财务全景', icon: Banknote },
|
||||
{ key: 'forecast', name: '盈利预测', icon: BarChart2 },
|
||||
{ key: 'tracking', name: '动态跟踪', icon: Newspaper },
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
|
||||
import type { ComponentType, ReactNode } from 'react';
|
||||
import type { IconType } from 'react-icons';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
|
||||
// ============================================
|
||||
@@ -34,7 +33,7 @@ export interface CompanyTheme {
|
||||
export interface TabConfig {
|
||||
key: string;
|
||||
name: string;
|
||||
icon: LucideIcon | IconType | ComponentType;
|
||||
icon: LucideIcon | ComponentType;
|
||||
component: ComponentType<TabComponentProps>;
|
||||
/** 自定义 Suspense fallback(如骨架屏) */
|
||||
fallback?: ReactNode;
|
||||
|
||||
Reference in New Issue
Block a user