style(BusinessInfoPanel): 优化工商信息模块 UI

- 使用玻璃态卡片布局(Glassmorphism)
- 添加图标增强视觉效果
- 信息行使用悬停效果
- 服务机构使用独立卡片展示
- 主营业务/经营范围两列布局
- 统一 FUI 黑金主题风格

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-18 18:16:42 +08:00
parent 997724e0b1
commit 79572fcc98

View File

@@ -1,5 +1,5 @@
// src/views/Company/components/CompanyOverview/BasicInfoTab/components/BusinessInfoPanel.tsx // src/views/Company/components/CompanyOverview/BasicInfoTab/components/BusinessInfoPanel.tsx
// 工商信息 Tab Panel // 工商信息 Tab Panel - FUI 风格
import React from "react"; import React from "react";
import { import {
@@ -7,13 +7,21 @@ import {
VStack, VStack,
HStack, HStack,
Text, Text,
Heading,
SimpleGrid, SimpleGrid,
Divider,
Center, Center,
Code, Icon,
Spinner, Spinner,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import {
FaBuilding,
FaMapMarkerAlt,
FaIdCard,
FaUsers,
FaBalanceScale,
FaCalculator,
FaBriefcase,
FaFileAlt,
} from "react-icons/fa";
import { THEME } from "../config"; import { THEME } from "../config";
import { useBasicInfo } from "../../hooks/useBasicInfo"; import { useBasicInfo } from "../../hooks/useBasicInfo";
@@ -22,6 +30,139 @@ interface BusinessInfoPanelProps {
stockCode: string; stockCode: string;
} }
// 玻璃态卡片样式
const glassCardStyle = {
bg: "rgba(15, 18, 35, 0.6)",
borderRadius: "12px",
border: "1px solid rgba(212, 175, 55, 0.2)",
backdropFilter: "blur(8px)",
position: "relative" as const,
overflow: "hidden",
transition: "all 0.2s ease",
_hover: {
borderColor: "rgba(212, 175, 55, 0.4)",
bg: "rgba(15, 18, 35, 0.7)",
},
};
// 区块标题组件
const SectionTitle: React.FC<{ icon: React.ElementType; title: string }> = ({
icon,
title,
}) => (
<HStack spacing={2} mb={4}>
<Icon as={icon} color={THEME.gold} boxSize={4} />
<Text
fontSize="14px"
fontWeight="700"
color={THEME.gold}
textTransform="uppercase"
letterSpacing="0.05em"
>
{title}
</Text>
<Box flex={1} h="1px" bg={`linear-gradient(90deg, ${THEME.border}, transparent)`} />
</HStack>
);
// 信息行组件
const InfoRow: React.FC<{
icon?: React.ElementType;
label: string;
value: string | undefined;
isCode?: boolean;
isMultiline?: boolean;
}> = ({ icon, label, value, isCode, isMultiline }) => (
<HStack
w="full"
align={isMultiline ? "start" : "center"}
spacing={3}
py={2}
px={3}
borderRadius="8px"
bg="rgba(0, 0, 0, 0.2)"
_hover={{ bg: "rgba(212, 175, 55, 0.05)" }}
transition="all 0.15s ease"
>
{icon && <Icon as={icon} color={THEME.goldLight} boxSize={3.5} opacity={0.8} />}
<Text fontSize="13px" color={THEME.textSecondary} minW="70px" flexShrink={0}>
{label}
</Text>
{isCode ? (
<Text
fontSize="12px"
fontFamily="mono"
bg="rgba(212, 175, 55, 0.15)"
color={THEME.goldLight}
px={2}
py={0.5}
borderRadius="4px"
letterSpacing="0.05em"
>
{value || "-"}
</Text>
) : (
<Text
fontSize="13px"
color={THEME.textPrimary}
fontWeight="500"
noOfLines={isMultiline ? 2 : 1}
flex={1}
>
{value || "-"}
</Text>
)}
</HStack>
);
// 服务机构卡片
const ServiceCard: React.FC<{
icon: React.ElementType;
label: string;
value: string | undefined;
}> = ({ icon, label, value }) => (
<Box
p={4}
borderRadius="10px"
bg="rgba(0, 0, 0, 0.2)"
border="1px solid rgba(212, 175, 55, 0.1)"
_hover={{ borderColor: "rgba(212, 175, 55, 0.25)" }}
transition="all 0.15s ease"
>
<HStack spacing={2} mb={2}>
<Icon as={icon} color={THEME.goldLight} boxSize={3.5} />
<Text fontSize="12px" color={THEME.textSecondary}>
{label}
</Text>
</HStack>
<Text fontSize="13px" color={THEME.textPrimary} fontWeight="500" noOfLines={2}>
{value || "-"}
</Text>
</Box>
);
// 文本区块组件
const TextSection: React.FC<{
icon: React.ElementType;
title: string;
content: string | undefined;
}> = ({ icon, title, content }) => (
<Box {...glassCardStyle} p={4}>
<SectionTitle icon={icon} title={title} />
<Text
fontSize="13px"
lineHeight="1.8"
color={THEME.textSecondary}
sx={{
textIndent: "2em",
textAlign: "justify",
}}
>
{content || "暂无信息"}
</Text>
</Box>
);
const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode }) => { const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode }) => {
const { basicInfo, loading } = useBasicInfo(stockCode); const { basicInfo, loading } = useBasicInfo(stockCode);
@@ -43,77 +184,69 @@ const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode }) => {
return ( return (
<VStack spacing={4} align="stretch"> <VStack spacing={4} align="stretch">
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={6}> {/* 上半部分:工商信息 + 服务机构 */}
<Box> <SimpleGrid columns={{ base: 1, lg: 2 }} spacing={4}>
<Heading size="sm" mb={3} color={THEME.textPrimary}></Heading> {/* 工商信息卡片 */}
<VStack align="start" spacing={2}> <Box {...glassCardStyle} p={4}>
<HStack w="full"> <SectionTitle icon={FaBuilding} title="工商信息" />
<Text fontSize="sm" color={THEME.textSecondary} minW="80px"> <VStack spacing={2} align="stretch">
<InfoRow
</Text> icon={FaIdCard}
<Code fontSize="xs" bg={THEME.tableHoverBg} color={THEME.goldLight}> label="信用代码"
{basicInfo.credit_code} value={basicInfo.credit_code}
</Code> isCode
</HStack> />
<HStack w="full"> <InfoRow
<Text fontSize="sm" color={THEME.textSecondary} minW="80px"> icon={FaUsers}
label="公司规模"
</Text> value={basicInfo.company_size}
<Text fontSize="sm" color={THEME.textPrimary}>{basicInfo.company_size}</Text> />
</HStack> <InfoRow
<HStack w="full" align="start"> icon={FaMapMarkerAlt}
<Text fontSize="sm" color={THEME.textSecondary} minW="80px"> label="注册地址"
value={basicInfo.reg_address}
</Text> isMultiline
<Text fontSize="sm" noOfLines={2} color={THEME.textPrimary}> />
{basicInfo.reg_address} <InfoRow
</Text> icon={FaMapMarkerAlt}
</HStack> label="办公地址"
<HStack w="full" align="start"> value={basicInfo.office_address}
<Text fontSize="sm" color={THEME.textSecondary} minW="80px"> isMultiline
/>
</Text>
<Text fontSize="sm" noOfLines={2} color={THEME.textPrimary}>
{basicInfo.office_address}
</Text>
</HStack>
</VStack> </VStack>
</Box> </Box>
<Box> {/* 服务机构卡片 */}
<Heading size="sm" mb={3} color={THEME.textPrimary}></Heading> <Box {...glassCardStyle} p={4}>
<VStack align="start" spacing={2}> <SectionTitle icon={FaBalanceScale} title="服务机构" />
<Box> <VStack spacing={3} align="stretch">
<Text fontSize="sm" color={THEME.textSecondary}></Text> <ServiceCard
<Text fontSize="sm" fontWeight="medium" color={THEME.textPrimary}> icon={FaCalculator}
{basicInfo.accounting_firm} label="会计师事务所"
</Text> value={basicInfo.accounting_firm}
</Box> />
<Box> <ServiceCard
<Text fontSize="sm" color={THEME.textSecondary}></Text> icon={FaBalanceScale}
<Text fontSize="sm" fontWeight="medium" color={THEME.textPrimary}> label="律师事务所"
{basicInfo.law_firm} value={basicInfo.law_firm}
</Text> />
</Box>
</VStack> </VStack>
</Box> </Box>
</SimpleGrid> </SimpleGrid>
<Divider borderColor={THEME.border} /> {/* 下半部分:主营业务 + 经营范围 */}
<SimpleGrid columns={{ base: 1, lg: 2 }} spacing={4}>
<Box> <TextSection
<Heading size="sm" mb={3} color={THEME.textPrimary}></Heading> icon={FaBriefcase}
<Text fontSize="sm" lineHeight="tall" color={THEME.textSecondary}> title="主营业务"
{basicInfo.main_business} content={basicInfo.main_business}
</Text> />
</Box> <TextSection
icon={FaFileAlt}
<Box> title="经营范围"
<Heading size="sm" mb={3} color={THEME.textPrimary}></Heading> content={basicInfo.business_scope}
<Text fontSize="sm" lineHeight="tall" color={THEME.textSecondary}> />
{basicInfo.business_scope} </SimpleGrid>
</Text>
</Box>
</VStack> </VStack>
); );
}; };