Files
nofx/web/src/components/landing/CommunitySection.tsx
Liu Xiang Qian 16bf34d56e feat: 添加 AI 扫描决策间隔配置支持
## 功能描述
在创建和编辑 Trader 时,支持配置 AI 扫描决策间隔(scan_interval_minutes),允许用户自定义 AI 决策的频率。
## 修改内容
### 后端修改 (api/server.go)
1. **CreateTraderRequest** 添加 `ScanIntervalMinutes` 字段
2. **UpdateTraderRequest** 添加 `ScanIntervalMinutes` 字段和 `SystemPromptTemplate` 字段
3. **handleCreateTrader** 处理扫描间隔默认值(默认 3 分钟)
4. **handleUpdateTrader** 支持更新扫描间隔
5. **handleGetTraderConfig** 返回中添加 `scan_interval_minutes` 字段
### 前端修改
#### web/src/types.ts
- `CreateTraderRequest` 添加 `scan_interval_minutes?` 可选字段
- `TraderConfigData` 添加 `scan_interval_minutes` 必填字段
#### web/src/components/TraderConfigModal.tsx
- 本地 `TraderConfigData` 接口添加 `scan_interval_minutes`
- 初始状态设置默认值为 3 分钟
- 添加 UI 输入框(范围 1-60 分钟)
- Label 优化为 "AI 扫描决策间隔 (分钟)"
#### web/src/components/AITradersPage.tsx
- `handleSaveEditTrader` 的更新请求中添加 `scan_interval_minutes`
#### web/src/components/landing/CommunitySection.tsx
- 修复 TypeScript 编译错误:定义 `CardProps` 接口
- 修正 `TestimonialCard` 组件的 prop 名称(author → authorName)
## 功能特性
-  支持 1-60 分钟的自定义间隔
-  默认值为 3 分钟
-  UI 提示建议范围:3-10 分钟
-  创建和编辑时均支持配置
-  后端验证和处理默认值
## 测试步骤
1. 创建新 Trader,设置自定义扫描间隔(如 10 分钟)
2. 验证 Trader 创建成功
3. 编辑现有 Trader,修改扫描间隔
4. 验证修改保存成功
5. 确认 AI 决策按照新的间隔执行
2025-11-03 21:55:26 +08:00

93 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { motion } from 'framer-motion'
import AnimatedSection from './AnimatedSection'
interface CardProps {
quote: string;
authorName: string;
handle: string;
avatarUrl: string;
tweetUrl: string;
delay: number;
}
function TestimonialCard({ quote, authorName, delay }: CardProps) {
return (
<motion.div
className='p-6 rounded-xl'
style={{ background: 'var(--brand-dark-gray)', border: '1px solid rgba(240, 185, 11, 0.1)' }}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay }}
whileHover={{ scale: 1.05 }}
>
<p className='text-lg mb-4' style={{ color: 'var(--brand-light-gray)' }}>
"{quote}"
</p>
<div className='flex items-center gap-2'>
<div className='w-8 h-8 rounded-full' style={{ background: 'var(--binance-yellow)' }} />
<span className='text-sm font-semibold' style={{ color: 'var(--text-secondary)' }}>
{authorName}
</span>
</div>
</motion.div>
)
}
export default function CommunitySection() {
const staggerContainer = { animate: { transition: { staggerChildren: 0.1 } } }
// 推特内容整合(保持原三列布局,超出自动换行)
const items: CardProps[] = [
{
quote:
'前不久非常火的 AI 量化交易系统 NOF1在 GitHub 上有人将其复刻并开源,这就是 NOFX 项目。基于 DeepSeek、Qwen 等大语言模型,打造的通用架构 AI 交易操作系统完成了从决策、到交易、再到复盘的闭环。GitHub: https://github.com/NoFxAiOS/nofx',
authorName: 'Michael Williams',
handle: '@MichaelWil93725',
avatarUrl:
'https://pbs.twimg.com/profile_images/1767615411594694659/Mj8Fdt6o_400x400.jpg',
tweetUrl:
'https://twitter.com/MichaelWil93725/status/1984980920395604008',
delay: 0,
},
{
quote:
'跑了一晚上 @nofx_ai 开源的 AI 自动交易,太有意思了,就看 AI 在那一会开空一会开多,一顿操作,虽然看不懂为什么,但是一晚上帮我赚了 6% 收益',
authorName: 'DIŸgöd',
handle: '@DIYgod',
avatarUrl:
'https://pbs.twimg.com/profile_images/1628393369029181440/r23HDDJk_400x400.jpg',
tweetUrl: 'https://twitter.com/DIYgod/status/1984442354515017923',
delay: 0.1,
},
{
quote:
'Open-source NOFX revives the legendary Alpha Arena, an AI-powered crypto futures battleground. Built on DeepSeek/Qwen AI, it trades live on Binance, Hyperliquid, and Aster DEX, featuring multi-AI battles and self-learning bots',
authorName: 'Kai',
handle: '@hqmank',
avatarUrl:
'https://pbs.twimg.com/profile_images/1905441261911506945/4YhLIqUm_400x400.jpg',
tweetUrl: 'https://twitter.com/hqmank/status/1984227431994290340',
delay: 0.15,
},
]
return (
<AnimatedSection>
<div className='max-w-7xl mx-auto'>
<motion.div
className='grid md:grid-cols-3 gap-6'
variants={staggerContainer}
initial='initial'
whileInView='animate'
viewport={{ once: true }}
>
{items.map((item, idx) => (
<TestimonialCard key={idx} {...item} />
))}
</motion.div>
</div>
</AnimatedSection>
)
}