update pay function
This commit is contained in:
309
src/components/ImageLightbox/index.js
Normal file
309
src/components/ImageLightbox/index.js
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
/**
|
||||||
|
* 图片灯箱组件
|
||||||
|
* 点击图片放大查看
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import {
|
||||||
|
Modal,
|
||||||
|
ModalOverlay,
|
||||||
|
ModalContent,
|
||||||
|
ModalBody,
|
||||||
|
ModalCloseButton,
|
||||||
|
Image,
|
||||||
|
Box,
|
||||||
|
IconButton,
|
||||||
|
HStack,
|
||||||
|
useDisclosure,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { ChevronLeft, ChevronRight, X, ZoomIn } from 'lucide-react';
|
||||||
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
|
|
||||||
|
const MotionBox = motion(Box);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单图片灯箱
|
||||||
|
*/
|
||||||
|
export const ImageLightbox = ({ src, alt, ...props }) => {
|
||||||
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* 缩略图 */}
|
||||||
|
<Box
|
||||||
|
position="relative"
|
||||||
|
cursor="pointer"
|
||||||
|
onClick={onOpen}
|
||||||
|
_hover={{
|
||||||
|
'& .zoom-icon': {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={src}
|
||||||
|
alt={alt}
|
||||||
|
w="100%"
|
||||||
|
h="100%"
|
||||||
|
objectFit="cover"
|
||||||
|
borderRadius="md"
|
||||||
|
transition="all 0.3s"
|
||||||
|
_hover={{
|
||||||
|
transform: 'scale(1.05)',
|
||||||
|
filter: 'brightness(0.8)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* 放大图标 */}
|
||||||
|
<Box
|
||||||
|
className="zoom-icon"
|
||||||
|
position="absolute"
|
||||||
|
top="50%"
|
||||||
|
left="50%"
|
||||||
|
transform="translate(-50%, -50%)"
|
||||||
|
opacity={0}
|
||||||
|
transition="opacity 0.3s"
|
||||||
|
pointerEvents="none"
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
bg="blackAlpha.700"
|
||||||
|
borderRadius="full"
|
||||||
|
p="3"
|
||||||
|
>
|
||||||
|
<ZoomIn size={32} color="white" />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 灯箱模态框 */}
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose} size="full" isCentered>
|
||||||
|
<ModalOverlay bg="blackAlpha.900" backdropFilter="blur(10px)" />
|
||||||
|
<ModalContent bg="transparent" boxShadow="none">
|
||||||
|
<ModalCloseButton
|
||||||
|
position="fixed"
|
||||||
|
top="4"
|
||||||
|
right="4"
|
||||||
|
size="lg"
|
||||||
|
color="white"
|
||||||
|
bg="blackAlpha.600"
|
||||||
|
_hover={{ bg: 'blackAlpha.800' }}
|
||||||
|
borderRadius="full"
|
||||||
|
zIndex={2}
|
||||||
|
/>
|
||||||
|
<ModalBody display="flex" alignItems="center" justifyContent="center" p="0">
|
||||||
|
<MotionBox
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
exit={{ opacity: 0, scale: 0.9 }}
|
||||||
|
transition={{ duration: 0.3 }}
|
||||||
|
maxW="90vw"
|
||||||
|
maxH="90vh"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={src}
|
||||||
|
alt={alt}
|
||||||
|
maxW="100%"
|
||||||
|
maxH="90vh"
|
||||||
|
objectFit="contain"
|
||||||
|
borderRadius="lg"
|
||||||
|
/>
|
||||||
|
</MotionBox>
|
||||||
|
</ModalBody>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多图片轮播灯箱
|
||||||
|
*/
|
||||||
|
export const ImageGalleryLightbox = ({ images, initialIndex = 0, ...props }) => {
|
||||||
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
const [currentIndex, setCurrentIndex] = useState(initialIndex);
|
||||||
|
|
||||||
|
const handleOpen = (index) => {
|
||||||
|
setCurrentIndex(index);
|
||||||
|
onOpen();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePrev = () => {
|
||||||
|
setCurrentIndex((prev) => (prev === 0 ? images.length - 1 : prev - 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNext = () => {
|
||||||
|
setCurrentIndex((prev) => (prev === images.length - 1 ? 0 : prev + 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleKeyDown = (e) => {
|
||||||
|
if (e.key === 'ArrowLeft') handlePrev();
|
||||||
|
if (e.key === 'ArrowRight') handleNext();
|
||||||
|
if (e.key === 'Escape') onClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* 缩略图网格 */}
|
||||||
|
<HStack spacing="2" flexWrap="wrap" {...props}>
|
||||||
|
{images.map((image, index) => (
|
||||||
|
<Box
|
||||||
|
key={index}
|
||||||
|
position="relative"
|
||||||
|
cursor="pointer"
|
||||||
|
onClick={() => handleOpen(index)}
|
||||||
|
_hover={{
|
||||||
|
'& .zoom-icon': {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={image.src || image}
|
||||||
|
alt={image.alt || `图片 ${index + 1}`}
|
||||||
|
w="150px"
|
||||||
|
h="150px"
|
||||||
|
objectFit="cover"
|
||||||
|
borderRadius="md"
|
||||||
|
transition="all 0.3s"
|
||||||
|
_hover={{
|
||||||
|
transform: 'scale(1.05)',
|
||||||
|
filter: 'brightness(0.8)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* 放大图标 */}
|
||||||
|
<Box
|
||||||
|
className="zoom-icon"
|
||||||
|
position="absolute"
|
||||||
|
top="50%"
|
||||||
|
left="50%"
|
||||||
|
transform="translate(-50%, -50%)"
|
||||||
|
opacity={0}
|
||||||
|
transition="opacity 0.3s"
|
||||||
|
pointerEvents="none"
|
||||||
|
>
|
||||||
|
<Box bg="blackAlpha.700" borderRadius="full" p="2">
|
||||||
|
<ZoomIn size={24} color="white" />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</HStack>
|
||||||
|
|
||||||
|
{/* 灯箱模态框(带轮播) */}
|
||||||
|
<Modal
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
size="full"
|
||||||
|
isCentered
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
|
>
|
||||||
|
<ModalOverlay bg="blackAlpha.900" backdropFilter="blur(10px)" />
|
||||||
|
<ModalContent bg="transparent" boxShadow="none">
|
||||||
|
{/* 关闭按钮 */}
|
||||||
|
<IconButton
|
||||||
|
icon={<X />}
|
||||||
|
position="fixed"
|
||||||
|
top="4"
|
||||||
|
right="4"
|
||||||
|
size="lg"
|
||||||
|
color="white"
|
||||||
|
bg="blackAlpha.600"
|
||||||
|
_hover={{ bg: 'blackAlpha.800' }}
|
||||||
|
borderRadius="full"
|
||||||
|
zIndex={2}
|
||||||
|
onClick={onClose}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ModalBody
|
||||||
|
display="flex"
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
p="0"
|
||||||
|
position="relative"
|
||||||
|
>
|
||||||
|
{/* 左箭头 */}
|
||||||
|
{images.length > 1 && (
|
||||||
|
<IconButton
|
||||||
|
icon={<ChevronLeft />}
|
||||||
|
position="absolute"
|
||||||
|
left="4"
|
||||||
|
top="50%"
|
||||||
|
transform="translateY(-50%)"
|
||||||
|
size="lg"
|
||||||
|
color="white"
|
||||||
|
bg="blackAlpha.600"
|
||||||
|
_hover={{ bg: 'blackAlpha.800' }}
|
||||||
|
borderRadius="full"
|
||||||
|
zIndex={2}
|
||||||
|
onClick={handlePrev}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 图片 */}
|
||||||
|
<AnimatePresence mode="wait">
|
||||||
|
<MotionBox
|
||||||
|
key={currentIndex}
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
exit={{ opacity: 0, scale: 0.9 }}
|
||||||
|
transition={{ duration: 0.3 }}
|
||||||
|
maxW="90vw"
|
||||||
|
maxH="90vh"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={images[currentIndex].src || images[currentIndex]}
|
||||||
|
alt={images[currentIndex].alt || `图片 ${currentIndex + 1}`}
|
||||||
|
maxW="100%"
|
||||||
|
maxH="90vh"
|
||||||
|
objectFit="contain"
|
||||||
|
borderRadius="lg"
|
||||||
|
/>
|
||||||
|
</MotionBox>
|
||||||
|
</AnimatePresence>
|
||||||
|
|
||||||
|
{/* 右箭头 */}
|
||||||
|
{images.length > 1 && (
|
||||||
|
<IconButton
|
||||||
|
icon={<ChevronRight />}
|
||||||
|
position="absolute"
|
||||||
|
right="4"
|
||||||
|
top="50%"
|
||||||
|
transform="translateY(-50%)"
|
||||||
|
size="lg"
|
||||||
|
color="white"
|
||||||
|
bg="blackAlpha.600"
|
||||||
|
_hover={{ bg: 'blackAlpha.800' }}
|
||||||
|
borderRadius="full"
|
||||||
|
zIndex={2}
|
||||||
|
onClick={handleNext}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 图片计数 */}
|
||||||
|
{images.length > 1 && (
|
||||||
|
<Box
|
||||||
|
position="absolute"
|
||||||
|
bottom="4"
|
||||||
|
left="50%"
|
||||||
|
transform="translateX(-50%)"
|
||||||
|
bg="blackAlpha.700"
|
||||||
|
color="white"
|
||||||
|
px="4"
|
||||||
|
py="2"
|
||||||
|
borderRadius="full"
|
||||||
|
fontSize="sm"
|
||||||
|
fontWeight="600"
|
||||||
|
>
|
||||||
|
{currentIndex + 1} / {images.length}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</ModalBody>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ImageLightbox;
|
||||||
@@ -6,6 +6,9 @@ import { BrowserRouter as Router } from 'react-router-dom';
|
|||||||
// 导入 Brainwave 样式(空文件,保留以避免错误)
|
// 导入 Brainwave 样式(空文件,保留以避免错误)
|
||||||
import './styles/brainwave.css';
|
import './styles/brainwave.css';
|
||||||
|
|
||||||
|
// 导入 Select 下拉框颜色修复样式
|
||||||
|
import './styles/select-fix.css';
|
||||||
|
|
||||||
// 导入 Bytedesk 客服系统 z-index 覆盖样式(必须在所有样式之后导入)
|
// 导入 Bytedesk 客服系统 z-index 覆盖样式(必须在所有样式之后导入)
|
||||||
import './styles/bytedesk-override.css';
|
import './styles/bytedesk-override.css';
|
||||||
|
|
||||||
|
|||||||
89
src/styles/select-fix.css
Normal file
89
src/styles/select-fix.css
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* 修复 Chakra UI Select 组件的下拉选项颜色问题
|
||||||
|
* 黑金主题下,下拉选项需要深色背景和白色文字
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 所有 select 元素的 option 样式 */
|
||||||
|
select option {
|
||||||
|
background-color: #1A1A1A !important; /* 深色背景 */
|
||||||
|
color: #FFFFFF !important; /* 白色文字 */
|
||||||
|
padding: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选中的 option */
|
||||||
|
select option:checked {
|
||||||
|
background-color: #2A2A2A !important;
|
||||||
|
color: #FFC107 !important; /* 金色高亮 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hover 状态的 option (某些浏览器支持) */
|
||||||
|
select option:hover {
|
||||||
|
background-color: #222222 !important;
|
||||||
|
color: #FFD700 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 禁用的 option */
|
||||||
|
select option:disabled {
|
||||||
|
color: #808080 !important;
|
||||||
|
background-color: #151515 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Firefox 特殊处理 */
|
||||||
|
@-moz-document url-prefix() {
|
||||||
|
select option {
|
||||||
|
background-color: #1A1A1A !important;
|
||||||
|
color: #FFFFFF !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Webkit/Chrome 特殊处理 */
|
||||||
|
select {
|
||||||
|
/* 自定义下拉箭头颜色 */
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 修复 Chakra UI Select 组件的特定样式 */
|
||||||
|
.chakra-select {
|
||||||
|
background-color: #1A1A1A !important;
|
||||||
|
color: #FFFFFF !important;
|
||||||
|
border-color: #333333 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chakra-select:hover {
|
||||||
|
border-color: #404040 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chakra-select:focus {
|
||||||
|
border-color: #FFC107 !important;
|
||||||
|
box-shadow: 0 0 0 1px rgba(255, 193, 7, 0.3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 下拉箭头图标 */
|
||||||
|
.chakra-select__icon-wrapper {
|
||||||
|
color: #FFFFFF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 修复所有表单 select 元素 */
|
||||||
|
select[class*="chakra-select"],
|
||||||
|
select[class*="select"] {
|
||||||
|
background-color: #1A1A1A !important;
|
||||||
|
color: #FFFFFF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 自定义滚动条 (适用于下拉列表) */
|
||||||
|
select::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select::-webkit-scrollbar-track {
|
||||||
|
background: #0A0A0A;
|
||||||
|
}
|
||||||
|
|
||||||
|
select::-webkit-scrollbar-thumb {
|
||||||
|
background: #333333;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #FFC107;
|
||||||
|
}
|
||||||
@@ -217,6 +217,32 @@ export const forumComponentStyles = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Select下拉框样式(修复白色文字问题)
|
||||||
|
Select: {
|
||||||
|
baseStyle: {
|
||||||
|
field: {
|
||||||
|
bg: forumColors.background.card,
|
||||||
|
color: forumColors.text.primary,
|
||||||
|
borderColor: forumColors.border.default,
|
||||||
|
_hover: {
|
||||||
|
borderColor: forumColors.border.light,
|
||||||
|
},
|
||||||
|
_focus: {
|
||||||
|
borderColor: forumColors.border.gold,
|
||||||
|
boxShadow: `0 0 0 1px ${forumColors.border.goldGlow}`,
|
||||||
|
},
|
||||||
|
// 修复下拉选项颜色
|
||||||
|
option: {
|
||||||
|
bg: forumColors.background.card,
|
||||||
|
color: forumColors.text.primary,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
color: forumColors.text.primary,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
// 标签样式
|
// 标签样式
|
||||||
Tag: {
|
Tag: {
|
||||||
variants: {
|
variants: {
|
||||||
|
|||||||
184
verify-prediction-market.js
Normal file
184
verify-prediction-market.js
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/**
|
||||||
|
* 预测市场功能验证脚本
|
||||||
|
* 检查所有必需的文件和配置是否正确
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
console.log('🔍 开始验证预测市场功能...\n');
|
||||||
|
|
||||||
|
let errors = 0;
|
||||||
|
let warnings = 0;
|
||||||
|
|
||||||
|
// 颜色输出
|
||||||
|
const colors = {
|
||||||
|
green: '\x1b[32m',
|
||||||
|
red: '\x1b[31m',
|
||||||
|
yellow: '\x1b[33m',
|
||||||
|
blue: '\x1b[34m',
|
||||||
|
reset: '\x1b[0m',
|
||||||
|
};
|
||||||
|
|
||||||
|
function success(msg) {
|
||||||
|
console.log(`${colors.green}✅ ${msg}${colors.reset}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function error(msg) {
|
||||||
|
console.log(`${colors.red}❌ ${msg}${colors.reset}`);
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function warning(msg) {
|
||||||
|
console.log(`${colors.yellow}⚠️ ${msg}${colors.reset}`);
|
||||||
|
warnings++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function info(msg) {
|
||||||
|
console.log(`${colors.blue}ℹ️ ${msg}${colors.reset}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 检查必需文件
|
||||||
|
console.log('📂 检查文件结构...\n');
|
||||||
|
|
||||||
|
const requiredFiles = [
|
||||||
|
'src/services/creditSystemService.js',
|
||||||
|
'src/services/predictionMarketService.js',
|
||||||
|
'src/views/ValueForum/index.js',
|
||||||
|
'src/views/ValueForum/PredictionTopicDetail.js',
|
||||||
|
'src/views/ValueForum/components/PredictionTopicCard.js',
|
||||||
|
'src/views/ValueForum/components/CreatePredictionModal.js',
|
||||||
|
'src/views/ValueForum/components/TradeModal.js',
|
||||||
|
'src/theme/forumTheme.js',
|
||||||
|
'src/routes/lazy-components.js',
|
||||||
|
'src/routes/routeConfig.js',
|
||||||
|
];
|
||||||
|
|
||||||
|
requiredFiles.forEach(file => {
|
||||||
|
const fullPath = path.join(__dirname, file);
|
||||||
|
if (fs.existsSync(fullPath)) {
|
||||||
|
success(`${file}`);
|
||||||
|
} else {
|
||||||
|
error(`文件不存在: ${file}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. 检查主题文件
|
||||||
|
console.log('\n🎨 检查主题配置...\n');
|
||||||
|
|
||||||
|
const themeFile = path.join(__dirname, 'src/theme/forumTheme.js');
|
||||||
|
if (fs.existsSync(themeFile)) {
|
||||||
|
const content = fs.readFileSync(themeFile, 'utf8');
|
||||||
|
|
||||||
|
const requiredColors = ['success:', 'error:', 'warning:', 'info:', 'primary:'];
|
||||||
|
requiredColors.forEach(color => {
|
||||||
|
if (content.includes(color)) {
|
||||||
|
success(`主题包含 ${color} 定义`);
|
||||||
|
} else {
|
||||||
|
error(`主题缺少 ${color} 定义`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 检查具体的颜色值
|
||||||
|
if (content.includes('500: \'#4CAF50\'') || content.includes('500: "#4CAF50"')) {
|
||||||
|
success('success[500] 颜色已定义');
|
||||||
|
} else {
|
||||||
|
error('success[500] 颜色缺失');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content.includes('500: \'#F44336\'') || content.includes('500: "#F44336"')) {
|
||||||
|
success('error[500] 颜色已定义');
|
||||||
|
} else {
|
||||||
|
error('error[500] 颜色缺失');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查路由配置
|
||||||
|
console.log('\n🛣️ 检查路由配置...\n');
|
||||||
|
|
||||||
|
const routeConfigFile = path.join(__dirname, 'src/routes/routeConfig.js');
|
||||||
|
if (fs.existsSync(routeConfigFile)) {
|
||||||
|
const content = fs.readFileSync(routeConfigFile, 'utf8');
|
||||||
|
|
||||||
|
if (content.includes('value-forum/prediction/:topicId')) {
|
||||||
|
success('预测话题详情路由已配置');
|
||||||
|
} else {
|
||||||
|
error('预测话题详情路由未配置');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const lazyComponentsFile = path.join(__dirname, 'src/routes/lazy-components.js');
|
||||||
|
if (fs.existsSync(lazyComponentsFile)) {
|
||||||
|
const content = fs.readFileSync(lazyComponentsFile, 'utf8');
|
||||||
|
|
||||||
|
if (content.includes('PredictionTopicDetail')) {
|
||||||
|
success('PredictionTopicDetail 懒加载已配置');
|
||||||
|
} else {
|
||||||
|
error('PredictionTopicDetail 懒加载未配置');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 检查依赖
|
||||||
|
console.log('\n📦 检查npm依赖...\n');
|
||||||
|
|
||||||
|
const packageJsonFile = path.join(__dirname, 'package.json');
|
||||||
|
if (fs.existsSync(packageJsonFile)) {
|
||||||
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonFile, 'utf8'));
|
||||||
|
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
||||||
|
|
||||||
|
const requiredDeps = [
|
||||||
|
'@chakra-ui/react',
|
||||||
|
'react',
|
||||||
|
'react-router-dom',
|
||||||
|
'framer-motion',
|
||||||
|
'lucide-react',
|
||||||
|
];
|
||||||
|
|
||||||
|
requiredDeps.forEach(dep => {
|
||||||
|
if (deps[dep]) {
|
||||||
|
success(`${dep}: ${deps[dep]}`);
|
||||||
|
} else {
|
||||||
|
error(`缺少依赖: ${dep}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 检查ES配置
|
||||||
|
console.log('\n🔌 检查Elasticsearch配置...\n');
|
||||||
|
|
||||||
|
const esServiceFile = path.join(__dirname, 'src/services/elasticsearchService.js');
|
||||||
|
if (fs.existsSync(esServiceFile)) {
|
||||||
|
const content = fs.readFileSync(esServiceFile, 'utf8');
|
||||||
|
|
||||||
|
if (content.includes('222.128.1.157:19200')) {
|
||||||
|
success('ES开发环境地址已配置: 222.128.1.157:19200');
|
||||||
|
} else {
|
||||||
|
warning('ES地址可能已修改,请检查配置');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content.includes('forum_posts')) {
|
||||||
|
success('ES索引 forum_posts 已定义');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 输出总结
|
||||||
|
console.log('\n' + '='.repeat(50));
|
||||||
|
console.log(`\n📊 验证结果总结:\n`);
|
||||||
|
|
||||||
|
if (errors === 0 && warnings === 0) {
|
||||||
|
console.log(`${colors.green}🎉 所有检查通过!预测市场功能已正确配置。${colors.reset}\n`);
|
||||||
|
console.log(`${colors.blue}👉 下一步: 运行 npm start 启动应用${colors.reset}\n`);
|
||||||
|
process.exit(0);
|
||||||
|
} else {
|
||||||
|
if (errors > 0) {
|
||||||
|
console.log(`${colors.red}❌ 发现 ${errors} 个错误${colors.reset}`);
|
||||||
|
}
|
||||||
|
if (warnings > 0) {
|
||||||
|
console.log(`${colors.yellow}⚠️ 发现 ${warnings} 个警告${colors.reset}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`\n${colors.blue}📚 查看故障排除指南:${colors.reset}`);
|
||||||
|
console.log(` cat TROUBLESHOOTING.md\n`);
|
||||||
|
|
||||||
|
process.exit(errors > 0 ? 1 : 0);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user