事件中心的涨停原因里面和事件相关

This commit is contained in:
2026-01-11 14:04:07 +08:00
parent 5ee6fe54f1
commit 11c9e7b134
5 changed files with 69 additions and 1229 deletions

Binary file not shown.

1209
app.py

File diff suppressed because it is too large Load Diff

View File

@@ -200,14 +200,26 @@ const PredictionTopicDetail = () => {
const timeLeft = useCountdown(topic?.deadline);
// 计算实际状态(基于截止时间自动判断)
const effectiveStatus = useMemo(() => {
if (!topic) return 'active';
// 使用状态而非 useMemo确保在 timeLeft 变化时能正确触发重渲染
const [effectiveStatus, setEffectiveStatus] = useState('active');
useEffect(() => {
if (!topic) {
setEffectiveStatus('active');
return;
}
// 如果已经是结算状态,保持不变
if (topic.status === 'settled') return 'settled';
if (topic.status === 'settled') {
setEffectiveStatus('settled');
return;
}
// 如果已过截止时间,自动变为已截止
if (timeLeft.expired && topic.status === 'active') return 'trading_closed';
return topic.status;
}, [topic?.status, timeLeft.expired]);
if (timeLeft.expired && topic.status === 'active') {
setEffectiveStatus('trading_closed');
return;
}
setEffectiveStatus(topic.status);
}, [topic, timeLeft.expired]);
// 判断当前用户是否是作者
const isAuthor = useMemo(() => {
@@ -216,14 +228,10 @@ const PredictionTopicDetail = () => {
}, [user, topic]);
// 判断是否可以结算(作者 + 已截止 + 未结算)
const canSettle = useMemo(() => {
return isAuthor && effectiveStatus === 'trading_closed';
}, [isAuthor, effectiveStatus]);
const canSettle = isAuthor && effectiveStatus === 'trading_closed';
// 判断是否可以交易
const canTrade = useMemo(() => {
return effectiveStatus === 'active' && !isAuthor;
}, [effectiveStatus, isAuthor]);
const canTrade = effectiveStatus === 'active' && !isAuthor;
// 结算成功回调
const handleSettleSuccess = async () => {

View File

@@ -14,8 +14,33 @@ import { forumColors } from '@theme/forumTheme';
* @returns {object} 时间差对象
*/
const calculateTimeLeft = (deadline) => {
// 处理无效输入
if (!deadline) {
return { expired: false, days: 0, hours: 0, minutes: 0, seconds: 0, totalMs: 0 };
}
const now = new Date();
const end = new Date(deadline);
let end;
// 处理不同格式的时间字符串
if (typeof deadline === 'string') {
// 如果是 ISO 格式或包含 T 的完整时间
if (deadline.includes('T') || deadline.includes(' ')) {
end = new Date(deadline);
} else {
// 如果只是日期格式 (YYYY-MM-DD),将其设置为当天结束时间 (23:59:59)
end = new Date(deadline + 'T23:59:59');
}
} else {
end = new Date(deadline);
}
// 检查日期是否有效
if (isNaN(end.getTime())) {
console.warn('Invalid deadline format:', deadline);
return { expired: false, days: 0, hours: 0, minutes: 0, seconds: 0, totalMs: 0 };
}
const diff = end - now;
if (diff <= 0) {
@@ -38,9 +63,17 @@ const calculateTimeLeft = (deadline) => {
export const useCountdown = (deadline) => {
const [timeLeft, setTimeLeft] = useState(() => calculateTimeLeft(deadline));
// 当 deadline 变化时,立即重新计算
useEffect(() => {
// 已过期则不需要更新
if (timeLeft.expired) return;
if (deadline) {
const newTimeLeft = calculateTimeLeft(deadline);
setTimeLeft(newTimeLeft);
}
}, [deadline]);
useEffect(() => {
// 无效的 deadline 或已过期则不需要更新
if (!deadline || timeLeft.expired) return;
// 根据剩余时间决定更新频率
const interval = timeLeft.totalMs < 60000 ? 1000 : 60000; // 小于1分钟时秒级更新

View File

@@ -3,7 +3,7 @@
* 展示预测市场的话题概览
*/
import React, { useMemo } from 'react';
import React, { useMemo, useState, useEffect } from 'react';
import {
Box,
Text,
@@ -51,12 +51,20 @@ const PredictionTopicCard = ({ topic }) => {
};
// 计算实际状态(基于截止时间自动判断)
const effectiveStatus = useMemo(() => {
const [effectiveStatus, setEffectiveStatus] = useState(topic.status);
useEffect(() => {
// 如果已经是结算状态,保持不变
if (topic.status === 'settled') return 'settled';
if (topic.status === 'settled') {
setEffectiveStatus('settled');
return;
}
// 如果已过截止时间,自动变为已截止
if (timeLeft.expired && topic.status === 'active') return 'trading_closed';
return topic.status;
if (timeLeft.expired && topic.status === 'active') {
setEffectiveStatus('trading_closed');
return;
}
setEffectiveStatus(topic.status);
}, [topic.status, timeLeft.expired]);
// 获取选项数据