Merge branch 'feature_bugfix/251201_vf_h5_ui' into feature_bugfix/251201_py_h5_ui
* feature_bugfix/251201_vf_h5_ui: (31 commits)
fix: CompactSearchBox 股票选择和行业筛选优化
fix: stocks 字段支持对象格式 {code, name}
refactor: EventDetailCard 重命名为 EventCard,支持多变体模式
fix: UI调试
fix: 修复 key 重复
feat: 修复数据结构访问
refactor: EventFormModal 从 Chakra UI 迁移到 Ant Design
fix: 适配 watchlist 新数据结构
refactor: 股票数据管理迁移到 Redux,新增类型化 Hooks
fix: 修复ts报错
feat: 添加mock数据
style: EventFormModal 和 InvestmentCalendar H5 响应式适配
style: EventFormModal 和 InvestmentCalendar H5 响应式适配
fix: 补充 investment.ts 类型定义变更(df90fc2 遗漏)
feat: h5隐藏日历视图
perf: EventPanel 性能优化,EventDetailCard H5适配,清理冗余类型
refactor: CalendarPanel 性能优化,统一弹窗状态管理
feat: 添加"我的计划"和"我的复盘"的 mock 数据
refactor: CalendarPanel 性能优化,统一弹窗状态管理
feat: 新增 EventDetailModal 和 EventEmptyState 组件 用于展示某一天的所有投资事件
...
This commit is contained in:
@@ -434,13 +434,8 @@ export const accountHandlers = [
|
||||
http.get('/api/account/calendar/events', async ({ request }) => {
|
||||
await delay(NETWORK_DELAY);
|
||||
|
||||
const currentUser = getCurrentUser();
|
||||
if (!currentUser) {
|
||||
return HttpResponse.json(
|
||||
{ success: false, error: '未登录' },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
// Mock 模式下允许无登录访问,使用默认用户 id: 1
|
||||
const currentUser = getCurrentUser() || { id: 1 };
|
||||
|
||||
const url = new URL(request.url);
|
||||
const startDate = url.searchParams.get('start_date');
|
||||
@@ -455,8 +450,8 @@ export const accountHandlers = [
|
||||
}
|
||||
|
||||
// 2. 获取投资计划和复盘,转换为日历事件格式
|
||||
// Mock 模式:不过滤 user_id,显示所有 mock 数据(方便开发测试)
|
||||
const investmentPlansAsEvents = mockInvestmentPlans
|
||||
.filter(plan => plan.user_id === currentUser.id)
|
||||
.map(plan => ({
|
||||
id: plan.id,
|
||||
user_id: plan.user_id,
|
||||
@@ -489,10 +484,13 @@ export const accountHandlers = [
|
||||
});
|
||||
}
|
||||
|
||||
console.log('[Mock] 合并后的日历事件数量:', {
|
||||
console.log('[Mock] 日历事件详情:', {
|
||||
currentUserId: currentUser.id,
|
||||
calendarEvents: calendarEvents.length,
|
||||
investmentPlansAsEvents: investmentPlansAsEvents.length,
|
||||
total: filteredEvents.length
|
||||
total: filteredEvents.length,
|
||||
plansCount: filteredEvents.filter(e => e.type === 'plan').length,
|
||||
reviewsCount: filteredEvents.filter(e => e.type === 'review').length
|
||||
});
|
||||
|
||||
return HttpResponse.json({
|
||||
|
||||
@@ -123,12 +123,12 @@ const generateStockList = () => {
|
||||
|
||||
// 股票相关的 Handlers
|
||||
export const stockHandlers = [
|
||||
// 搜索股票(个股中心页面使用)
|
||||
// 搜索股票(个股中心页面使用)- 支持模糊搜索
|
||||
http.get('/api/stocks/search', async ({ request }) => {
|
||||
await delay(200);
|
||||
|
||||
const url = new URL(request.url);
|
||||
const query = url.searchParams.get('q') || '';
|
||||
const query = (url.searchParams.get('q') || '').toLowerCase().trim();
|
||||
const limit = parseInt(url.searchParams.get('limit') || '10');
|
||||
|
||||
console.log('[Mock Stock] 搜索股票:', { query, limit });
|
||||
@@ -136,22 +136,44 @@ export const stockHandlers = [
|
||||
const stocks = generateStockList();
|
||||
|
||||
// 如果没有搜索词,返回空结果
|
||||
if (!query.trim()) {
|
||||
if (!query) {
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: []
|
||||
});
|
||||
}
|
||||
|
||||
// 过滤匹配的股票
|
||||
const results = stocks.filter(s =>
|
||||
s.code.includes(query) || s.name.includes(query)
|
||||
).slice(0, limit);
|
||||
// 模糊搜索:代码 + 名称(不区分大小写)
|
||||
const results = stocks.filter(s => {
|
||||
const code = s.code.toLowerCase();
|
||||
const name = s.name.toLowerCase();
|
||||
return code.includes(query) || name.includes(query);
|
||||
});
|
||||
|
||||
// 按相关性排序:完全匹配 > 开头匹配 > 包含匹配
|
||||
results.sort((a, b) => {
|
||||
const aCode = a.code.toLowerCase();
|
||||
const bCode = b.code.toLowerCase();
|
||||
const aName = a.name.toLowerCase();
|
||||
const bName = b.name.toLowerCase();
|
||||
|
||||
// 计算匹配分数
|
||||
const getScore = (code, name) => {
|
||||
if (code === query || name === query) return 100; // 完全匹配
|
||||
if (code.startsWith(query)) return 80; // 代码开头
|
||||
if (name.startsWith(query)) return 60; // 名称开头
|
||||
if (code.includes(query)) return 40; // 代码包含
|
||||
if (name.includes(query)) return 20; // 名称包含
|
||||
return 0;
|
||||
};
|
||||
|
||||
return getScore(bCode, bName) - getScore(aCode, aName);
|
||||
});
|
||||
|
||||
// 返回格式化数据
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: results.map(s => ({
|
||||
data: results.slice(0, limit).map(s => ({
|
||||
stock_code: s.code,
|
||||
stock_name: s.name,
|
||||
market: s.code.startsWith('6') ? 'SH' : 'SZ',
|
||||
|
||||
Reference in New Issue
Block a user