// 思投录 - 投资决策与复盘工具 class VestMindApp { constructor() { this.currentTab = 'portfolio'; this.modal = document.getElementById('modal'); this.modalTitle = document.getElementById('modal-title'); this.modalBody = document.getElementById('modal-body'); this.closeModalBtn = document.getElementById('close-modal'); this.init(); } init() { this.bindEvents(); this.showPage('portfolio'); this.loadData(); } bindEvents() { // 底部导航栏事件 document.querySelectorAll('.nav-item').forEach(item => { item.addEventListener('click', (e) => { const tab = e.currentTarget.dataset.tab; this.switchTab(tab); }); }); // 模态框关闭事件 this.closeModalBtn.addEventListener('click', () => { this.hideModal(); }); this.modal.addEventListener('click', (e) => { if (e.target === this.modal) { this.hideModal(); } }); // 工具卡片点击事件 document.querySelectorAll('.tool-card').forEach(card => { card.addEventListener('click', (e) => { const tool = e.currentTarget.dataset.tool; this.openTool(tool); }); }); // 添加按钮事件 document.querySelectorAll('.add-btn').forEach(btn => { btn.addEventListener('click', (e) => { const page = e.currentTarget.closest('.page').id; this.showAddModal(page); }); }); } switchTab(tab) { // 更新导航栏状态 document.querySelectorAll('.nav-item').forEach(item => { item.classList.remove('active'); }); document.querySelector(`[data-tab="${tab}"]`).classList.add('active'); // 显示对应页面 this.showPage(tab); this.currentTab = tab; } showPage(pageId) { // 隐藏所有页面 document.querySelectorAll('.page').forEach(page => { page.classList.add('hidden'); }); // 显示目标页面 const targetPage = document.getElementById(`${pageId}-page`); if (targetPage) { targetPage.classList.remove('hidden'); } } loadData() { // 模拟数据加载 this.loadPortfolioData(); this.loadPlansData(); this.loadRecordsData(); } loadPortfolioData() { // 模拟持仓数据 const holdings = [ { name: '贵州茅台', code: '600519', shares: 100, currentPrice: 1850.00, profit: 2500.00, profitRate: 15.6 }, { name: '腾讯控股', code: '00700', shares: 200, currentPrice: 320.00, profit: -800.00, profitRate: -1.2 }, { name: '招商银行', code: '600036', shares: 500, currentPrice: 42.50, profit: 1250.00, profitRate: 6.2 } ]; this.renderHoldings(holdings); } renderHoldings(holdings) { const container = document.querySelector('.holdings-list'); if (!container) return; container.innerHTML = holdings.map(holding => `
${holding.name}
${holding.code}
${holding.shares}股
¥${holding.currentPrice.toFixed(2)}
${holding.profit >= 0 ? '+' : ''}¥${holding.profit.toFixed(2)} (${holding.profitRate >= 0 ? '+' : ''}${holding.profitRate}%)
`).join(''); } loadPlansData() { // 模拟交易计划数据 const plans = [ { name: '招商银行', code: '600036', targetPrice: 45.00, amount: 10000, deadline: '2024-03-15', progress: 60, status: 'pending' }, { name: '中国平安', code: '601318', targetPrice: 55.00, amount: 15000, deadline: '2024-04-20', progress: 30, status: 'pending' } ]; this.renderPlans(plans); } renderPlans(plans) { const container = document.querySelector('.plans-list'); if (!container) return; container.innerHTML = plans.map(plan => `
${plan.name}
${plan.code}
进行中
目标价格: ¥${plan.targetPrice.toFixed(2)}
计划金额: ¥${plan.amount.toLocaleString()}
截止时间: ${plan.deadline}
已完成 ${plan.progress}%
`).join(''); } loadRecordsData() { // 模拟交易记录数据 const records = [ { date: '2024-01-15', type: 'buy', name: '贵州茅台', code: '600519', shares: 100, price: 1600.00, thoughts: '基于茅台品牌价值和长期增长潜力,认为当前价格具有投资价值。白酒行业龙头地位稳固,现金流优秀。' }, { date: '2024-01-10', type: 'sell', name: '比亚迪', code: '002594', shares: 200, price: 280.00, thoughts: '新能源汽车行业竞争加剧,估值偏高,选择获利了结。' } ]; this.renderRecords(records); } renderRecords(records) { const container = document.querySelector('.timeline'); if (!container) return; container.innerHTML = records.map(record => `
${record.date}
${record.name}
${record.code}
${record.type === 'buy' ? '买入' : '卖出'}
数量: ${record.shares}股
价格: ¥${record.price.toFixed(2)}

交易思考:

${record.thoughts}

`).join(''); } openTool(tool) { switch (tool) { case 'checklist': this.showChecklistModal(); break; case 'calculator': this.showCalculatorModal(); break; case 'valuation': this.showValuationModal(); break; case 'freedom': this.showFreedomModal(); break; } } showChecklistModal() { this.modalTitle.textContent = '投资检查清单'; this.modalBody.innerHTML = `

买入检查清单

卖出检查清单

`; this.showModal(); } showCalculatorModal() { this.modalTitle.textContent = '复利计算器'; this.modalBody.innerHTML = `
`; this.showModal(); } calculateCompound() { const initialAmount = parseFloat(document.getElementById('initial-amount').value) || 0; const annualInvestment = parseFloat(document.getElementById('annual-investment').value) || 0; const growthRate = parseFloat(document.getElementById('growth-rate').value) || 0; const years = parseInt(document.getElementById('years').value) || 0; const rate = growthRate / 100; let totalInvestment = initialAmount + annualInvestment * years; let finalAmount = initialAmount * Math.pow(1 + rate, years); // 计算每年投入的复利 for (let i = 1; i <= years; i++) { finalAmount += annualInvestment * Math.pow(1 + rate, years - i); } const totalProfit = finalAmount - totalInvestment; document.getElementById('total-investment').textContent = `¥${totalInvestment.toLocaleString()}`; document.getElementById('final-amount').textContent = `¥${finalAmount.toLocaleString()}`; document.getElementById('total-profit').textContent = `¥${totalProfit.toLocaleString()}`; document.getElementById('calculator-result').style.display = 'block'; } showValuationModal() { this.modalTitle.textContent = '估值工具'; this.modalBody.innerHTML = `
`; this.showModal(); } calculateTangValuation() { const netProfit = parseFloat(document.getElementById('net-profit').value) || 0; const riskFreeRate = parseFloat(document.getElementById('risk-free-rate').value) || 0; const peRatio = parseFloat(document.getElementById('pe-ratio').value) || 0; const reasonablePE = 1 / (riskFreeRate / 100); const valuation = netProfit * Math.min(peRatio, reasonablePE); document.getElementById('tang-value').textContent = `¥${valuation.toFixed(2)}亿`; document.getElementById('tang-result').style.display = 'block'; } showFreedomModal() { this.modalTitle.textContent = '自由目标'; this.modalBody.innerHTML = `
`; this.showModal(); } calculateFreedom() { const targetAssets = parseFloat(document.getElementById('target-assets').value) || 0; const currentAssets = parseFloat(document.getElementById('current-assets').value) || 0; const growthRate = parseFloat(document.getElementById('freedom-growth-rate').value) || 0; const annualInvestment = parseFloat(document.getElementById('freedom-annual-investment').value) || 0; const rate = growthRate / 100; let years = 0; let assets = currentAssets; // 模拟逐年增长 while (assets < targetAssets && years < 50) { assets = assets * (1 + rate) + annualInvestment; years++; } const totalInvestment = currentAssets + annualInvestment * years; const currentAge = 30; // 假设当前年龄 const targetAge = currentAge + years; document.getElementById('freedom-years').textContent = `${years}年`; document.getElementById('freedom-age').textContent = `${targetAge}岁`; document.getElementById('freedom-total-investment').textContent = `¥${totalInvestment.toFixed(2)}万`; document.getElementById('freedom-result').style.display = 'block'; } showAddModal(page) { switch (page) { case 'portfolio-page': this.showAddHoldingModal(); break; case 'plans-page': this.showAddPlanModal(); break; case 'records-page': this.showAddRecordModal(); break; } } showAddHoldingModal() { this.modalTitle.textContent = '添加持仓'; this.modalBody.innerHTML = `
`; this.showModal(); } showAddPlanModal() { this.modalTitle.textContent = '新建交易计划'; this.modalBody.innerHTML = `
`; this.showModal(); } showAddRecordModal() { this.modalTitle.textContent = '记录交易'; this.modalBody.innerHTML = `
`; this.showModal(); } addHolding() { // 模拟添加持仓 this.showToast('持仓添加成功!'); this.hideModal(); } addPlan() { // 模拟添加计划 this.showToast('交易计划创建成功!'); this.hideModal(); } addRecord() { // 模拟添加记录 this.showToast('交易记录添加成功!'); this.hideModal(); } showModal() { this.modal.classList.add('show'); document.body.style.overflow = 'hidden'; } hideModal() { this.modal.classList.remove('show'); document.body.style.overflow = 'auto'; } showToast(message) { // 创建提示框 const toast = document.createElement('div'); toast.className = 'toast'; toast.textContent = message; toast.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0, 0, 0, 0.8); color: white; padding: 12px 24px; border-radius: 8px; font-size: 14px; z-index: 10000; opacity: 0; transition: opacity 0.3s ease; `; document.body.appendChild(toast); // 显示动画 setTimeout(() => { toast.style.opacity = '1'; }, 100); // 自动隐藏 setTimeout(() => { toast.style.opacity = '0'; setTimeout(() => { document.body.removeChild(toast); }, 300); }, 2000); } } // 初始化应用 const app = new VestMindApp(); // 添加一些额外的样式 const additionalStyles = ` `; document.head.insertAdjacentHTML('beforeend', additionalStyles);