Merge branch 'feature_bugfix/251201_vf_h5_ui' into feature_bugfix/251201_py_h5_ui
* feature_bugfix/251201_vf_h5_ui: fix: 事件详情唔错页面UI调整 fix: 调整事件详情页面 feat: 事件详情页 URL ID 加密,防止用户遍历 style: 首页整体尺寸缩小约 67% fix: 调整客服弹窗 将 PC 端聊天窗口从 380×640 调整为 450×750。 H5 端:宽度占满,高度根据宽度等比缩放 fix: ICP 备案号现在可以点击跳转到 https://beian.miit.gov.cn/ feat: 田间mock数据 feat: 个股中心复用 TradeDatePicker 日期选择器组件 feat: 概念中心历史时间轴弹窗UI调整 feat: 提取日历选择器组件 refactor: 提取 ConceptStocksModal 为通用组件,统一概念中心和个股中心弹窗 refactor: 事件详情弹窗改用 Drawer 组件从底部弹出 fix: 在 viewport meta 标签中添加了 viewport-fit=cover,这样浏览器会将页面内容延伸到曲面屏边缘,同时启用 safe-area-inset-* CSS 环境变量 在普通设备上保持至少 16px 的右侧内边距 在华为 MATE70 PRO 等曲面屏设备上,使用系统提供的安全区域值,避免右侧导航被遮挡 fix: 概念中心H5端卡片尺寸优化,一屏可显示更多内容 fix: 修复自选股添加失败 405 错误 fix: H5端热门事件移除Tooltip避免黑色悬浮框无法消除
This commit is contained in:
@@ -1,36 +1,8 @@
|
||||
.event-detail-modal {
|
||||
top: 20% !important;
|
||||
margin: 0 auto !important;
|
||||
padding-bottom: 0 !important;
|
||||
|
||||
.ant-modal-content {
|
||||
border-radius: 24px !important;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
// 标题样式 - 深色文字(白色背景)
|
||||
.ant-modal-title {
|
||||
// 事件详情抽屉样式(从底部弹出)
|
||||
// 注意:大部分样式已在 TSX 的 styles 属性中配置,这里只保留必要的覆盖
|
||||
.event-detail-drawer {
|
||||
// 标题样式
|
||||
.ant-drawer-title {
|
||||
color: #1A202C;
|
||||
}
|
||||
|
||||
// 关闭按钮样式 - 深色(白色背景)
|
||||
.ant-modal-close {
|
||||
color: #4A5568;
|
||||
|
||||
&:hover {
|
||||
color: #1A202C;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 自底向上滑入动画
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
transform: translateY(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Modal } from 'antd';
|
||||
import { Drawer } from 'antd';
|
||||
import { CloseOutlined } from '@ant-design/icons';
|
||||
import { selectIsMobile } from '@store/slices/deviceSlice';
|
||||
import DynamicNewsDetailPanel from './DynamicNewsDetail/DynamicNewsDetailPanel';
|
||||
import './EventDetailModal.less';
|
||||
@@ -15,7 +16,7 @@ interface EventDetailModalProps {
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件详情弹窗组件
|
||||
* 事件详情抽屉组件(从底部弹出)
|
||||
*/
|
||||
const EventDetailModal: React.FC<EventDetailModalProps> = ({
|
||||
open,
|
||||
@@ -25,23 +26,35 @@ const EventDetailModal: React.FC<EventDetailModalProps> = ({
|
||||
const isMobile = useSelector(selectIsMobile);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
<Drawer
|
||||
open={open}
|
||||
onCancel={onClose}
|
||||
footer={null}
|
||||
onClose={onClose}
|
||||
placement="bottom"
|
||||
height={isMobile ? 'calc(100vh - 60px)' : 'calc(100vh - 100px)'}
|
||||
width={isMobile ? '100%' : '70vw'}
|
||||
title={event?.title || '事件详情'}
|
||||
width='100vw'
|
||||
destroyOnClose
|
||||
className="event-detail-modal"
|
||||
destroyOnHidden
|
||||
rootClassName="event-detail-drawer"
|
||||
closeIcon={null}
|
||||
extra={
|
||||
<CloseOutlined
|
||||
onClick={onClose}
|
||||
style={{ cursor: 'pointer', fontSize: 16, color: '#4A5568' }}
|
||||
/>
|
||||
}
|
||||
styles={{
|
||||
mask: { background: 'transparent' },
|
||||
content: { borderRadius: 24, padding: 0, maxWidth: 1400, background: 'transparent', margin: '0 auto', maxHeight: '80vh', display: 'flex', flexDirection: 'column' },
|
||||
header: { background: '#FFFFFF', borderBottom: '1px solid #E2E8F0', padding: '16px 24px', borderRadius: '24px 24px 0 0', margin: 0, flexShrink: 0 },
|
||||
body: { padding: 0, overflowY: 'auto', flex: 1 },
|
||||
wrapper: isMobile ? {} : {
|
||||
maxWidth: 1400,
|
||||
margin: '0 auto',
|
||||
borderRadius: '16px 16px 0 0',
|
||||
},
|
||||
content: { borderRadius: '16px 16px 0 0' },
|
||||
header: { background: '#FFFFFF', borderBottom: '1px solid #E2E8F0', padding: '16px 24px' },
|
||||
body: { padding: 0, background: '#FFFFFF' },
|
||||
}}
|
||||
>
|
||||
{event && <DynamicNewsDetailPanel event={event} showHeader={false} />}
|
||||
</Modal>
|
||||
</Drawer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Card, Badge, Tag, Empty, Carousel, Tooltip } from 'antd';
|
||||
import { ArrowUpOutlined, ArrowDownOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons';
|
||||
import { useDisclosure } from '@chakra-ui/react';
|
||||
import { useDisclosure, useBreakpointValue } from '@chakra-ui/react';
|
||||
import EventDetailModal from './EventDetailModal';
|
||||
import dayjs from 'dayjs';
|
||||
import './HotEvents.css';
|
||||
@@ -31,6 +31,8 @@ const HotEvents = ({ events, onPageChange, onEventClick }) => {
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
const { isOpen: isModalOpen, onOpen: onModalOpen, onClose: onModalClose } = useDisclosure();
|
||||
const [modalEvent, setModalEvent] = useState(null);
|
||||
// H5 端不显示 Tooltip(避免触摸触发后无法消除的黑色悬浮框)
|
||||
const isMobile = useBreakpointValue({ base: true, md: false });
|
||||
|
||||
const renderPriceChange = (value) => {
|
||||
if (value === null || value === undefined) {
|
||||
@@ -154,21 +156,33 @@ const HotEvents = ({ events, onPageChange, onEventClick }) => {
|
||||
>
|
||||
{/* Custom layout without Card.Meta */}
|
||||
<div className="event-header">
|
||||
<Tooltip title={event.title}>
|
||||
{isMobile ? (
|
||||
<span className="event-title">
|
||||
{event.title}
|
||||
</span>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Tooltip title={event.title}>
|
||||
<span className="event-title">
|
||||
{event.title}
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
<span className="event-tag">
|
||||
{renderPriceChange(event.related_avg_chg)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Tooltip title={event.description}>
|
||||
{isMobile ? (
|
||||
<div className="event-description">
|
||||
{event.description}
|
||||
</div>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Tooltip title={event.description}>
|
||||
<div className="event-description">
|
||||
{event.description}
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<div className="event-footer">
|
||||
<span className="creator">{event.creator?.username || 'Anonymous'}</span>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useSearchParams } from 'react-router-dom';
|
||||
import { logger } from '../../../utils/logger';
|
||||
import { usePostHogTrack } from '../../../hooks/usePostHogRedux';
|
||||
import { RETENTION_EVENTS } from '../../../lib/constants';
|
||||
import { getEventDetailUrl } from '@/utils/idEncoder';
|
||||
|
||||
/**
|
||||
* 事件筛选逻辑 Hook
|
||||
@@ -145,7 +146,7 @@ export const useEventFilters = ({ navigate, onEventClick, eventTimelineRef } = {
|
||||
});
|
||||
|
||||
if (navigate) {
|
||||
navigate(`/event-detail/${eventId}`);
|
||||
navigate(getEventDetailUrl(eventId));
|
||||
}
|
||||
}, [navigate, track]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user