From 873adda1fd582aadfb8eeae5a75ff13301525c95 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Fri, 24 Oct 2025 17:43:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=82=A1=E7=A5=A8moc?= =?UTF-8?q?k=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mocks/handlers/index.js | 2 + src/mocks/handlers/stock.js | 143 ++++++++++++++ .../Community/components/EventFilters.js | 183 ------------------ 3 files changed, 145 insertions(+), 183 deletions(-) create mode 100644 src/mocks/handlers/stock.js delete mode 100644 src/views/Community/components/EventFilters.js diff --git a/src/mocks/handlers/index.js b/src/mocks/handlers/index.js index 4169d355..d751237f 100644 --- a/src/mocks/handlers/index.js +++ b/src/mocks/handlers/index.js @@ -8,6 +8,7 @@ import { eventHandlers } from './event'; import { paymentHandlers } from './payment'; import { industryHandlers } from './industry'; import { conceptHandlers } from './concept'; +import { stockHandlers } from './stock'; // 可以在这里添加更多的 handlers // import { userHandlers } from './user'; @@ -20,5 +21,6 @@ export const handlers = [ ...paymentHandlers, ...industryHandlers, ...conceptHandlers, + ...stockHandlers, // ...userHandlers, ]; diff --git a/src/mocks/handlers/stock.js b/src/mocks/handlers/stock.js new file mode 100644 index 00000000..e41bdd59 --- /dev/null +++ b/src/mocks/handlers/stock.js @@ -0,0 +1,143 @@ +// src/mocks/handlers/stock.js +// 股票相关的 Mock Handlers + +import { http, HttpResponse } from 'msw'; + +// 模拟延迟 +const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); + +// 生成A股主要股票数据(包含各大指数成分股) +const generateStockList = () => { + const stocks = [ + // 银行 + { code: '000001', name: '平安银行' }, + { code: '600000', name: '浦发银行' }, + { code: '600036', name: '招商银行' }, + { code: '601166', name: '兴业银行' }, + { code: '601169', name: '北京银行' }, + { code: '601288', name: '农业银行' }, + { code: '601328', name: '交通银行' }, + { code: '601398', name: '工商银行' }, + { code: '601818', name: '光大银行' }, + { code: '601939', name: '建设银行' }, + { code: '601998', name: '中信银行' }, + + // 证券 + { code: '600030', name: '中信证券' }, + { code: '600109', name: '国金证券' }, + { code: '600837', name: '海通证券' }, + { code: '600999', name: '招商证券' }, + { code: '601688', name: '华泰证券' }, + { code: '601901', name: '方正证券' }, + + // 保险 + { code: '601318', name: '中国平安' }, + { code: '601336', name: '新华保险' }, + { code: '601601', name: '中国太保' }, + { code: '601628', name: '中国人寿' }, + + // 白酒/食品饮料 + { code: '000568', name: '泸州老窖' }, + { code: '000596', name: '古井贡酒' }, + { code: '000858', name: '五粮液' }, + { code: '600519', name: '贵州茅台' }, + { code: '600600', name: '青岛啤酒' }, + { code: '600779', name: '水井坊' }, + { code: '603369', name: '今世缘' }, + + // 医药 + { code: '000538', name: '云南白药' }, + { code: '000661', name: '长春高新' }, + { code: '002422', name: '科伦药业' }, + { code: '002594', name: '比亚迪' }, + { code: '600276', name: '恒瑞医药' }, + { code: '600436', name: '片仔癀' }, + { code: '603259', name: '药明康德' }, + + // 科技/半导体 + { code: '000063', name: '中兴通讯' }, + { code: '000725', name: '京东方A' }, + { code: '002049', name: '紫光国微' }, + { code: '002415', name: '海康威视' }, + { code: '002475', name: '立讯精密' }, + { code: '600584', name: '长电科技' }, + { code: '600893', name: '航发动力' }, + { code: '603501', name: '韦尔股份' }, + + // 新能源/电力 + { code: '000002', name: '万科A' }, + { code: '002460', name: '赣锋锂业' }, + { code: '300750', name: '宁德时代' }, + { code: '600438', name: '通威股份' }, + { code: '601012', name: '隆基绿能' }, + { code: '601668', name: '中国建筑' }, + + // 汽车 + { code: '000625', name: '长安汽车' }, + { code: '600066', name: '宇通客车' }, + { code: '600104', name: '上汽集团' }, + { code: '601238', name: '广汽集团' }, + { code: '601633', name: '长城汽车' }, + + // 地产 + { code: '000002', name: '万科A' }, + { code: '000069', name: '华侨城A' }, + { code: '600340', name: '华夏幸福' }, + { code: '600606', name: '绿地控股' }, + + // 家电 + { code: '000333', name: '美的集团' }, + { code: '000651', name: '格力电器' }, + { code: '002032', name: '苏泊尔' }, + { code: '600690', name: '海尔智家' }, + + // 互联网/电商 + { code: '002024', name: '苏宁易购' }, + { code: '002074', name: '国轩高科' }, + { code: '300059', name: '东方财富' }, + + // 能源/化工 + { code: '600028', name: '中国石化' }, + { code: '600309', name: '万华化学' }, + { code: '600547', name: '山东黄金' }, + { code: '600585', name: '海螺水泥' }, + { code: '601088', name: '中国神华' }, + { code: '601857', name: '中国石油' }, + + // 电信/运营商 + { code: '600050', name: '中国联通' }, + { code: '600941', name: '中国移动' }, + { code: '601728', name: '中国电信' }, + + // 其他蓝筹 + { code: '600887', name: '伊利股份' }, + { code: '601111', name: '中国国航' }, + { code: '601390', name: '中国中铁' }, + { code: '601899', name: '紫金矿业' }, + { code: '603288', name: '海天味业' }, + ]; + + return stocks; +}; + +// 股票相关的 Handlers +export const stockHandlers = [ + // 获取所有股票列表 + http.get('/api/stocklist', async () => { + await delay(200); + + try { + const stocks = generateStockList(); + + console.log('[Mock Stock] 获取股票列表成功:', { count: stocks.length }); + + return HttpResponse.json(stocks); + } catch (error) { + console.error('[Mock Stock] 获取股票列表失败:', error); + return HttpResponse.json( + { error: '获取股票列表失败' }, + { status: 500 } + ); + } + }), +]; diff --git a/src/views/Community/components/EventFilters.js b/src/views/Community/components/EventFilters.js deleted file mode 100644 index 0f11422a..00000000 --- a/src/views/Community/components/EventFilters.js +++ /dev/null @@ -1,183 +0,0 @@ -// src/views/Community/components/EventFilters.js -import React, { useState, useEffect } from 'react'; -import { Card, Row, Col, DatePicker, Button, Select, Form, Cascader } from 'antd'; -import { FilterOutlined } from '@ant-design/icons'; -import moment from 'moment'; -import locale from 'antd/es/date-picker/locale/zh_CN'; -import { useIndustry } from '../../../contexts/IndustryContext'; -import { logger } from '../../../utils/logger'; - -const { RangePicker } = DatePicker; -const { Option } = Select; - -const EventFilters = ({ filters, onFilterChange, loading }) => { - const [form] = Form.useForm(); - - // 使用全局行业数据 - const { industryData, loading: industryLoading, loadIndustryData } = useIndustry(); - - // 初始化表单值 - useEffect(() => { - const initialValues = { - date_range: filters.date_range ? filters.date_range.split(' 至 ').map(d => moment(d)) : null, - sort: filters.sort, - importance: filters.importance, - industry_code: filters.industry_code ? filters.industry_code.split(',') : [] - }; - form.setFieldsValue(initialValues); - }, [filters, form]); - - // Cascader 获得焦点时确保数据已加载 - const handleCascaderFocus = async () => { - if (!industryData || industryData.length === 0) { - logger.debug('EventFilters', 'Cascader 获得焦点,触发数据加载'); - await loadIndustryData(); - } - }; - - const handleDateRangeChange = (dates) => { - if (dates && dates.length === 2) { - const dateRange = `${dates[0].format('YYYY-MM-DD')} 至 ${dates[1].format('YYYY-MM-DD')}`; - onFilterChange('date_range', dateRange); - } else { - onFilterChange('date_range', ''); - } - }; - - const handleSortChange = (value) => { - onFilterChange('sort', value); - }; - - const handleImportanceChange = (value) => { - onFilterChange('importance', value); - }; - - // 收集所有叶子节点的 value(递归) - const collectLeafValues = (node) => { - // 如果没有子节点,说明是叶子节点 - if (!node.children || node.children.length === 0) { - return [node.value]; - } - - // 有子节点,递归收集所有子节点的叶子节点 - let leafValues = []; - node.children.forEach(child => { - leafValues = leafValues.concat(collectLeafValues(child)); - }); - return leafValues; - }; - - // 根据级联路径找到对应的节点 - const findNodeByPath = (options, path) => { - let current = options; - let node = null; - - for (let i = 0; i < path.length; i++) { - node = current.find(item => item.value === path[i]); - if (!node) return null; - if (i < path.length - 1) { - current = node.children || []; - } - } - return node; - }; - - // 行业级联选择变化 - const handleIndustryChange = (value) => { - if (!value || value.length === 0) { - onFilterChange('industry_code', ''); - return; - } - - // 获取选中的节点 - const selectedNode = findNodeByPath(industryData || [], value); - - if (!selectedNode) { - // 如果找不到节点,使用最后一个值 - onFilterChange('industry_code', value[value.length - 1]); - return; - } - - // 如果选中的节点有子节点,收集所有叶子节点的 value - // 这样可以匹配该级别下的所有事件 - if (selectedNode.children && selectedNode.children.length > 0) { - const leafValues = collectLeafValues(selectedNode); - onFilterChange('industry_code', leafValues.join(',')); - } else { - // 叶子节点,直接使用该 value - onFilterChange('industry_code', selectedNode.value); - } - }; - - return ( - -
- - - - - - - - - - - - - - - - - - - - - - - {/* 行业分类级联选择器 - 替换原来的 5 个独立 Select */} - - - - - path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1) - }} - disabled={loading || industryLoading} - loading={industryLoading} - allowClear - style={{ width: '100%' }} - displayRender={(labels) => labels.join(' / ')} - /> - - - -
-
- ); -}; - -export default EventFilters; \ No newline at end of file