{eventDetail.creator?.username || 'Anonymous'}
@@ -234,7 +234,7 @@ const EventDetailModal = ({ visible, event, onClose }) => {
{comment.author?.username || 'Anonymous'}
- {moment(comment.created_at).format('MM-DD HH:mm')}
+ {dayjs(comment.created_at).format('MM-DD HH:mm')}
}
diff --git a/src/views/Community/components/HotEvents.js b/src/views/Community/components/HotEvents.js
index 97412830..8d7411d8 100644
--- a/src/views/Community/components/HotEvents.js
+++ b/src/views/Community/components/HotEvents.js
@@ -11,7 +11,7 @@ import {
ModalCloseButton,
useDisclosure
} from '@chakra-ui/react';
-import moment from 'moment';
+import dayjs from 'dayjs';
import './HotEvents.css';
import defaultEventImage from '../../../assets/img/default-event.jpg';
import DynamicNewsDetailPanel from './DynamicNewsDetail';
@@ -181,9 +181,9 @@ const HotEvents = ({ events, onPageChange, onEventClick }) => {
{event.creator?.username || 'Anonymous'}
- {moment(event.created_at).format('YYYY-MM-DD')}
+ {dayjs(event.created_at).format('YYYY-MM-DD')}
{' '}
- {moment(event.created_at).format('HH:mm')}
+ {dayjs(event.created_at).format('HH:mm')}
diff --git a/src/views/Community/components/InvestmentCalendar.js b/src/views/Community/components/InvestmentCalendar.js
index 3df32c21..e9d73cdf 100644
--- a/src/views/Community/components/InvestmentCalendar.js
+++ b/src/views/Community/components/InvestmentCalendar.js
@@ -8,7 +8,7 @@ import {
StarFilled, StarOutlined, CalendarOutlined, LinkOutlined, StockOutlined,
TagsOutlined, ClockCircleOutlined, InfoCircleOutlined, LockOutlined, RobotOutlined
} from '@ant-design/icons';
-import moment from 'moment';
+import dayjs from 'dayjs';
import ReactMarkdown from 'react-markdown';
import { eventService, stockService } from '../../../services/eventService';
import StockChartAntdModal from '../../../components/StockChart/StockChartAntdModal';
@@ -33,7 +33,7 @@ const InvestmentCalendar = () => {
const [selectedDateEvents, setSelectedDateEvents] = useState([]);
const [modalVisible, setModalVisible] = useState(false);
const [loading, setLoading] = useState(false);
- const [currentMonth, setCurrentMonth] = useState(moment());
+ const [currentMonth, setCurrentMonth] = useState(dayjs());
// 新增状态
const [detailDrawerVisible, setDetailDrawerVisible] = useState(false);
@@ -344,7 +344,7 @@ const InvestmentCalendar = () => {
render: (time) => (
- {moment(time).format('HH:mm')}
+ {dayjs(time).format('HH:mm')}
)
},
diff --git a/src/views/Community/components/MarketReviewCard.js b/src/views/Community/components/MarketReviewCard.js
index 78d771d2..77164be4 100644
--- a/src/views/Community/components/MarketReviewCard.js
+++ b/src/views/Community/components/MarketReviewCard.js
@@ -20,7 +20,7 @@ import {
GridItem,
} from '@chakra-ui/react';
import { TimeIcon, InfoIcon } from '@chakra-ui/icons';
-import moment from 'moment';
+import dayjs from 'dayjs';
import CompactEventCard from './EventCard/CompactEventCard';
import EventHeader from './EventCard/EventHeader';
import EventStats from './EventCard/EventStats';
@@ -160,7 +160,7 @@ const MarketReviewCard = forwardRef(({
{/* 右侧:时间 + 作者 */}
- {moment(selectedEvent.created_at).format('YYYY-MM-DD HH:mm')}
+ {dayjs(selectedEvent.created_at).format('YYYY-MM-DD HH:mm')}
•
@{selectedEvent.creator?.username || 'Anonymous'}
diff --git a/src/views/Community/components/StockDetailPanel.js b/src/views/Community/components/StockDetailPanel.js
index fae14619..c626b761 100644
--- a/src/views/Community/components/StockDetailPanel.js
+++ b/src/views/Community/components/StockDetailPanel.js
@@ -3,7 +3,7 @@ import React, { useState, useEffect, useRef, useMemo, useCallback } from 'react'
import { Drawer, Spin, Button, Alert } from 'antd';
import { CloseOutlined, LockOutlined, CrownOutlined } from '@ant-design/icons';
import { Tabs as AntdTabs } from 'antd';
-import moment from 'moment';
+import dayjs from 'dayjs';
// Services and Utils
import { eventService } from '../../../services/eventService';
@@ -167,7 +167,7 @@ function StockDetailPanel({ visible, event, onClose }) {
if (fixedCharts.length === 0) return null;
const formattedEventTime = event?.start_time
- ? moment(event.start_time).format('YYYY-MM-DD HH:mm')
+ ? dayjs(event.start_time).format('YYYY-MM-DD HH:mm')
: undefined;
return fixedCharts.map(({ stock }, index) => (
diff --git a/src/views/Community/components/StockDetailPanel/components/MiniTimelineChart.js b/src/views/Community/components/StockDetailPanel/components/MiniTimelineChart.js
index 45c26d11..b2b55d04 100644
--- a/src/views/Community/components/StockDetailPanel/components/MiniTimelineChart.js
+++ b/src/views/Community/components/StockDetailPanel/components/MiniTimelineChart.js
@@ -2,7 +2,7 @@
import React, { useState, useEffect, useMemo, useRef } from 'react';
import ReactECharts from 'echarts-for-react';
import * as echarts from 'echarts';
-import moment from 'moment';
+import dayjs from 'dayjs';
import {
fetchKlineData,
getCacheKey,
@@ -27,7 +27,7 @@ const MiniTimelineChart = React.memo(function MiniTimelineChart({ stockCode, eve
// 稳定的事件时间,避免因为格式化导致的重复请求
const stableEventTime = useMemo(() => {
- return eventTime ? moment(eventTime).format('YYYY-MM-DD HH:mm') : '';
+ return eventTime ? dayjs(eventTime).format('YYYY-MM-DD HH:mm') : '';
}, [eventTime]);
useEffect(() => {
@@ -109,7 +109,7 @@ const MiniTimelineChart = React.memo(function MiniTimelineChart({ stockCode, eve
let eventMarkLineData = [];
if (stableEventTime && Array.isArray(times) && times.length > 0) {
try {
- const eventMinute = moment(stableEventTime, 'YYYY-MM-DD HH:mm').format('HH:mm');
+ const eventMinute = dayjs(stableEventTime, 'YYYY-MM-DD HH:mm').format('HH:mm');
const parseMinuteTime = (timeStr) => {
const [h, m] = String(timeStr).split(':').map(Number);
return h * 60 + m;
diff --git a/src/views/Community/components/StockDetailPanel/components/StockTable.js b/src/views/Community/components/StockDetailPanel/components/StockTable.js
index c78f230e..3edd9ca9 100644
--- a/src/views/Community/components/StockDetailPanel/components/StockTable.js
+++ b/src/views/Community/components/StockDetailPanel/components/StockTable.js
@@ -2,7 +2,7 @@
import React, { useState, useCallback, useMemo } from 'react';
import { Table, Button } from 'antd';
import { StarFilled, StarOutlined } from '@ant-design/icons';
-import moment from 'moment';
+import dayjs from 'dayjs';
import MiniTimelineChart from './MiniTimelineChart';
import { logger } from '../../../../../utils/logger';
@@ -31,7 +31,7 @@ const StockTable = ({
// 稳定的事件时间,避免重复渲染
const stableEventTime = useMemo(() => {
- return eventTime ? moment(eventTime).format('YYYY-MM-DD HH:mm') : '';
+ return eventTime ? dayjs(eventTime).format('YYYY-MM-DD HH:mm') : '';
}, [eventTime]);
// 切换行展开状态
diff --git a/src/views/Community/components/StockDetailPanel/utils/klineDataCache.js b/src/views/Community/components/StockDetailPanel/utils/klineDataCache.js
index 4bb1c194..55e42c5c 100644
--- a/src/views/Community/components/StockDetailPanel/utils/klineDataCache.js
+++ b/src/views/Community/components/StockDetailPanel/utils/klineDataCache.js
@@ -1,5 +1,5 @@
// src/views/Community/components/StockDetailPanel/utils/klineDataCache.js
-import moment from 'moment';
+import dayjs from 'dayjs';
import { stockService } from '../../../../../services/eventService';
import { logger } from '../../../../../utils/logger';
@@ -19,7 +19,7 @@ const REQUEST_INTERVAL = 30000; // 30秒内不重复请求同一只股票的数
* @returns {string} 缓存键
*/
export const getCacheKey = (stockCode, eventTime, chartType = 'timeline') => {
- const date = eventTime ? moment(eventTime).format('YYYY-MM-DD') : moment().format('YYYY-MM-DD');
+ const date = eventTime ? dayjs(eventTime).format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD');
return `${stockCode}|${date}|${chartType}`;
};
@@ -36,7 +36,7 @@ export const shouldRefreshData = (cacheKey) => {
const elapsed = now - lastTime;
// 如果是今天的数据且交易时间内,允许更频繁的更新
- const today = moment().format('YYYY-MM-DD');
+ const today = dayjs().format('YYYY-MM-DD');
const isToday = cacheKey.includes(today);
const currentHour = new Date().getHours();
const isTradingHours = currentHour >= 9 && currentHour < 16;
@@ -76,7 +76,7 @@ export const fetchKlineData = async (stockCode, eventTime, chartType = 'timeline
// 3. 发起新请求
logger.debug('klineDataCache', '发起新K线数据请求', { cacheKey, chartType });
- const normalizedEventTime = eventTime ? moment(eventTime).format('YYYY-MM-DD HH:mm') : undefined;
+ const normalizedEventTime = eventTime ? dayjs(eventTime).format('YYYY-MM-DD HH:mm') : undefined;
const requestPromise = stockService
.getKlineData(stockCode, chartType, normalizedEventTime)
.then((res) => {
diff --git a/src/views/Dashboard/components/InvestmentCalendarChakra.js b/src/views/Dashboard/components/InvestmentCalendarChakra.js
index 1ee18f9d..1e0930a3 100644
--- a/src/views/Dashboard/components/InvestmentCalendarChakra.js
+++ b/src/views/Dashboard/components/InvestmentCalendarChakra.js
@@ -52,13 +52,13 @@ import {
import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
-import moment from 'moment';
-import 'moment/locale/zh-cn';
+import dayjs from 'dayjs';
+import 'dayjs/locale/zh-cn';
import { logger } from '../../../utils/logger';
import { getApiBase } from '../../../utils/apiConfig';
import './InvestmentCalendar.css';
-moment.locale('zh-cn');
+dayjs.locale('zh-cn');
export default function InvestmentCalendarChakra() {
const { isOpen, onOpen, onClose } = useDisclosure();
@@ -140,12 +140,12 @@ export default function InvestmentCalendarChakra() {
// 处理日期点击
const handleDateClick = (info) => {
- const clickedDate = moment(info.date);
+ const clickedDate = dayjs(info.date);
setSelectedDate(clickedDate);
// 筛选当天的事件
const dayEvents = events.filter(event =>
- moment(event.start).isSame(clickedDate, 'day')
+ dayjs(event.start).isSame(clickedDate, 'day')
);
setSelectedDateEvents(dayEvents);
onOpen();
@@ -154,7 +154,7 @@ export default function InvestmentCalendarChakra() {
// 处理事件点击
const handleEventClick = (info) => {
const event = info.event;
- const clickedDate = moment(event.start);
+ const clickedDate = dayjs(event.start);
setSelectedDate(clickedDate);
setSelectedDateEvents([{
title: event.title,
@@ -173,7 +173,7 @@ export default function InvestmentCalendarChakra() {
const eventData = {
...newEvent,
- event_date: (selectedDate ? selectedDate.format('YYYY-MM-DD') : moment().format('YYYY-MM-DD')),
+ event_date: (selectedDate ? selectedDate.format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD')),
stocks: newEvent.stocks.split(',').map(s => s.trim()).filter(s => s),
};
@@ -274,7 +274,7 @@ export default function InvestmentCalendarChakra() {
size="sm"
colorScheme="blue"
leftIcon={}
- onClick={() => { if (!selectedDate) setSelectedDate(moment()); onAddOpen(); }}
+ onClick={() => { if (!selectedDate) setSelectedDate(dayjs()); onAddOpen(); }}
>
添加计划
diff --git a/src/views/Dashboard/components/InvestmentPlanningCenter.js b/src/views/Dashboard/components/InvestmentPlanningCenter.js
index 600b8439..d8c93994 100644
--- a/src/views/Dashboard/components/InvestmentPlanningCenter.js
+++ b/src/views/Dashboard/components/InvestmentPlanningCenter.js
@@ -66,13 +66,13 @@ import {
import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
-import moment from 'moment';
-import 'moment/locale/zh-cn';
+import dayjs from 'dayjs';
+import 'dayjs/locale/zh-cn';
import { logger } from '../../../utils/logger';
import { getApiBase } from '../../../utils/apiConfig';
import '../components/InvestmentCalendar.css';
-moment.locale('zh-cn');
+dayjs.locale('zh-cn');
// 创建 Context 用于跨标签页共享数据
const PlanningDataContext = createContext();
@@ -232,11 +232,11 @@ function CalendarPanel() {
// 处理日期点击
const handleDateClick = (info) => {
- const clickedDate = moment(info.date);
+ const clickedDate = dayjs(info.date);
setSelectedDate(clickedDate);
const dayEvents = allEvents.filter(event =>
- moment(event.event_date).isSame(clickedDate, 'day')
+ dayjs(event.event_date).isSame(clickedDate, 'day')
);
setSelectedDateEvents(dayEvents);
onOpen();
@@ -245,11 +245,11 @@ function CalendarPanel() {
// 处理事件点击
const handleEventClick = (info) => {
const event = info.event;
- const clickedDate = moment(event.start);
+ const clickedDate = dayjs(event.start);
setSelectedDate(clickedDate);
const dayEvents = allEvents.filter(ev =>
- moment(ev.event_date).isSame(clickedDate, 'day')
+ dayjs(ev.event_date).isSame(clickedDate, 'day')
);
setSelectedDateEvents(dayEvents);
onOpen();
@@ -262,7 +262,7 @@ function CalendarPanel() {
const eventData = {
...newEvent,
- event_date: (selectedDate ? selectedDate.format('YYYY-MM-DD') : moment().format('YYYY-MM-DD')),
+ event_date: (selectedDate ? selectedDate.format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD')),
stocks: newEvent.stocks.split(',').map(s => s.trim()).filter(s => s),
};
@@ -368,7 +368,7 @@ function CalendarPanel() {
size="sm"
colorScheme="purple"
leftIcon={}
- onClick={() => { if (!selectedDate) setSelectedDate(moment()); onAddOpen(); }}
+ onClick={() => { if (!selectedDate) setSelectedDate(dayjs()); onAddOpen(); }}
>
添加计划
@@ -619,7 +619,7 @@ function PlansPanel() {
const { isOpen, onOpen, onClose } = useDisclosure();
const [editingItem, setEditingItem] = useState(null);
const [formData, setFormData] = useState({
- date: moment().format('YYYY-MM-DD'),
+ date: dayjs().format('YYYY-MM-DD'),
title: '',
content: '',
type: 'plan',
@@ -638,13 +638,13 @@ function PlansPanel() {
setEditingItem(item);
setFormData({
...item,
- date: moment(item.event_date || item.date).format('YYYY-MM-DD'),
+ date: dayjs(item.event_date || item.date).format('YYYY-MM-DD'),
content: item.description || item.content || '',
});
} else {
setEditingItem(null);
setFormData({
- date: moment().format('YYYY-MM-DD'),
+ date: dayjs().format('YYYY-MM-DD'),
title: '',
content: '',
type: 'plan',
@@ -795,7 +795,7 @@ function PlansPanel() {
- {moment(item.event_date || item.date).format('YYYY年MM月DD日')}
+ {dayjs(item.event_date || item.date).format('YYYY年MM月DD日')}
- {moment(item.event_date || item.date).format('YYYY年MM月DD日')}
+ {dayjs(item.event_date || item.date).format('YYYY年MM月DD日')}
diff --git a/src/views/Dashboard/components/InvestmentPlansAndReviews.js b/src/views/Dashboard/components/InvestmentPlansAndReviews.js
index 87f9e8bb..fb4d81bd 100644
--- a/src/views/Dashboard/components/InvestmentPlansAndReviews.js
+++ b/src/views/Dashboard/components/InvestmentPlansAndReviews.js
@@ -60,12 +60,12 @@ import {
FiXCircle,
FiAlertCircle,
} from 'react-icons/fi';
-import moment from 'moment';
-import 'moment/locale/zh-cn';
+import dayjs from 'dayjs';
+import 'dayjs/locale/zh-cn';
import { logger } from '../../../utils/logger';
import { getApiBase } from '../../../utils/apiConfig';
-moment.locale('zh-cn');
+dayjs.locale('zh-cn');
export default function InvestmentPlansAndReviews({ type = 'both' }) {
const { isOpen, onOpen, onClose } = useDisclosure();
@@ -83,7 +83,7 @@ export default function InvestmentPlansAndReviews({ type = 'both' }) {
const [loading, setLoading] = useState(false);
const [editingItem, setEditingItem] = useState(null);
const [formData, setFormData] = useState({
- date: moment().format('YYYY-MM-DD'),
+ date: dayjs().format('YYYY-MM-DD'),
title: '',
content: '',
type: 'plan',
@@ -134,12 +134,12 @@ export default function InvestmentPlansAndReviews({ type = 'both' }) {
setEditingItem(item);
setFormData({
...item,
- date: moment(item.date).format('YYYY-MM-DD'),
+ date: dayjs(item.date).format('YYYY-MM-DD'),
});
} else {
setEditingItem(null);
setFormData({
- date: moment().format('YYYY-MM-DD'),
+ date: dayjs().format('YYYY-MM-DD'),
title: '',
content: '',
type: itemType,
@@ -291,7 +291,7 @@ export default function InvestmentPlansAndReviews({ type = 'both' }) {
- {moment(item.date).format('YYYY年MM月DD日')}
+ {dayjs(item.date).format('YYYY年MM月DD日')}
- moment(a.calendar_time).valueOf() - moment(b.calendar_time).valueOf()
+ dayjs(a.calendar_time).valueOf() - dayjs(b.calendar_time).valueOf()
);
setFutureEvents(sortedEvents);
logger.debug('MyFutureEvents', '未来事件加载成功', {
@@ -98,8 +98,8 @@ export default function MyFutureEvents({ limit = 5 }) {
// 格式化时间
const formatEventTime = (time) => {
- const eventTime = moment(time);
- const now = moment();
+ const eventTime = dayjs(time);
+ const now = dayjs();
const daysDiff = eventTime.diff(now, 'days');
if (daysDiff === 0) {
diff --git a/src/views/EventDetail/components/RelatedConcepts.js b/src/views/EventDetail/components/RelatedConcepts.js
index 00fa178e..34c53232 100644
--- a/src/views/EventDetail/components/RelatedConcepts.js
+++ b/src/views/EventDetail/components/RelatedConcepts.js
@@ -30,7 +30,7 @@ import {
Divider
} from '@chakra-ui/react';
import { FaEye, FaExternalLinkAlt, FaChartLine, FaCalendarAlt } from 'react-icons/fa';
-import moment from 'moment';
+import dayjs from 'dayjs';
import tradingDayUtils from '../../../utils/tradingDayUtils'; // 引入交易日工具
import { logger } from '../../../utils/logger';
import { PROFESSIONAL_COLORS } from '../../../constants/professionalTheme';
@@ -326,7 +326,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
if (typeof tradeDate === 'string') {
formattedTradeDate = tradeDate;
} else if (tradeDate instanceof Date) {
- formattedTradeDate = moment(tradeDate).format('YYYY-MM-DD');
+ formattedTradeDate = dayjs(tradeDate).format('YYYY-MM-DD');
} else if (moment.isMoment(tradeDate)) {
formattedTradeDate = tradeDate.format('YYYY-MM-DD');
} else {
@@ -334,7 +334,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
tradeDate,
tradeDateType: typeof tradeDate
});
- formattedTradeDate = moment().format('YYYY-MM-DD');
+ formattedTradeDate = dayjs().format('YYYY-MM-DD');
}
const requestBody = {
@@ -414,18 +414,18 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
// 检查是否是Date对象
if (eventTime instanceof Date) {
- eventMoment = moment(eventTime);
+ eventMoment = dayjs(eventTime);
} else if (typeof eventTime === 'string') {
- eventMoment = moment(eventTime);
+ eventMoment = dayjs(eventTime);
} else if (typeof eventTime === 'number') {
- eventMoment = moment(eventTime);
+ eventMoment = dayjs(eventTime);
} else {
logger.warn('RelatedConcepts', '未知的事件时间格式', {
eventTime,
eventTimeType: typeof eventTime,
eventId
});
- eventMoment = moment();
+ eventMoment = dayjs();
}
// 确保moment对象有效
@@ -434,7 +434,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
eventTime,
eventId
});
- eventMoment = moment();
+ eventMoment = dayjs();
}
formattedDate = eventMoment.format('YYYY-MM-DD');
@@ -448,7 +448,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
if (typeof nextTradingDay === 'string') {
formattedDate = nextTradingDay;
} else if (nextTradingDay instanceof Date) {
- formattedDate = moment(nextTradingDay).format('YYYY-MM-DD');
+ formattedDate = dayjs(nextTradingDay).format('YYYY-MM-DD');
} else {
logger.warn('RelatedConcepts', '交易日工具返回了无效格式', {
nextTradingDay,
@@ -476,16 +476,16 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
if (typeof currentTradingDay === 'string') {
formattedDate = currentTradingDay;
} else if (currentTradingDay instanceof Date) {
- formattedDate = moment(currentTradingDay).format('YYYY-MM-DD');
+ formattedDate = dayjs(currentTradingDay).format('YYYY-MM-DD');
} else {
logger.warn('RelatedConcepts', '当前交易日工具返回了无效格式', {
currentTradingDay,
eventId
});
- formattedDate = moment().format('YYYY-MM-DD');
+ formattedDate = dayjs().format('YYYY-MM-DD');
}
} else {
- formattedDate = moment().format('YYYY-MM-DD');
+ formattedDate = dayjs().format('YYYY-MM-DD');
}
}
@@ -558,9 +558,9 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
涨跌幅数据日期:{effectiveTradingDate}
- {eventTime && effectiveTradingDate !== moment(eventTime).format('YYYY-MM-DD') && (
+ {eventTime && effectiveTradingDate !== dayjs(eventTime).format('YYYY-MM-DD') && (
- (事件发生于 {typeof eventTime === 'object' ? moment(eventTime).format('YYYY-MM-DD HH:mm') : eventTime},显示下一交易日数据)
+ (事件发生于 {typeof eventTime === 'object' ? dayjs(eventTime).format('YYYY-MM-DD HH:mm') : eventTime},显示下一交易日数据)
)}