diff --git a/src/views/Company/components/CompanyHeader/constants.ts b/src/views/Company/components/CompanyHeader/constants.ts
new file mode 100644
index 00000000..07254c11
--- /dev/null
+++ b/src/views/Company/components/CompanyHeader/constants.ts
@@ -0,0 +1,70 @@
+/**
+ * CompanyHeader 组件常量
+ */
+
+import { FUI_COLORS, FUI_GLOW, FUI_ANIMATION } from '../../theme/fui';
+
+/** 下拉菜单样式 */
+export const DROPDOWN_STYLE: React.CSSProperties = {
+ backgroundColor: FUI_COLORS.bg.elevated,
+ borderRadius: '6px',
+ border: `1px solid ${FUI_COLORS.gold[400]}`,
+ boxShadow: '0 4px 20px rgba(0, 0, 0, 0.5)',
+};
+
+/** 搜索图标样式 */
+export const SEARCH_ICON_STYLE: React.CSSProperties = {
+ color: FUI_COLORS.gold[400],
+ fontSize: 16,
+ cursor: 'pointer',
+};
+
+/** 输入框样式 */
+export const INPUT_STYLE: React.CSSProperties = {
+ backgroundColor: 'transparent',
+ borderColor: FUI_COLORS.gold[400],
+ borderRadius: 6,
+ height: 44,
+ color: FUI_COLORS.gold[400],
+};
+
+/** AutoComplete 宽度样式 */
+export const AUTOCOMPLETE_STYLE: React.CSSProperties = {
+ width: 320,
+};
+
+/** 搜索框容器样式 */
+export const SEARCH_BOX_SX = {
+ '.ant-select': {
+ width: '320px !important',
+ },
+ '.ant-input-affix-wrapper': {
+ backgroundColor: 'transparent !important',
+ borderColor: `${FUI_COLORS.gold[400]} !important`,
+ borderWidth: '1px !important',
+ borderRadius: '6px !important',
+ height: '44px !important',
+ padding: '0 12px !important',
+ transition: `all ${FUI_ANIMATION.duration.fast} ${FUI_ANIMATION.easing.default}`,
+ '&:hover': {
+ borderColor: `${FUI_COLORS.gold[300]} !important`,
+ boxShadow: FUI_GLOW.gold.sm,
+ },
+ '&:focus-within, &.ant-input-affix-wrapper-focused': {
+ borderColor: `${FUI_COLORS.gold[300]} !important`,
+ boxShadow: `${FUI_GLOW.gold.md} !important`,
+ },
+ },
+ '.ant-input': {
+ backgroundColor: 'transparent !important',
+ color: `${FUI_COLORS.gold[400]} !important`,
+ fontSize: '14px !important',
+ '&::placeholder': {
+ color: `${FUI_COLORS.gold[400]} !important`,
+ opacity: '0.7 !important',
+ },
+ },
+ '.ant-input-prefix': {
+ marginRight: '8px !important',
+ },
+} as const;
diff --git a/src/views/Company/components/CompanyHeader/index.tsx b/src/views/Company/components/CompanyHeader/index.tsx
index 05e2bc9f..6e8f7d01 100644
--- a/src/views/Company/components/CompanyHeader/index.tsx
+++ b/src/views/Company/components/CompanyHeader/index.tsx
@@ -1,71 +1,41 @@
/**
* Company 页面顶部搜索栏组件 - FUI 科幻风格
- *
- * 设计特点:
- * - 左侧固定标题 + 副标题
- * - 右侧简洁搜索框
- * - 深色背景 + 金色强调色
*/
import React, { memo, useMemo, useCallback, useState } from 'react';
-import {
- Box,
- Flex,
- HStack,
- VStack,
- Text,
-} from '@chakra-ui/react';
+import { Box, Flex, HStack, VStack, Text } from '@chakra-ui/react';
import { AutoComplete, Input, Spin } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import { useStockSearch } from '@hooks/useStockSearch';
import { THEME } from '../../config';
-import { FUI_COLORS, FUI_GLOW, FUI_ANIMATION, FUI_GLASS } from '../../theme/fui';
+import { FUI_COLORS, FUI_GLOW } from '../../theme/fui';
import type { CompanyHeaderProps, StockSearchResult } from '../../types';
+import {
+ DROPDOWN_STYLE,
+ SEARCH_ICON_STYLE,
+ INPUT_STYLE,
+ AUTOCOMPLETE_STYLE,
+ SEARCH_BOX_SX,
+} from './constants';
-/**
- * 页面标题组件
- */
-const PageTitle = memo(() => (
-
-
- 个股详情
-
-
- 查看股票实时行情、财务数据和盈利预测
-
-
-));
+// ============================================
+// SearchBox 子组件
+// ============================================
-PageTitle.displayName = 'PageTitle';
-
-/**
- * 搜索框组件(状态自管理,减少父组件重渲染)
- */
const SearchBox = memo<{
- stockCode: string;
onStockChange: (value: string) => void;
-}>(({
- stockCode,
- onStockChange,
-}) => {
- // 输入状态 - 默认为空,显示 placeholder
+}>(({ onStockChange }) => {
const [inputCode, setInputCode] = useState('');
- // 股票搜索 Hook
- const searchHook = useStockSearch({
+ const {
+ searchResults,
+ isSearching,
+ handleSearch: doSearch,
+ clearSearch,
+ } = useStockSearch({
limit: 10,
debounceMs: 300,
- onSearch: () => {}, // 空回调,追踪在父组件处理
+ onSearch: () => {},
}) as {
searchResults: StockSearchResult[];
isSearching: boolean;
@@ -73,11 +43,8 @@ const SearchBox = memo<{
clearSearch: () => void;
};
- const { searchResults, isSearching, handleSearch: doSearch, clearSearch } = searchHook;
-
- // 转换为 AutoComplete options
- const stockOptions = useMemo(() => {
- return searchResults.map((stock: StockSearchResult) => ({
+ const stockOptions = useMemo(() => (
+ searchResults.map((stock: StockSearchResult) => ({
value: stock.stock_code,
label: (
@@ -92,62 +59,31 @@ const SearchBox = memo<{
)}
),
- }));
- }, [searchResults]);
+ }))
+ ), [searchResults]);
+
+ const handleSearch = useCallback(() => {
+ if (inputCode) {
+ onStockChange(inputCode);
+ }
+ }, [inputCode, onStockChange]);
- // 选中股票
const handleSelect = useCallback((value: string) => {
clearSearch();
setInputCode(value);
- if (value !== stockCode) {
- onStockChange(value);
- }
- }, [clearSearch, stockCode, onStockChange]);
+ onStockChange(value);
+ }, [clearSearch, onStockChange]);
- // 键盘事件 - 回车搜索
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
- if (e.key === 'Enter' && inputCode && inputCode !== stockCode) {
- onStockChange(inputCode);
- }
- }, [inputCode, stockCode, onStockChange]);
+ if (e.key === 'Enter') handleSearch();
+ }, [handleSearch]);
+
+ const searchIcon = useMemo(() => (
+
+ ), [handleSearch]);
return (
-
+
: null}
>
}
+ prefix={searchIcon}
onKeyDown={handleKeyDown}
- style={{
- backgroundColor: 'transparent',
- borderColor: FUI_COLORS.gold[400],
- borderRadius: 6,
- height: 44,
- color: FUI_COLORS.gold[400],
- }}
+ style={INPUT_STYLE}
/>
@@ -183,42 +108,45 @@ const SearchBox = memo<{
SearchBox.displayName = 'SearchBox';
-/**
- * Company 页面顶部组件
- */
-const CompanyHeader: React.FC = memo(({
- stockCode,
- onStockChange,
-}) => {
- return (
-
-
- {/* 左侧:页面标题 */}
-
+// ============================================
+// CompanyHeader 主组件
+// ============================================
- {/* 右侧:搜索框 */}
-
-
-
- );
-});
+const CompanyHeader: React.FC = memo(({ onStockChange }) => (
+
+
+
+
+ 个股详情
+
+
+ 查看股票实时行情、财务数据和盈利预测
+
+
+
+
+
+));
CompanyHeader.displayName = 'CompanyHeader';
diff --git a/src/views/Company/index.tsx b/src/views/Company/index.tsx
index 0430e004..431915bb 100644
--- a/src/views/Company/index.tsx
+++ b/src/views/Company/index.tsx
@@ -354,16 +354,12 @@ const CompanyIndex: React.FC = () => {
CompanyHeader 组件
负责展示:
- 左侧:页面标题和副标题
- - 右侧:股票搜索框 (支持代码/名称搜索)
+ - 右侧:股票搜索框 (支持代码/名称搜索,点击图标可搜索)
Props 说明:
- - stockCode: 当前股票代码,用于搜索框默认值
- onStockChange: 股票切换回调
*/}
-
+
{/* ========================================
diff --git a/src/views/Company/types.ts b/src/views/Company/types.ts
index b2f1787a..19d36e86 100644
--- a/src/views/Company/types.ts
+++ b/src/views/Company/types.ts
@@ -110,7 +110,6 @@ export interface UseCompanyDataReturn {
// ============================================
export interface CompanyHeaderProps {
- stockCode: string;
onStockChange: (code: string) => void;
}