<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.5">利润计算器 · 极简脚本</title>
<style>
* {
box-sizing: border-box;
margin: 0;
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
}
body {
min-height: 100vh;
background: linear-gradient(145deg, #f5f7fc 0%, #e9ecf3 100%);
display: flex;
justify-content: center;
align-items: center;
padding: 1.5rem;
}
.card {
max-width: 560px;
width: 100%;
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(4px);
background: #ffffff;
border-radius: 36px;
box-shadow: 0 20px 40px -12px rgba(0, 20, 30, 0.25),
0 4px 18px rgba(0,0,0,0.05);
padding: 2rem 2rem 2.5rem;
transition: all 0.2s ease;
border: 1px solid rgba(255,255,255,0.5);
}
h1 {
font-size: 1.9rem;
font-weight: 600;
letter-spacing: -0.02em;
color: #0b1b2b;
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.1rem;
}
h1 small {
font-size: 1rem;
font-weight: 400;
color: #4b6479;
margin-left: 0.3rem;
}
.subhead {
color: #3a536a;
border-left: 3px solid #4f8cff;
padding-left: 0.75rem;
margin: 0.5rem 0 1.8rem 0;
font-size: 0.95rem;
background: #f0f4fe;
border-radius: 0 12px 12px 0;
line-height: 1.4;
width: fit-content;
padding: 0.4rem 1rem 0.4rem 0.75rem;
}
.input-group {
margin-bottom: 1.4rem;
}
label {
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 500;
color: #1e3348;
font-size: 0.95rem;
letter-spacing: 0.01em;
margin-bottom: 0.3rem;
}
label .hint {
font-weight: 350;
font-size: 0.8rem;
color: #627a92;
}
.input-wrapper {
display: flex;
align-items: center;
background: #f8faff;
border-radius: 20px;
border: 1px solid #d9e1ec;
transition: 0.2s;
padding: 0 1rem;
}
.input-wrapper:focus-within {
border-color: #4f8cff;
box-shadow: 0 0 0 3px rgba(79, 140, 255, 0.15);
background: #ffffff;
}
.input-wrapper span.currency {
font-weight: 500;
color: #3f5b77;
margin-right: 0.5rem;
font-size: 1.1rem;
}
input[type="number"] {
width: 100%;
padding: 0.9rem 0 0.9rem 0.2rem;
border: none;
background: transparent;
font-size: 1.1rem;
font-weight: 450;
color: #0a1a2a;
outline: none;
-moz-appearance: textfield;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.inline-group {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.inline-group .input-group {
flex: 1;
min-width: 120px;
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin: 2rem 0 1.2rem 0;
align-items: center;
}
.btn {
background: #1d344a;
color: white;
border: none;
padding: 0.8rem 2rem;
border-radius: 40px;
font-weight: 500;
font-size: 1rem;
cursor: pointer;
transition: 0.15s ease;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.4rem;
box-shadow: 0 4px 8px rgba(0,20,40,0.1);
flex: 1 0 auto;
}
.btn:hover {
background: #264b67;
transform: scale(0.97);
box-shadow: 0 6px 12px rgba(28, 55, 94, 0.2);
}
.btn:active {
transform: scale(0.94);
}
.btn-outline {
background: transparent;
border: 1.5px solid #b6c9de;
color: #1e3a54;
box-shadow: none;
flex: 0.4;
}
.btn-outline:hover {
background: #eef4fd;
border-color: #7f9fc7;
transform: none;
box-shadow: none;
}
.result-panel {
background: #f2f6fe;
border-radius: 24px;
padding: 1.2rem 1.5rem;
margin-top: 1rem;
border: 1px solid #dce6f2;
transition: all 0.2s;
}
.result-row {
display: flex;
justify-content: space-between;
align-items: baseline;
padding: 0.4rem 0;
border-bottom: 1px dashed #d4e0ef;
}
.result-row:last-child {
border-bottom: none;
}
.result-row .label {
color: #30506b;
font-weight: 450;
font-size: 0.95rem;
}
.result-row .value {
font-weight: 600;
font-size: 1.2rem;
color: #092034;
letter-spacing: 0.01em;
}
.value.profit-positive {
color: #0d7c5f;
}
.value.profit-negative {
color: #b13e4b;
}
.value.profit-neutral {
color: #4a6a85;
}
.footnote {
margin-top: 1.6rem;
text-align: right;
font-size: 0.7rem;
color: #6c86a0;
border-top: 1px solid #e3ebf5;
padding-top: 0.9rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.badge {
background: #dce5f2;
padding: 0.2rem 1rem;
border-radius: 30px;
color: #1c334b;
font-size: 0.7rem;
font-weight: 500;
}
@media (max-width: 460px) {
.card { padding: 1.5rem; }
h1 { font-size: 1.6rem; flex-wrap: wrap; }
.inline-group { flex-direction: column; gap: 0; }
.btn { padding: 0.7rem 1.2rem; }
}
</style>
</head>
<body>
<div class="card" role="main">
<h1>
💰 利润计算器
<small>脚本 · 极简</small>
</h1>
<div class="subhead">📊 收入 − 成本 = 利润</div>
<!-- 收入 & 成本 输入区 -->
<div class="inline-group">
<div class="input-group">
<label for="revenue">
<span>总收入</span>
<span class="hint">销售额</span>
</label>
<div class="input-wrapper">
<span class="currency">¥</span>
<input type="number" id="revenue" placeholder="0.00" step="0.01" min="0" value="2500.00">
</div>
</div>
<div class="input-group">
<label for="cost">
<span>总成本</span>
<span class="hint">支出</span>
</label>
<div class="input-wrapper">
<span class="currency">¥</span>
<input type="number" id="cost" placeholder="0.00" step="0.01" min="0" value="1800.00">
</div>
</div>
</div>
<!-- 操作按钮区 -->
<div class="actions">
<button class="btn" id="calcBtn">🧮 计算利润</button>
<button class="btn btn-outline" id="resetBtn">⟲ 重置</button>
</div>
<!-- 结果展示面板 (脚本核心输出) -->
<div class="result-panel" id="resultPanel">
<div class="result-row">
<span class="label">📌 利润</span>
<span class="value profit-neutral" id="profitValue">¥700.00</span>
</div>
<div class="result-row">
<span class="label">📈 利润率</span>
<span class="value" id="marginValue">28.00%</span>
</div>
<div class="result-row">
<span class="label">📋 状态</span>
<span class="value" id="statusValue" style="font-size:1rem; font-weight:500;">✅ 盈利</span>
</div>
</div>
<!-- 脚注:快速说明 -->
<div class="footnote">
<span class="badge">⚡ 实时计算 · 一键脚本</span>
<span>收入 − 成本</span>
</div>
</div>
<script>
(function() {
'use strict';
// DOM 元素
const revenueInput = document.getElementById('revenue');
const costInput = document.getElementById('cost');
const profitSpan = document.getElementById('profitValue');
const marginSpan = document.getElementById('marginValue');
const statusSpan = document.getElementById('statusValue');
const calcBtn = document.getElementById('calcBtn');
const resetBtn = document.getElementById('resetBtn');
// ----- 核心:计算 & 更新视图 (利润计算脚本) -----
function computeProfit() {
// 1. 获取原始值并转为数字 (保留两位小数精度)
const revenue = parseFloat(revenueInput.value) || 0;
const cost = parseFloat(costInput.value) || 0;
// 2. 利润计算 (基础脚本逻辑)
const profit = revenue - cost;
// 3. 利润率计算 (当 revenue > 0 时计算,否则避免除以零)
let margin = 0;
if (revenue > 0) {
margin = (profit / revenue) * 100;
} else if (revenue === 0 && profit === 0) {
margin = 0; // 无收入无成本
} else if (revenue === 0 && profit < 0) {
// 收入为0但成本>0,利润率为 -Infinity (人为显示为 -100% 更直观)
margin = -100;
} else if (revenue === 0 && profit > 0) {
// 理论上不会出现 (成本为负才有可能,但成本输入限制>=0)
margin = 100;
}
// 4. 格式化数字 (保留两位小数,显示友好)
const formattedProfit = profit.toFixed(2);
const formattedMargin = margin.toFixed(2);
// 5. 更新利润显示 (带颜色状态)
profitSpan.textContent = `¥${formattedProfit}`;
// 清除所有状态类
profitSpan.classList.remove('profit-positive', 'profit-negative', 'profit-neutral');
if (profit > 0) {
profitSpan.classList.add('profit-positive');
} else if (profit < 0) {
profitSpan.classList.add('profit-negative');
} else {
profitSpan.classList.add('profit-neutral');
}
// 6. 更新利润率
let marginDisplay = `${formattedMargin}%`;
// 特殊显示:如果收入为0且成本>0,显示 -100%
if (revenue === 0 && cost > 0) {
marginDisplay = `-100.00%`;
} else if (revenue === 0 && cost === 0) {
marginDisplay = `0.00%`;
}
marginSpan.textContent = marginDisplay;
// 7. 状态文案 (表情 + 描述)
if (profit > 0) {
statusSpan.textContent = '✅ 盈利';
statusSpan.style.color = '#0d7c5f';
} else if (profit < 0) {
statusSpan.textContent = '❌ 亏损';
statusSpan.style.color = '#b13e4b';
} else {
statusSpan.textContent = '⚖️ 收支平衡';
statusSpan.style.color = '#4a6a85';
}
// 额外: 如果收入或成本为 NaN 兜底 (但parseInt会转0)
}
// ----- 重置到示例数值 (清晰展示) -----
function resetToDefault() {
revenueInput.value = '2500.00';
costInput.value = '1800.00';
computeProfit(); // 立即更新视图
}
// ----- 事件绑定 -----
// 1. 点击「计算利润」按钮
calcBtn.addEventListener('click', function(e) {
e.preventDefault();
// 对输入框做简单清洗:保留数字、允许空值转为0
let revVal = revenueInput.value.trim();
let costVal = costInput.value.trim();
if (revVal === '') revVal = '0';
if (costVal === '') costVal = '0';
// 如果包含非数字字符(除了小数点、负号,但为了友好统一过滤)
// 但 number input 已经限制,但用户可能输入 e 或特殊符号
const cleanedRev = parseFloat(revVal);
const cleanedCost = parseFloat(costVal);
if (!isNaN(cleanedRev)) revenueInput.value = cleanedRev.toFixed(2);
else revenueInput.value = '0.00';
if (!isNaN(cleanedCost)) costInput.value = cleanedCost.toFixed(2);
else costInput.value = '0.00';
computeProfit();
});
// 2. 重置按钮
resetBtn.addEventListener('click', function(e) {
e.preventDefault();
resetToDefault();
});
// 3. 支持回车触发计算 (在输入框按回车)
revenueInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
calcBtn.click();
}
});
costInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
calcBtn.click();
}
});
// 4. 防止输入非数字字符 (辅助)
function restrictNonNumeric(el) {
el.addEventListener('input', function() {
// 只允许数字、小数点、负号 (但负号一般不用于收入/成本,不过保留灵活性)
// 但number input 已处理;额外过滤掉字母e (允许科学计数法但容易错乱)
let val = this.value;
// 如果包含e或E,替换掉 (科学计数法让用户迷惑)
if (/[eE]/.test(val)) {
val = val.replace(/[eE]/g, '');
this.value = val;
}
// 空或者纯负号等保留,但parseFloat会处理
});
}
restrictNonNumeric(revenueInput);
restrictNonNumeric(costInput);
// 5. 处理失去焦点时格式化显示 (保留两位)
function formatOnBlur(input) {
input.addEventListener('blur', function() {
let val = this.value.trim();
if (val === '' || val === '-') {
this.value = '0.00';
return;
}
const num = parseFloat(val);
if (!isNaN(num)) {
// 限制负号可能,但收入/成本一般>=0, 但为了脚本宽容保留负号显示
this.value = num.toFixed(2);
} else {
// 如果完全无法解析,置为0
this.value = '0.00';
}
});
}
formatOnBlur(revenueInput);
formatOnBlur(costInput);
// 6. 页面加载完成自动计算 (显示初始demo值)
window.addEventListener('DOMContentLoaded', function() {
// 确保输入框有初始值
if (revenueInput.value === '') revenueInput.value = '2500.00';
if (costInput.value === '') costInput.value = '1800.00';
computeProfit();
});
// 额外:输入变化时若用户想自动计算?可以加双效,但保留手动计算风格。
// 但为了更好的体验,在输入框修改后按回车或点击计算。
// 不过我们可以添加一个可选的自动计算(感知不强,保留按钮主导)
// 增加双击空白计算彩蛋(小细节)
document.querySelector('.result-panel').addEventListener('dblclick', function() {
calcBtn.click();
});
// 暴露reset给调试 (非必须)
window.__resetProfit = resetToDefault;
})();
</script>
</body>
</html>
核心功能与操作流程
您可以通过输入收入与成本,快速获取利润、利润率以及盈亏状态,其核心计算逻辑清晰,操作直观。

- 数据输入:您可以在“总收入”和“总成本”输入框中分别填写数值,输入框已做格式化处理,并会限制非数字字符的输入。
- 计算与反馈:点击 “计算利润” 按钮或按键盘回车键,脚本将立即执行计算,结果面板会清晰显示:
- 利润:以绿色(盈利)、红色(亏损)或灰色(平衡)高亮显示。
- 利润率:以百分比形式呈现。
- 状态:用文字和表情符号(✅盈利、❌亏损、⚖️收支平衡)直观告知结果。
- 重置与便捷操作:您可以使用 “重置” 按钮恢复示例数据,双击结果面板区域也可快速触发计算。