Files
LLHS/回报率预测计算器.html
2025-09-16 17:34:34 +08:00

370 lines
24 KiB
HTML
Raw Permalink 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.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>回报率预测计算器</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#2563eb',
secondary: '#38bdf8'
}
}
}
}
</script>
</head>
<body class="bg-gray-50 font-sans text-gray-800">
<div class="min-h-screen px-4 py-6 md:px-8 md:py-8">
<div class="max-w-6xl mx-auto bg-white/95 shadow-xl rounded-2xl p-6 md:p-8">
<header class="mb-8">
<h1 class="text-2xl md:text-3xl font-bold text-gray-900 mb-2">回报率预测计算器</h1>
<p class="text-gray-600 text-sm md:text-base">根据《回报率预测》文档的假设提供默认值,可随场景调整实时查看财务指标。</p>
</header>
<!-- Summary Cards -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
<div class="bg-gradient-to-br from-primary to-secondary rounded-xl p-5 text-white">
<h2 class="text-xs md:text-sm uppercase tracking-wider font-semibold mb-3">月度净利润</h2>
<div id="monthlyNetProfit" class="text-2xl md:text-3xl font-bold mb-2">¥ 33.00</div>
<p class="text-xs text-blue-100">= 月毛利 - 固定运营成本</p>
</div>
<div class="bg-gradient-to-br from-primary to-secondary rounded-xl p-5 text-white">
<h2 class="text-xs md:text-sm uppercase tracking-wider font-semibold mb-3">投资回收期</h2>
<div id="paybackPeriod" class="text-2xl md:text-3xl font-bold mb-2">54.5 个月</div>
<p class="text-xs text-blue-100">= 总投资 / 月净利润</p>
</div>
<div class="bg-gradient-to-br from-primary to-secondary rounded-xl p-5 text-white">
<h2 class="text-xs md:text-sm uppercase tracking-wider font-semibold mb-3">年化 ROI</h2>
<div id="annualROI" class="text-2xl md:text-3xl font-bold mb-2">22.0%</div>
<p class="text-xs text-blue-100">= (年净利润 / 总投资) × 100%</p>
</div>
</div>
<!-- Input Sections -->
<section class="mb-8">
<h3 class="text-lg md:text-xl font-semibold text-gray-900 mb-4">核心量化假设</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">日均废纸板回收量 (公斤)</span>
<input id="dailyCardboard" type="number" min="0" step="0.1" value="20"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">日均塑料瓶回收量 (公斤)</span>
<input id="dailyPet" type="number" min="0" step="0.1" value="10"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">月计费天数 (天)</span>
<input id="daysPerMonth" type="number" min="1" step="1" value="30"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">运营站点数量 (个)</span>
<input id="siteCount" type="number" min="1" step="1" value="5"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">废纸板回收价 ¥/公斤 (给用户)</span>
<input id="buyPriceCardboard" type="number" min="0" step="0.01" value="0.8"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">废纸板出售价 ¥/公斤 (给打包站)</span>
<input id="sellPriceCardboard" type="number" min="0" step="0.01" value="1.2"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">塑料瓶回收价 ¥/公斤 (给用户)</span>
<input id="buyPricePet" type="number" min="0" step="0.01" value="1.4"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">塑料瓶出售价 ¥/公斤 (给打包站)</span>
<input id="sellPricePet" type="number" min="0" step="0.01" value="2.0"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
</div>
</section>
<section class="mb-8">
<h3 class="text-lg md:text-xl font-semibold text-gray-900 mb-4">运营及投入假设</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">场地合作分成 (占销售总收入 %)</span>
<input id="siteFeePercent" type="number" min="0" step="0.1" value="10"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">月物流清运成本 (¥)</span>
<input id="logisticsCost" type="number" min="0" step="1" value="220"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">设备维护与网络费 (¥/月)</span>
<input id="maintenanceCost" type="number" min="0" step="1" value="27"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">其他运营成本 (¥/月)</span>
<input id="otherCost" type="number" min="0" step="1" value="50"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">单站设备投入 (¥)</span>
<input id="equipmentCost" type="number" min="0" step="10" value="1500"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
<label class="block">
<span class="text-sm font-medium text-gray-700 mb-2 block">部署及安装成本 (¥)</span>
<input id="deploymentCost" type="number" min="0" step="10" value="300"
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-base focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none transition-colors" />
</label>
</div>
</section>
<!-- Results Section -->
<section class="space-y-6">
<h3 class="text-lg md:text-xl font-semibold text-gray-900">产出指标</h3>
<!-- 产出指标表格 -->
<div class="overflow-x-auto">
<table class="w-full border-collapse bg-white rounded-lg overflow-hidden shadow-sm">
<thead>
<tr class="bg-blue-50">
<th class="text-left px-4 py-3 text-sm font-semibold text-gray-900">指标</th>
<th class="text-right px-4 py-3 text-sm font-semibold text-gray-900">废纸板</th>
<th class="text-right px-4 py-3 text-sm font-semibold text-gray-900">塑料瓶</th>
<th class="text-right px-4 py-3 text-sm font-semibold text-gray-900">合计</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 text-sm text-gray-900">月度回收量 (公斤)</td>
<td id="monthlyCardboardKg" class="px-4 py-3 text-sm text-right text-gray-600">600.0</td>
<td id="monthlyPetKg" class="px-4 py-3 text-sm text-right text-gray-600">300.0</td>
<td id="monthlyTotalKg" class="px-4 py-3 text-sm text-right font-medium text-gray-900">900.0</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">给用户回收金 (¥)</td>
<td id="payoutCardboard" class="px-4 py-3 text-sm text-right text-gray-600">¥ 480.00</td>
<td id="payoutPet" class="px-4 py-3 text-sm text-right text-gray-600">¥ 420.00</td>
<td id="payoutTotal" class="px-4 py-3 text-sm text-right font-medium text-gray-900">¥ 900.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">销售收入 (¥)</td>
<td id="saleCardboard" class="px-4 py-3 text-sm text-right text-gray-600">¥ 720.00</td>
<td id="salePet" class="px-4 py-3 text-sm text-right text-gray-600">¥ 600.00</td>
<td id="saleTotal" class="px-4 py-3 text-sm text-right font-medium text-gray-900">¥ 1,320.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">毛利 (¥)</td>
<td id="grossCardboard" class="px-4 py-3 text-sm text-right text-gray-600">¥ 240.00</td>
<td id="grossPet" class="px-4 py-3 text-sm text-right text-gray-600">¥ 180.00</td>
<td id="grossTotal" class="px-4 py-3 text-sm text-right font-medium text-primary">¥ 420.00</td>
</tr>
</tbody>
</table>
</div>
<!-- 成本拆解表格 -->
<div class="overflow-x-auto">
<table class="w-full border-collapse bg-white rounded-lg overflow-hidden shadow-sm">
<thead>
<tr class="bg-blue-50">
<th class="text-left px-4 py-3 text-sm font-semibold text-gray-900">成本拆解</th>
<th class="text-right px-4 py-3 text-sm font-semibold text-gray-900">金额 (¥)</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 text-sm text-gray-900">场地合作费</td>
<td id="siteFee" class="px-4 py-3 text-sm text-right text-gray-600">¥ 90.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">月物流清运成本</td>
<td id="logisticsCostCell" class="px-4 py-3 text-sm text-right text-gray-600">¥ 220.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">设备维护与网络费</td>
<td id="maintenanceCostCell" class="px-4 py-3 text-sm text-right text-gray-600">¥ 27.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">其他运营成本</td>
<td id="otherCostCell" class="px-4 py-3 text-sm text-right text-gray-600">¥ 50.00</td>
</tr>
<tr class="bg-gray-50">
<td class="px-4 py-3 text-sm font-semibold text-gray-900">固定成本合计</td>
<td id="fixedCostTotal" class="px-4 py-3 text-sm text-right font-semibold text-gray-900">¥ 387.00</td>
</tr>
</tbody>
</table>
</div>
<!-- 投资与回报表格 -->
<div class="overflow-x-auto">
<table class="w-full border-collapse bg-white rounded-lg overflow-hidden shadow-sm">
<thead>
<tr class="bg-blue-50">
<th class="text-left px-4 py-3 text-sm font-semibold text-gray-900">投资与回报</th>
<th class="text-right px-4 py-3 text-sm font-semibold text-gray-900">金额 / 指标</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 text-sm text-gray-900">总投资 (Capex)</td>
<td id="totalInvestment" class="px-4 py-3 text-sm text-right text-gray-600">¥ 1,800.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">月度净利润</td>
<td id="netProfitCell" class="px-4 py-3 text-sm text-right font-medium text-primary">¥ 33.00</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">投资回收期</td>
<td id="paybackCell" class="px-4 py-3 text-sm text-right text-gray-600">54.5 个月</td>
</tr>
<tr>
<td class="px-4 py-3 text-sm text-gray-900">年化投资回报率</td>
<td id="annualRoiCell" class="px-4 py-3 text-sm text-right font-medium text-green-600">22.0%</td>
</tr>
</tbody>
</table>
</div>
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
<p class="text-sm text-yellow-800">
<span class="font-semibold">提示:</span>
若月度净利润≤0则投资回收期视为"尚无法回收",请通过提升日均回收量或优化成本结构来改进模型。
</p>
</div>
</section>
</div>
</div>
<script>
// 工具函数安全读取输入值若为空则返回0
function getValue(id) {
const value = parseFloat(document.getElementById(id).value);
return Number.isFinite(value) ? value : 0;
}
// 工具函数:格式化为货币展示
function formatCurrency(value) {
return `¥ ${value.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}
// 工具函数:格式化数值,保留一位小数
function formatNumber(value) {
return value.toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 });
}
// 核心计算逻辑
function recalc() {
const dailyCardboard = getValue("dailyCardboard");
const dailyPet = getValue("dailyPet");
const days = getValue("daysPerMonth");
const siteCount = Math.max(getValue("siteCount"), 0);
const buyCardboard = getValue("buyPriceCardboard");
const sellCardboard = getValue("sellPriceCardboard");
const buyPet = getValue("buyPricePet");
const sellPet = getValue("sellPricePet");
const siteFeePercent = getValue("siteFeePercent") / 100;
const logisticsCost = getValue("logisticsCost");
const maintenanceCost = getValue("maintenanceCost");
const otherCost = getValue("otherCost");
const equipmentCost = getValue("equipmentCost");
const deploymentCost = getValue("deploymentCost");
const monthlyCardboardKg = dailyCardboard * days * siteCount;
const monthlyPetKg = dailyPet * days * siteCount;
const monthlyTotalKg = monthlyCardboardKg + monthlyPetKg;
const payoutCardboard = monthlyCardboardKg * buyCardboard;
const payoutPet = monthlyPetKg * buyPet;
const payoutTotal = payoutCardboard + payoutPet;
const saleCardboard = monthlyCardboardKg * sellCardboard;
const salePet = monthlyPetKg * sellPet;
const saleTotal = saleCardboard + salePet;
const grossCardboard = saleCardboard - payoutCardboard;
const grossPet = salePet - payoutPet;
const grossTotal = grossCardboard + grossPet;
const logisticsCostTotal = logisticsCost * siteCount;
const maintenanceCostTotal = maintenanceCost * siteCount;
const otherCostTotal = otherCost * siteCount;
const siteFee = saleTotal * siteFeePercent;
const fixedCostTotal = siteFee + logisticsCostTotal + maintenanceCostTotal + otherCostTotal;
const monthlyNetProfit = grossTotal - fixedCostTotal;
const totalInvestmentPerSite = equipmentCost + deploymentCost;
const totalInvestment = totalInvestmentPerSite * siteCount;
const annualNetProfit = monthlyNetProfit * 12;
const paybackMonths = monthlyNetProfit > 0 ? totalInvestment / monthlyNetProfit : Infinity;
const annualROI = monthlyNetProfit > 0 ? (annualNetProfit / totalInvestment) * 100 : 0;
// 更新表格及摘要展示
document.getElementById("monthlyCardboardKg").textContent = formatNumber(monthlyCardboardKg);
document.getElementById("monthlyPetKg").textContent = formatNumber(monthlyPetKg);
document.getElementById("monthlyTotalKg").textContent = formatNumber(monthlyTotalKg);
document.getElementById("payoutCardboard").textContent = formatCurrency(payoutCardboard);
document.getElementById("payoutPet").textContent = formatCurrency(payoutPet);
document.getElementById("payoutTotal").textContent = formatCurrency(payoutTotal);
document.getElementById("saleCardboard").textContent = formatCurrency(saleCardboard);
document.getElementById("salePet").textContent = formatCurrency(salePet);
document.getElementById("saleTotal").textContent = formatCurrency(saleTotal);
document.getElementById("grossCardboard").textContent = formatCurrency(grossCardboard);
document.getElementById("grossPet").textContent = formatCurrency(grossPet);
document.getElementById("grossTotal").textContent = formatCurrency(grossTotal);
document.getElementById("siteFee").textContent = formatCurrency(siteFee);
document.getElementById("logisticsCostCell").textContent = formatCurrency(logisticsCostTotal);
document.getElementById("maintenanceCostCell").textContent = formatCurrency(maintenanceCostTotal);
document.getElementById("otherCostCell").textContent = formatCurrency(otherCostTotal);
document.getElementById("fixedCostTotal").textContent = formatCurrency(fixedCostTotal);
document.getElementById("totalInvestment").textContent = formatCurrency(totalInvestment);
const netProfitLabel = formatCurrency(monthlyNetProfit);
document.getElementById("monthlyNetProfit").textContent = netProfitLabel;
document.getElementById("netProfitCell").textContent = netProfitLabel;
if (monthlyNetProfit > 0) {
const paybackText = `${paybackMonths.toFixed(1)} 个月`;
const annualRoiText = `${annualROI.toFixed(1)}%`;
document.getElementById("paybackPeriod").textContent = paybackText;
document.getElementById("annualROI").textContent = annualRoiText;
document.getElementById("paybackCell").textContent = paybackText;
document.getElementById("annualRoiCell").textContent = annualRoiText;
} else {
const warningText = "尚无法回收";
document.getElementById("paybackPeriod").textContent = warningText;
document.getElementById("paybackCell").textContent = warningText;
document.getElementById("annualROI").textContent = "0.0%";
document.getElementById("annualRoiCell").textContent = "0.0%";
}
}
// 监听所有输入框,实时刷新
document.querySelectorAll("input[type='number']").forEach((input) => {
input.addEventListener("input", recalc);
});
// 初始化计算一次,确保默认值正确呈现
recalc();
</script>
</body>
</html>