// 简易版公司盈利预测报表视图 import React, { useState, useEffect } from 'react'; import { Box, Flex, Input, Button, SimpleGrid, HStack, Text, Skeleton, VStack } from '@chakra-ui/react'; import { Card, CardHeader, CardBody, Heading, Table, Thead, Tr, Th, Tbody, Td, Tag } from '@chakra-ui/react'; import { RepeatIcon } from '@chakra-ui/icons'; import ReactECharts from 'echarts-for-react'; import { stockService } from '../../services/eventService'; const ForecastReport = ({ stockCode: propStockCode }) => { const [code, setCode] = useState(propStockCode || '600000'); const [data, setData] = useState(null); const [loading, setLoading] = useState(false); const load = async () => { if (!code) return; setLoading(true); try { const resp = await stockService.getForecastReport(code); if (resp && resp.success) setData(resp.data); } finally { setLoading(false); } }; // 监听props中的stockCode变化 useEffect(() => { if (propStockCode && propStockCode !== code) { setCode(propStockCode); } }, [propStockCode]); // 加载数据 useEffect(() => { if (code) { load(); } }, [code]); const years = data?.detail_table?.years || []; const colors = ['#805AD5', '#38B2AC', '#F6AD55', '#63B3ED', '#E53E3E', '#10B981']; const incomeProfitOption = data ? { color: [colors[0], colors[4]], tooltip: { trigger: 'axis' }, legend: { data: ['营业总收入(百万元)', '归母净利润(百万元)'] }, grid: { left: 40, right: 20, bottom: 40, top: 30 }, xAxis: { type: 'category', data: data.income_profit_trend.years, axisLabel: { rotate: 30 } }, yAxis: [ { type: 'value', name: '收入(百万元)' }, { type: 'value', name: '利润(百万元)' } ], series: [ { name: '营业总收入(百万元)', type: 'line', data: data.income_profit_trend.income, smooth: true, lineStyle: { width: 2 }, areaStyle: { opacity: 0.08 } }, { name: '归母净利润(百万元)', type: 'line', yAxisIndex: 1, data: data.income_profit_trend.profit, smooth: true, lineStyle: { width: 2 } } ] } : {}; const growthOption = data ? { color: [colors[2]], tooltip: { trigger: 'axis' }, grid: { left: 40, right: 20, bottom: 40, top: 30 }, xAxis: { type: 'category', data: data.growth_bars.years, axisLabel: { rotate: 30 } }, yAxis: { type: 'value', axisLabel: { formatter: '{value}%' } }, series: [ { name: '营收增长率(%)', type: 'bar', data: data.growth_bars.revenue_growth_pct, itemStyle: { color: (params) => params.value >= 0 ? '#E53E3E' : '#10B981' } } ] } : {}; const epsOption = data ? { color: [colors[3]], tooltip: { trigger: 'axis' }, grid: { left: 40, right: 20, bottom: 40, top: 30 }, xAxis: { type: 'category', data: data.eps_trend.years, axisLabel: { rotate: 30 } }, yAxis: { type: 'value', name: '元/股' }, series: [ { name: 'EPS(稀释)', type: 'line', data: data.eps_trend.eps, smooth: true, areaStyle: { opacity: 0.1 }, lineStyle: { width: 2 } } ] } : {}; const pePegOption = data ? { color: [colors[0], colors[1]], tooltip: { trigger: 'axis' }, legend: { data: ['PE', 'PEG'] }, grid: { left: 40, right: 40, bottom: 40, top: 30 }, xAxis: { type: 'category', data: data.pe_peg_axes.years, axisLabel: { rotate: 30 } }, yAxis: [ { type: 'value', name: 'PE(倍)' }, { type: 'value', name: 'PEG' } ], series: [ { name: 'PE', type: 'line', data: data.pe_peg_axes.pe, smooth: true }, { name: 'PEG', type: 'line', yAxisIndex: 1, data: data.pe_peg_axes.peg, smooth: true } ] } : {}; return ( 盈利预测报表 {loading && !data && ( {[1,2,3,4].map(i => ( ))} )} {data && ( 营业收入与净利润趋势 增长率分析 EPS 趋势 PE 与 PEG 分析 )} {data && ( 详细数据表格 {years.map(y => )} {data.detail_table.rows.map((row, idx) => ( {years.map(y => )} ))}
关键指标{y}
{row['指标']}{row[y] ?? '-'}
)}
); }; export default ForecastReport;