图

说明:本来想用opencode +SKILL 来完成 电脑DIY组装报价系统 但是他变化的因素有点大,老是提出配置不对,输出结果要变化多次,知道是因为他收集数据 新的程度有限导致的,所以 就用html 固定他的输入结果,其它变化和录入 交给opencode

代码:index.html
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>电脑DIY组装报价系统</title>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700&family=Noto+Sans+SC:wght@400;500;600&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--bg: #0d0d12;
--card: #15151d;
--card-hover: #1a1a25;
--border: #252535;
--cyan: #00e5ff;
--purple: #a855f7;
--pink: #ec4899;
--green: #22c55e;
--orange: #f97316;
--text: #e5e5e5;
--text2: #b0b0b0;
--muted: #71717a;
--input-bg: #0a0a0f;
--shadow: rgba(0,0,0,0.3);
}
[data-theme="light"] {
--bg: #f0f2f5;
--card: #ffffff;
--card-hover: #f8f9fa;
--border: #e2e8f0;
--cyan: #0891b2;
--purple: #7c3aed;
--pink: #db2777;
--green: #16a34a;
--orange: #ea580c;
--text: #1a1a2e;
--text2: #4a5568;
--muted: #94a3b8;
--input-bg: #f8fafc;
--shadow: rgba(0,0,0,0.08);
}
body {
font-family: 'Noto Sans SC', sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
transition: background 0.3s, color 0.3s;
}
body::before {
content: '';
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background:
radial-gradient(ellipse at 10% 20%, rgba(0,229,255,0.05) 0%, transparent 50%),
radial-gradient(ellipse at 90% 80%, rgba(168,85,247,0.05) 0%, transparent 50%);
pointer-events: none;
z-index: 0;
}
[data-theme="light"] body::before {
background:
radial-gradient(ellipse at 10% 20%, rgba(8,145,178,0.06) 0%, transparent 50%),
radial-gradient(ellipse at 90% 80%, rgba(124,58,237,0.06) 0%, transparent 50%);
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 16px;
position: relative;
z-index: 1;
}
/* 头部 */
header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0;
border-bottom: 1px solid var(--border);
margin-bottom: 16px;
}
.header-left {
display: flex;
align-items: center;
gap: 16px;
}
.logo {
font-family: 'Orbitron', sans-serif;
font-size: 1.4rem;
font-weight: 700;
background: linear-gradient(135deg, var(--cyan), var(--purple));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.subtitle {
font-size: 0.75rem;
color: var(--muted);
}
.header-right {
display: flex;
align-items: center;
gap: 20px;
}
.stats {
display: flex;
gap: 20px;
}
.stat { text-align: center; }
.stat-label {
font-size: 0.65rem;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.stat-value {
font-family: 'Orbitron', sans-serif;
font-size: 1rem;
font-weight: 700;
}
.stat-value.cyan { color: var(--cyan); }
.stat-value.green { color: var(--green); }
/* 主题切换 */
.theme-toggle {
position: relative;
width: 56px;
height: 28px;
background: var(--card);
border: 1px solid var(--border);
border-radius: 14px;
cursor: pointer;
transition: all 0.3s;
display: flex;
align-items: center;
padding: 0 4px;
}
.theme-toggle:hover { border-color: var(--cyan); }
.theme-toggle-ball {
width: 20px;
height: 20px;
background: linear-gradient(135deg, var(--cyan), var(--purple));
border-radius: 50%;
transition: transform 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
[data-theme="light"] .theme-toggle-ball { transform: translateX(28px); }
.theme-icons {
position: absolute;
width: 100%;
display: flex;
justify-content: space-between;
padding: 0 6px;
font-size: 0.75rem;
pointer-events: none;
}
.theme-icon-moon { opacity: 1; }
.theme-icon-sun { opacity: 0.5; }
[data-theme="light"] .theme-icon-moon { opacity: 0.5; }
[data-theme="light"] .theme-icon-sun { opacity: 1; }
/* 预设方案 */
.presets {
display: flex;
gap: 10px;
margin-bottom: 16px;
}
.preset-btn {
flex: 1;
padding: 10px 14px;
background: var(--card);
border: 1px solid var(--border);
border-radius: 10px;
color: var(--text);
cursor: pointer;
display: flex;
align-items: center;
gap: 10px;
transition: all 0.2s;
}
.preset-btn:hover {
border-color: var(--cyan);
transform: translateY(-2px);
box-shadow: 0 4px 15px var(--shadow);
}
.preset-btn .icon { font-size: 1.4rem; }
.preset-btn .info { text-align: left; }
.preset-btn .name { font-weight: 600; font-size: 0.85rem; }
.preset-btn .price { font-size: 0.75rem; color: var(--cyan); font-family: 'Orbitron'; margin-top: 2px; }
/* 主布局 */
.main {
display: grid;
grid-template-columns: 1fr 320px;
gap: 16px;
}
@media (max-width: 900px) {
.main { grid-template-columns: 1fr; }
.presets { flex-wrap: wrap; }
.header-left { flex-direction: column; align-items: flex-start; gap: 4px; }
.stats { gap: 14px; }
}
/* 配件列表 */
.components {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
@media (max-width: 700px) {
.components { grid-template-columns: 1fr; }
}
.comp-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 10px;
padding: 5px 12px 5px 12px;
transition: all 0.2s;
}
.comp-card:hover {
border-color: var(--cyan);
box-shadow: 0 2px 10px var(--shadow);
}
.comp-card.selected {
border-color: var(--green);
background: linear-gradient(135deg, rgba(34,197,94,0.08), transparent);
}
.comp-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
}
.comp-icon {
width: 32px;
height: 32px;
background: linear-gradient(135deg, rgba(0,229,255,0.15), rgba(168,85,247,0.15));
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1rem;
}
[data-theme="light"] .comp-icon {
background: linear-gradient(135deg, rgba(8,145,178,0.12), rgba(124,58,237,0.12));
}
.comp-name { font-weight: 600; font-size: 0.85rem; }
.comp-badge {
margin-left: auto;
font-size: 0.6rem;
padding: 2px 8px;
border-radius: 10px;
background: rgba(236,72,153,0.15);
color: var(--pink);
}
[data-theme="light"] .comp-badge {
background: rgba(219,39,119,0.1);
}
.comp-row {
display: flex;
gap: 6px;
}
.comp-select {
flex: 1;
padding: 8px 10px;
background: var(--input-bg);
border: 1px solid var(--border);
border-radius: 6px;
color: var(--text);
font-size: 0.78rem;
font-family: inherit;
cursor: pointer;
transition: all 0.2s;
}
.comp-select:focus {
outline: none;
border-color: var(--cyan);
box-shadow: 0 0 0 3px rgba(0,229,255,0.1);
}
/* 添加按钮 */
.btn-add {
width: 34px;
height: 34px;
background: linear-gradient(135deg, var(--orange), var(--pink));
border: none;
border-radius: 6px;
color: #fff;
font-size: 1.1rem;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.btn-add:hover {
transform: scale(1.1);
box-shadow: 0 2px 10px rgba(249,115,22,0.4);
}
.btn-del-custom {
width: 34px;
height: 34px;
background: rgba(236,72,153,0.2);
border: 1px solid rgba(236,72,153,0.3);
border-radius: 6px;
color: var(--pink);
font-size: 0.9rem;
cursor: pointer;
transition: all 0.2s;
display: none;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.btn-del-custom.show { display: flex; }
.btn-del-custom:hover { background: rgba(236,72,153,0.4); }
.comp-price {
margin-top: 6px;
font-family: 'Orbitron';
font-size: 0.82rem;
color: var(--green);
text-align: right;
min-height: 1.2em;
font-weight: 600;
}
/* 新增表单 */
.add-form {
margin-top: 8px;
padding: 10px;
background: var(--input-bg);
border-radius: 8px;
border: 1px dashed var(--orange);
display: none;
animation: slideDown 0.2s ease;
}
.add-form.show { display: block; }
@keyframes slideDown {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
.add-form-row {
display: flex;
gap: 6px;
margin-bottom: 8px;
}
.add-form-row:last-child { margin-bottom: 0; }
.add-input {
flex: 1;
padding: 7px 10px;
background: var(--card);
border: 1px solid var(--border);
border-radius: 5px;
color: var(--text);
font-size: 0.75rem;
font-family: inherit;
}
.add-input:focus { outline: none; border-color: var(--orange); }
.add-input::placeholder { color: var(--muted); }
.add-input.name { flex: 2; }
.add-input.price { flex: 1; }
.add-input.watt { flex: 1; }
.add-btns {
display: flex;
gap: 6px;
}
.btn-confirm {
flex: 1;
padding: 7px;
background: linear-gradient(135deg, var(--orange), var(--pink));
border: none;
border-radius: 5px;
color: #fff;
font-size: 0.75rem;
font-weight: 600;
font-family: inherit;
cursor: pointer;
transition: all 0.2s;
}
.btn-confirm:hover { transform: translateY(-1px); }
.btn-cancel {
padding: 7px 12px;
background: transparent;
border: 1px solid var(--border);
border-radius: 5px;
color: var(--text);
font-size: 0.75rem;
font-family: inherit;
cursor: pointer;
transition: all 0.2s;
}
.btn-cancel:hover { border-color: var(--pink); color: var(--pink); }
/* 报价面板 */
.quote-panel {
position: sticky;
top: 16px;
}
.quote-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 16px;
}
.quote-title {
font-size: 0.9rem;
font-weight: 600;
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 8px;
}
.config-list {
max-height: 300px;
overflow-y: auto;
margin-bottom: 12px;
}
.config-list::-webkit-scrollbar { width: 4px; }
.config-list::-webkit-scrollbar-track { background: var(--input-bg); border-radius: 2px; }
.config-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
.config-item {
display: flex;
align-items: center;
gap: 8px;
padding: 8px;
background: var(--input-bg);
border-radius: 6px;
margin-bottom: 6px;
font-size: 0.78rem;
}
.config-item:hover { background: var(--card-hover); }
.config-item-type {
font-size: 0.62rem;
color: var(--cyan);
min-width: 36px;
font-weight: 600;
text-transform: uppercase;
}
.config-item-name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--text2);
}
.config-item-custom {
font-size: 0.6rem;
padding: 1px 4px;
background: rgba(249,115,22,0.2);
color: var(--orange);
border-radius: 3px;
margin-left: 4px;
}
.config-item-price {
font-family: 'Orbitron';
font-size: 0.72rem;
color: var(--green);
font-weight: 600;
}
.config-item-remove {
background: none;
border: none;
color: var(--pink);
cursor: pointer;
opacity: 0.5;
font-size: 0.8rem;
transition: opacity 0.2s;
padding: 2px;
}
.config-item-remove:hover { opacity: 1; }
.empty-msg {
text-align: center;
padding: 24px;
color: var(--muted);
font-size: 0.78rem;
line-height: 1.6;
}
.empty-msg-icon {
font-size: 2rem;
margin-bottom: 8px;
opacity: 0.5;
}
/* 价格 */
.divider {
height: 1px;
background: var(--border);
margin: 12px 0;
}
.price-row {
display: flex;
justify-content: space-between;
font-size: 0.78rem;
margin-bottom: 6px;
}
.price-row .label { color: var(--muted); }
.price-row .value { font-family: 'Orbitron'; font-weight: 500; }
.total-row {
font-size: 0.95rem;
font-weight: 600;
margin-top: 8px;
padding-top: 8px;
border-top: 1px solid var(--border);
}
.total-row .value {
font-size: 1.15rem;
background: linear-gradient(135deg, var(--cyan), var(--green));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* 功耗提示 */
.watt-warning {
background: rgba(255,170,0,0.1);
border: 1px solid rgba(255,170,0,0.3);
border-radius: 8px;
padding: 10px 12px;
margin-top: 12px;
font-size: 0.75rem;
color: #ffaa00;
display: none;
}
.watt-warning.show { display: flex; align-items: center; gap: 8px; }
[data-theme="light"] .watt-warning {
background: rgba(234,179,8,0.1);
border-color: rgba(234,179,8,0.3);
color: #ca8a04;
}
/* 按钮组 */
.btns {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
margin-top: 12px;
}
.btns-full {
grid-column: span 2;
}
.btn {
padding: 10px;
border: none;
border-radius: 8px;
font-size: 0.78rem;
font-weight: 600;
font-family: inherit;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
gap: 4px;
}
.btn-primary {
background: linear-gradient(135deg, var(--cyan), var(--purple));
color: #fff;
}
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 4px 15px rgba(0,229,255,0.3); }
.btn-secondary {
background: transparent;
border: 1px solid var(--border);
color: var(--text);
}
.btn-secondary:hover { border-color: var(--cyan); background: rgba(0,229,255,0.05); }
.btn-danger {
background: rgba(236,72,153,0.1);
border: 1px solid rgba(236,72,153,0.3);
color: var(--pink);
}
.btn-danger:hover { background: rgba(236,72,153,0.2); }
.btn-outline {
background: transparent;
border: 1px solid var(--border);
color: var(--text);
}
.btn-outline:hover { border-color: var(--green); background: rgba(34,197,94,0.05); }
/* 管理自定义配件 */
.manage-section {
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid var(--border);
}
.manage-title {
font-size: 0.75rem;
color: var(--muted);
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 6px;
}
.manage-list {
max-height: 120px;
overflow-y: auto;
}
.manage-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 8px;
background: var(--input-bg);
border-radius: 5px;
margin-bottom: 4px;
font-size: 0.72rem;
}
.manage-item-info {
display: flex;
align-items: center;
gap: 8px;
flex: 1;
overflow: hidden;
}
.manage-item-type {
font-size: 0.6rem;
color: var(--orange);
background: rgba(249,115,22,0.15);
padding: 1px 5px;
border-radius: 3px;
}
.manage-item-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--text2);
}
.manage-item-price {
color: var(--green);
font-family: 'Orbitron';
font-size: 0.7rem;
margin-left: 8px;
}
.manage-item-del {
background: none;
border: none;
color: var(--pink);
cursor: pointer;
opacity: 0.6;
font-size: 0.8rem;
padding: 2px 6px;
}
.manage-item-del:hover { opacity: 1; }
.manage-empty {
text-align: center;
padding: 12px;
color: var(--muted);
font-size: 0.72rem;
}
/* Toast */
.toast {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%) translateY(60px);
background: var(--card);
border: 1px solid var(--green);
border-radius: 10px;
padding: 12px 24px;
font-size: 0.85rem;
z-index: 100;
opacity: 0;
transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
box-shadow: 0 10px 30px var(--shadow);
display: flex;
align-items: center;
gap: 8px;
}
.toast.show {
transform: translateX(-50%) translateY(0);
opacity: 1;
}
</style>
</head>
<body>
<div class="container">
<header>
<div class="header-left">
<div class="logo">BUILDER PRO</div>
<div class="subtitle">电脑DIY组装报价系统</div>
</div>
<div class="header-right">
<div class="stats">
<div class="stat">
<div class="stat-label">配件</div>
<div class="stat-value cyan" id="count">0</div>
</div>
<div class="stat">
<div class="stat-label">功耗</div>
<div class="stat-value cyan" id="watt">0W</div>
</div>
<div class="stat">
<div class="stat-label">总价</div>
<div class="stat-value green" id="total-stat">¥0</div>
</div>
</div>
<div class="theme-toggle" onclick="toggleTheme()" title="切换主题">
<div class="theme-icons">
<span class="theme-icon-moon">🌙</span>
<span class="theme-icon-sun">☀️</span>
</div>
<div class="theme-toggle-ball"></div>
</div>
</div>
</header>
<div class="presets">
<button class="preset-btn" onclick="loadPreset('office')">
<span class="icon">💼</span>
<div class="info">
<div class="name">办公机1</div>
<div class="price">¥780</div>
</div>
</button>
<button class="preset-btn" onclick="loadPreset('office1')">
<span class="icon">💼</span>
<div class="info">
<div class="name">办公机2</div>
<div class="price">¥1,980</div>
</div>
</button>
<button class="preset-btn" onclick="loadPreset('office2')">
<span class="icon">💼</span>
<div class="info">
<div class="name">办公机3</div>
<div class="price">¥2,650</div>
</div>
</button>
<button class="preset-btn" onclick="loadPreset('gaming')">
<span class="icon">🎮</span>
<div class="info">
<div class="name">电竞游戏</div>
<div class="price">¥14,339</div>
</div>
</button>
<button class="preset-btn" onclick="loadPreset('pro')">
<span class="icon">🎨</span>
<div class="info">
<div class="name">专业创作</div>
<div class="price">¥29,689</div>
</div>
</button>
</div>
<div class="main">
<div class="components">
<div class="comp-card" id="card-cpu">
<div class="comp-header">
<div class="comp-icon">🔲</div>
<div class="comp-name">处理器 CPU</div>
<span class="comp-badge">必选</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-cpu" onchange="update('cpu')">
<option value="">-- 选择处理器 --</option>
</select>
<button class="btn-add" onclick="toggleAddForm('cpu')" title="添加自定义">+</button>
<button class="btn-del-custom" id="del-cpu" onclick="deleteCustom('cpu')" title="删除自定义">✕</button>
</div>
<div class="add-form" id="form-cpu">
<div class="add-form-row">
<input class="add-input name" id="name-cpu" placeholder="配件名称(如:i9-14900K)">
</div>
<div class="add-form-row">
<input class="add-input price" id="price-cpu" type="number" placeholder="价格">
<input class="add-input watt" id="watt-cpu" type="number" placeholder="功耗(W)">
</div>
<div class="add-btns">
<button class="btn-confirm" onclick="confirmAdd('cpu')">确认添加</button>
<button class="btn-cancel" onclick="toggleAddForm('cpu')">取消</button>
</div>
</div>
<div class="comp-price" id="price-cpu"></div>
</div>
<div class="comp-card" id="card-mb">
<div class="comp-header">
<div class="comp-icon">🟩</div>
<div class="comp-name">主板</div>
<span class="comp-badge">必选</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-mb" onchange="update('mb')">
<option value="">-- 选择主板 --</option>
</select>
<button class="btn-add" onclick="toggleAddForm('mb')" title="添加自定义">+</button>
<button class="btn-del-custom" id="del-mb" onclick="deleteCustom('mb')" title="删除自定义">✕</button>
</div>
<div class="add-form" id="form-mb">
<div class="add-form-row">
<input class="add-input name" id="name-mb" placeholder="配件名称">
</div>
<div class="add-form-row">
<input class="add-input price" id="price-mb" type="number" placeholder="价格">
<input class="add-input watt" id="watt-mb" type="number" placeholder="功耗(W)">
</div>
<div class="add-btns">
<button class="btn-confirm" onclick="confirmAdd('mb')">确认添加</button>
<button class="btn-cancel" onclick="toggleAddForm('mb')">取消</button>
</div>
</div>
<div class="comp-price" id="price-mb"></div>
</div>
<div class="comp-card" id="card-ram">
<div class="comp-header">
<div class="comp-icon">📏</div>
<div class="comp-name">内存 RAM</div>
<span class="comp-badge">必选</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-ram" onchange="update('ram')">
<option value="">-- 选择内存 --</option>
</select>
<button class="btn-add" onclick="toggleAddForm('ram')" title="添加自定义">+</button>
<button class="btn-del-custom" id="del-ram" onclick="deleteCustom('ram')" title="删除自定义">✕</button>
</div>
<div class="add-form" id="form-ram">
<div class="add-form-row">
<input class="add-input name" id="name-ram" placeholder="配件名称">
</div>
<div class="add-form-row">
<input class="add-input price" id="price-ram" type="number" placeholder="价格">
<input class="add-input watt" id="watt-ram" type="number" placeholder="功耗(W)">
</div>
<div class="add-btns">
<button class="btn-confirm" onclick="confirmAdd('ram')">确认添加</button>
<button class="btn-cancel" onclick="toggleAddForm('ram')">取消</button>
</div>
</div>
<div class="comp-price" id="price-ram"></div>
</div>
<div class="comp-card" id="card-gpu">
<div class="comp-header">
<div class="comp-icon">🎴</div>
<div class="comp-name">显卡 GPU</div>
<span class="comp-badge">必选</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-gpu" onchange="update('gpu')">
<option value="">-- 选择显卡 --</option>
</select>
<button class="btn-add" onclick="toggleAddForm('gpu')" title="添加自定义">+</button>
<button class="btn-del-custom" id="del-gpu" onclick="deleteCustom('gpu')" title="删除自定义">✕</button>
</div>
<div class="add-form" id="form-gpu">
<div class="add-form-row">
<input class="add-input name" id="name-gpu" placeholder="配件名称">
</div>
<div class="add-form-row">
<input class="add-input price" id="price-gpu" type="number" placeholder="价格">
<input class="add-input watt" id="watt-gpu" type="number" placeholder="功耗(W)">
</div>
<div class="add-btns">
<button class="btn-confirm" onclick="confirmAdd('gpu')">确认添加</button>
<button class="btn-cancel" onclick="toggleAddForm('gpu')">取消</button>
</div>
</div>
<div class="comp-price" id="price-gpu"></div>
</div>
<div class="comp-card" id="card-ssd">
<div class="comp-header">
<div class="comp-icon">💾</div>
<div class="comp-name">存储</div>
<span class="comp-badge">必选</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-ssd" onchange="update('ssd')">
<option value="">-- 选择存储 --</option>
</select>
<button class="btn-add" onclick="toggleAddForm('ssd')" title="添加自定义">+</button>
<button class="btn-del-custom" id="del-ssd" onclick="deleteCustom('ssd')" title="删除自定义">✕</button>
</div>
<div class="add-form" id="form-ssd">
<div class="add-form-row">
<input class="add-input name" id="name-ssd" placeholder="配件名称">
</div>
<div class="add-form-row">
<input class="add-input price" id="price-ssd" type="number" placeholder="价格">
<input class="add-input watt" id="watt-ssd" type="number" placeholder="功耗(W)">
</div>
<div class="add-btns">
<button class="btn-confirm" onclick="confirmAdd('ssd')">确认添加</button>
<button class="btn-cancel" onclick="toggleAddForm('ssd')">取消</button>
</div>
</div>
<div class="comp-price" id="price-ssd"></div>
</div>
<div class="comp-card" id="card-psu">
<div class="comp-header">
<div class="comp-icon">⚡</div>
<div class="comp-name">电源 PSU</div>
<span class="comp-badge">必选</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-psu" onchange="update('psu')">
<option value="">-- 选择电源 --</option>
</select>
<button class="btn-add" onclick="toggleAddForm('psu')" title="添加自定义">+</button>
<button class="btn-del-custom" id="del-psu" onclick="deleteCustom('psu')" title="删除自定义">✕</button>
</div>
<div class="add-form" id="form-psu">
<div class="add-form-row">
<input class="add-input name" id="name-psu" placeholder="配件名称">
</div>
<div class="add-form-row">
<input class="add-input price" id="price-psu" type="number" placeholder="价格">
<input class="add-input watt" id="watt-psu" type="number" placeholder="功耗(W)">
</div>
<div class="add-btns">
<button class="btn-confirm" onclick="confirmAdd('psu')">确认添加</button>
<button class="btn-cancel" onclick="toggleAddForm('psu')">取消</button>
</div>
</div>
<div class="comp-price" id="price-psu"></div>
</div>
<div class="comp-card" id="card-case">
<div class="comp-header">
<div class="comp-icon">🖥️</div>
<div class="comp-name">机箱</div>
<span class="comp-badge">必选</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-case" onchange="update('case')">
<option value="">-- 选择机箱 --</option>
</select>
<button class="btn-add" onclick="toggleAddForm('case')" title="添加自定义">+</button>
<button class="btn-del-custom" id="del-case" onclick="deleteCustom('case')" title="删除自定义">✕</button>
</div>
<div class="add-form" id="form-case">
<div class="add-form-row">
<input class="add-input name" id="name-case" placeholder="配件名称">
</div>
<div class="add-form-row">
<input class="add-input price" id="price-case" type="number" placeholder="价格">
<input class="add-input watt" id="watt-case" type="number" placeholder="功耗(W)">
</div>
<div class="add-btns">
<button class="btn-confirm" onclick="confirmAdd('case')">确认添加</button>
<button class="btn-cancel" onclick="toggleAddForm('case')">取消</button>
</div>
</div>
<div class="comp-price" id="price-case"></div>
</div>
<div class="comp-card" id="card-cooler">
<div class="comp-header">
<div class="comp-icon">❄️</div>
<div class="comp-name">散热器</div>
<span class="comp-badge">必选</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-cooler" onchange="update('cooler')">
<option value="">-- 选择散热器 --</option>
</select>
<button class="btn-add" onclick="toggleAddForm('cooler')" title="添加自定义">+</button>
<button class="btn-del-custom" id="del-cooler" onclick="deleteCustom('cooler')" title="删除自定义">✕</button>
</div>
<div class="add-form" id="form-cooler">
<div class="add-form-row">
<input class="add-input name" id="name-cooler" placeholder="配件名称">
</div>
<div class="add-form-row">
<input class="add-input price" id="price-cooler" type="number" placeholder="价格">
<input class="add-input watt" id="watt-cooler" type="number" placeholder="功耗(W)">
</div>
<div class="add-btns">
<button class="btn-confirm" onclick="confirmAdd('cooler')">确认添加</button>
<button class="btn-cancel" onclick="toggleAddForm('cooler')">取消</button>
</div>
</div>
<div class="comp-price" id="price-cooler"></div>
</div>
<div class="comp-card" id="card-monitor">
<div class="comp-header">
<div class="comp-icon">🖥️</div>
<div class="comp-name">显示器</div>
<span class="comp-badge">可选</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-monitor" onchange="update('monitor')">
<option value="">-- 选择显示器 --</option>
</select>
<button class="btn-add" onclick="toggleAddForm('monitor')" title="添加自定义">+</button>
<button class="btn-del-custom" id="del-monitor" onclick="deleteCustom('monitor')" title="删除自定义">✕</button>
</div>
<div class="add-form" id="form-monitor">
<div class="add-form-row">
<input class="add-input name" id="name-monitor" placeholder="配件名称">
</div>
<div class="add-form-row">
<input class="add-input price" id="price-monitor" type="number" placeholder="价格">
<input class="add-input watt" id="watt-monitor" type="number" placeholder="功耗(W)">
</div>
<div class="add-btns">
<button class="btn-confirm" onclick="confirmAdd('monitor')">确认添加</button>
<button class="btn-cancel" onclick="toggleAddForm('monitor')">取消</button>
</div>
</div>
<div class="comp-price" id="price-monitor"></div>
</div>
<div class="comp-card" id="card-kbm">
<div class="comp-header">
<div class="comp-icon">⌨️</div>
<div class="comp-name">键盘鼠标</div>
<span class="comp-badge">可选</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-kbm" onchange="update('kbm')">
<option value="">-- 选择键鼠套装 --</option>
</select>
<button class="btn-add" onclick="toggleAddForm('kbm')" title="添加自定义">+</button>
<button class="btn-del-custom" id="del-kbm" onclick="deleteCustom('kbm')" title="删除自定义">✕</button>
</div>
<div class="add-form" id="form-kbm">
<div class="add-form-row">
<input class="add-input name" id="name-kbm" placeholder="配件名称">
</div>
<div class="add-form-row">
<input class="add-input price" id="price-kbm" type="number" placeholder="价格">
<input class="add-input watt" id="watt-kbm" type="number" placeholder="功耗(W)">
</div>
<div class="add-btns">
<button class="btn-confirm" onclick="confirmAdd('kbm')">确认添加</button>
<button class="btn-cancel" onclick="toggleAddForm('kbm')">取消</button>
</div>
</div>
<div class="comp-price" id="price-kbm"></div>
</div>
<div class="comp-card" id="card-giftKbm">
<div class="comp-header">
<div class="comp-icon">🎁</div>
<div class="comp-name">赠送键鼠</div>
<span class="comp-badge" style="background:rgba(34,197,94,0.15);color:var(--green);">免费</span>
</div>
<div class="comp-row">
<select class="comp-select" id="sel-giftKbm" onchange="update('giftKbm')">
<option value="">-- 选择赠送键鼠 --</option>
</select>
</div>
<div class="comp-price" id="price-giftKbm"></div>
</div>
</div>
<div class="quote-panel">
<div class="quote-card">
<div class="quote-title">📋 配置清单</div>
<div class="config-list" id="configList">
<div class="empty-msg">
<div class="empty-msg-icon">🔧</div>
请从左侧选择配件<br>或点击快速方案
</div>
</div>
<div class="divider"></div>
<div class="price-row">
<span class="label">配件小计</span>
<span class="value" id="subtotal">¥0</span>
</div>
<div class="price-row">
<span class="label">装机服务</span>
<input type="number" id="fee" value="300" min="0" style="width:80px;background:var(--input-bg);border:1px solid var(--border);border-radius:4px;color:var(--green);font-family:'Orbitron';font-size:0.78rem;text-align:right;padding:4px 6px;" onchange="render()" oninput="render()">
</div>
<div class="price-row">
<span class="label">说明</span>
<input type="text" id="note" placeholder="如:赠送配件" style="width:120px;background:var(--input-bg);border:1px solid var(--border);border-radius:4px;color:var(--text);font-size:0.75rem;text-align:right;padding:4px 6px;">
</div>
<div class="price-row total-row">
<span class="label">总计</span>
<span class="value" id="total">¥0</span>
</div>
<div class="watt-warning" id="wattWarning">
⚠️ <span>功耗较高,建议选择更大功率电源</span>
</div>
<div class="btns">
<button class="btn btn-primary" onclick="exportConfig('full')">📤 详细导出</button>
<button class="btn btn-outline" onclick="exportConfig('simple')">📄 简洁导出</button>
<button class="btn btn-secondary" onclick="copyConfig('full')">📋 详细复制</button>
<button class="btn btn-secondary" onclick="copyConfig('simple')">📝 简洁复制</button>
<button class="btn btn-danger btns-full" onclick="clearAll()">🗑️ 清空配置</button>
</div>
<div class="manage-section" id="manageSection">
<div class="manage-title">🔧 自定义配件管理</div>
<div class="manage-list" id="manageList">
<div class="manage-empty">暂无自定义配件</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="toast" id="toast">
<span id="toastIcon">✅</span>
<span id="toastMsg"></span>
</div>
<script src="data.js"></script>
<script>
const selected = { cpu: null, mb: null, ram: null, gpu: null, ssd: null, psu: null, case: null, cooler: null, monitor: null, kbm: null, giftKbm: null };
const names = { cpu: 'CPU', mb: '主板', ram: '内存', gpu: '显卡', ssd: '存储', psu: '电源', case: '机箱', cooler: '散热', monitor: '显示器', kbm: '键鼠', giftKbm: '赠送键鼠' };
const typeNames = { cpu: '处理器', mb: '主板', ram: '内存', ssd: '存储', psu: '电源', case: '机箱', cooler: '散热器', monitor: '显示器', kbm: '键盘鼠标', giftKbm: '赠送键鼠' };
const presets = {
office: { cpu:'cpu1', mb:'mb1', ram:'ram1',ssd:'ssd1', psu:'psu1', case:'case1', cooler:'cl1', monitor:'mon1', giftKbm:'gkbm1' },
office1: { cpu:'cpu1', mb:'mb1', ram:'ram1',ssd:'ssd1', psu:'psu1', case:'case1', cooler:'cl1', monitor:'mon1', giftKbm:'gkbm1' },
office2: { cpu:'cpu2', mb:'mb2', ram:'ram2',ssd:'ssd2', psu:'psu1', case:'case1', cooler:'cl1', monitor:'mon1',giftKbm:'gkbm1'},
gaming: { cpu:'cpu3', mb:'mb3', ram:'ram5', gpu:'gpu4', ssd:'ssd3', psu:'psu4', case:'case3', cooler:'cl5', monitor:'mon5', kbm:'kbm5' },
pro: { cpu:'cpu5', mb:'mb8', ram:'ram7', gpu:'gpu6', ssd:'ssd5', psu:'psu6', case:'case6', cooler:'cl8', monitor:'mon7', kbm:'kbm7' }
};
let customParts = JSON.parse(localStorage.getItem('customParts') || '{}');
let customIdCounter = parseInt(localStorage.getItem('customIdCounter') || '1000');
function toggleTheme() {
const body = document.body;
const isLight = body.getAttribute('data-theme') === 'light';
body.setAttribute('data-theme', isLight ? 'dark' : 'light');
localStorage.setItem('theme', isLight ? 'dark' : 'light');
toast(isLight ? '🌙 已切换深色主题' : '☀️ 已切换浅色主题');
}
function initTheme() {
document.body.setAttribute('data-theme', localStorage.getItem('theme') || 'dark');
}
function toggleAddForm(type) {
const form = document.getElementById('form-' + type);
form.classList.toggle('show');
if (form.classList.contains('show')) {
document.getElementById('name-' + type).focus();
}
}
function confirmAdd(type) {
const name = document.getElementById('name-' + type).value.trim();
const price = parseInt(document.getElementById('price-' + type).value);
const watt = parseInt(document.getElementById('watt-' + type).value) || 0;
if (!name) { toast('请输入配件名称', '⚠️'); return; }
if (!price || price <= 0) { toast('请输入有效价格', '⚠️'); return; }
const id = 'custom_' + (++customIdCounter);
localStorage.setItem('customIdCounter', customIdCounter);
if (!customParts[type]) customParts[type] = [];
customParts[type].push({ id, name, price, watt });
localStorage.setItem('customParts', JSON.stringify(customParts));
addOptionToSelect(type, id, name, price, watt);
document.getElementById('sel-' + type).value = id;
update(type);
document.getElementById('name-' + type).value = '';
document.getElementById('price-' + type).value = '';
document.getElementById('watt-' + type).value = '';
toggleAddForm(type);
updateManageList();
toast('已添加: ' + name);
}
function addOptionToSelect(type, id, name, price, watt) {
const select = document.getElementById('sel-' + type);
const option = document.createElement('option');
option.value = id;
option.dataset.p = price;
option.dataset.w = watt;
option.dataset.custom = 'true';
option.textContent = name + ' - ¥' + price.toLocaleString();
select.appendChild(option);
}
function deleteCustom(type) {
const select = document.getElementById('sel-' + type);
const currentValue = select.value;
if (!currentValue || !currentValue.startsWith('custom_')) {
toast('请先选择一个自定义配件', '⚠️');
return;
}
if (customParts[type]) {
customParts[type] = customParts[type].filter(p => p.id !== currentValue);
if (customParts[type].length === 0) delete customParts[type];
localStorage.setItem('customParts', JSON.stringify(customParts));
}
const option = select.querySelector(`option[value="${currentValue}"]`);
if (option) {
const name = option.text.split(' - ')[0];
option.remove();
toast('已删除: ' + name);
}
select.value = '';
update(type);
updateManageList();
}
function updateDelButton(type) {
const select = document.getElementById('sel-' + type);
const delBtn = document.getElementById('del-' + type);
delBtn.classList.toggle('show', select.value && select.value.startsWith('custom_'));
}
function initCustomParts() {
Object.entries(customParts).forEach(([type, parts]) => {
parts.forEach(part => addOptionToSelect(type, part.id, part.name, part.price, part.watt));
});
updateManageList();
}
function updateManageList() {
const list = document.getElementById('manageList');
const allCustom = [];
Object.entries(customParts).forEach(([type, parts]) => {
parts.forEach(part => allCustom.push({ ...part, type }));
});
if (allCustom.length === 0) {
list.innerHTML = '<div class="manage-empty">暂无自定义配件</div>';
} else {
list.innerHTML = allCustom.map(item => `
<div class="manage-item">
<div class="manage-item-info">
<span class="manage-item-type">${typeNames[item.type]}</span>
<span class="manage-item-name">${item.name}</span>
<span class="manage-item-price">¥${item.price.toLocaleString()}</span>
</div>
<button class="manage-item-del" onclick="deleteFromManage('${item.type}', '${item.id}')">✕</button>
</div>
`).join('');
}
}
function deleteFromManage(type, id) {
if (customParts[type]) {
customParts[type] = customParts[type].filter(p => p.id !== id);
if (customParts[type].length === 0) delete customParts[type];
localStorage.setItem('customParts', JSON.stringify(customParts));
}
const select = document.getElementById('sel-' + type);
const option = select.querySelector(`option[value="${id}"]`);
if (option) {
if (select.value === id) { select.value = ''; update(type); }
option.remove();
}
updateManageList();
toast('已删除配件');
}
function update(type) {
const sel = document.getElementById('sel-' + type);
const card = document.getElementById('card-' + type);
const priceEl = document.getElementById('price-' + type);
if (sel.value) {
const opt = sel.options[sel.selectedIndex];
selected[type] = {
id: sel.value,
name: opt.text.split(' - ')[0],
price: +opt.dataset.p,
watt: +opt.dataset.w,
isCustom: sel.value.startsWith('custom_')
};
priceEl.textContent = selected[type].price > 0 ? '¥' + selected[type].price.toLocaleString() : '免费';
card.classList.add('selected');
} else {
selected[type] = null;
priceEl.textContent = '';
card.classList.remove('selected');
}
if (type !== 'giftKbm') updateDelButton(type);
render();
}
function render() {
const list = document.getElementById('configList');
const items = Object.entries(selected).filter(([_, v]) => v);
if (!items.length) {
list.innerHTML = '<div class="empty-msg"><div class="empty-msg-icon">🔧</div>请从左侧选择配件<br>或点击快速方案</div>';
} else {
list.innerHTML = items.map(([t, c]) => `
<div class="config-item">
<span class="config-item-type">${names[t]}</span>
<span class="config-item-name">${c.name}${c.isCustom ? '<span class="config-item-custom">自定义</span>' : ''}${t === 'giftKbm' ? '<span class="config-item-custom" style="background:rgba(34,197,94,0.15);color:var(--green);">赠送</span>' : ''}</span>
<span class="config-item-price">${c.price > 0 ? '¥' + c.price.toLocaleString() : '免费'}</span>
<button class="config-item-remove" onclick="remove('${t}')">✕</button>
</div>
`).join('');
}
const sub = items.reduce((s, [_, c]) => s + c.price, 0);
const fee = parseInt(document.getElementById('fee').value) || 0;
const totalWatt = items.reduce((s, [_, c]) => s + c.watt, 0);
document.getElementById('subtotal').textContent = '¥' + sub.toLocaleString();
document.getElementById('total').textContent = '¥' + (sub + fee).toLocaleString();
document.getElementById('count').textContent = items.length;
document.getElementById('watt').textContent = totalWatt + 'W';
document.getElementById('total-stat').textContent = '¥' + (sub + fee).toLocaleString();
const warning = document.getElementById('wattWarning');
if (totalWatt > 500) {
warning.classList.add('show');
warning.querySelector('span').textContent = `总功耗 ${totalWatt}W,建议选择 ${Math.ceil(totalWatt * 1.3 / 100) * 100}W 以上电源`;
} else {
warning.classList.remove('show');
}
}
function remove(type) {
document.getElementById('sel-' + type).value = '';
update(type);
toast('已移除 ' + names[type]);
}
function clearAll() {
Object.keys(selected).forEach(t => {
document.getElementById('sel-' + t).value = '';
selected[t] = null;
document.getElementById('card-' + t).classList.remove('selected');
document.getElementById('price-' + t).textContent = '';
if (t !== 'giftKbm') updateDelButton(t);
});
render();
toast('已清空配置');
}
function loadPreset(name) {
clearAll();
const p = presets[name];
Object.entries(p).forEach(([t, v]) => {
document.getElementById('sel-' + t).value = v;
update(t);
});
toast('已加载 ' + {office:'办公',office1:'办公1',office2:'办公2',gaming:'游戏',pro:'创作'}[name] + ' 方案');
}
function copyConfig(mode) {
const items = Object.entries(selected).filter(([_, v]) => v);
if (!items.length) return toast('请先选择配件', '⚠️');
const sub = items.reduce((s, [_, c]) => s + c.price, 0);
const fee = parseInt(document.getElementById('fee').value) || 0;
const note = document.getElementById('note').value.trim();
let txt = '【电脑配置单】\n';
if (mode === 'full') {
items.forEach(([t, c]) => txt += `${names[t]}: ${c.name} ${c.price > 0 ? '¥' + c.price : '免费'}${c.isCustom ? ' [自定义]' : ''}${t === 'giftKbm' ? ' [赠送]' : ''}\n`);
txt += `─────────\n小计: ¥${sub.toLocaleString()}\n服务费: ¥${fee}\n总计: ¥${(sub + fee).toLocaleString()}${note ? `\n说明: ${note}` : ''}`;
} else {
items.forEach(([t, c]) => txt += `${names[t]}: ${c.name}${c.isCustom ? ' [自定义]' : ''}${t === 'giftKbm' ? ' [赠送]' : ''}\n`);
txt += `─────────\n总计: ¥${(sub + fee).toLocaleString()}${note ? `\n说明: ${note}` : ''}`;
}
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(txt).then(() => toast(mode === 'full' ? '详细配置已复制' : '简洁配置已复制'));
} else {
const textarea = document.createElement('textarea');
textarea.value = txt;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
toast(mode === 'full' ? '详细配置已复制' : '简洁配置已复制');
}
}
function exportConfig(mode) {
const items = Object.entries(selected).filter(([_, v]) => v);
if (!items.length) return toast('请先选择配件', '⚠️');
const sub = items.reduce((s, [_, c]) => s + c.price, 0);
const fee = parseInt(document.getElementById('fee').value) || 0;
const note = document.getElementById('note').value.trim();
let html;
if (mode === 'full') {
html = `<!DOCTYPE html><html><head><meta charset="UTF-8"><title>配置单</title><style>body{font-family:sans-serif;max-width:600px;margin:40px auto;padding:20px}h1{text-align:center;border-bottom:2px solid #0891b2;padding-bottom:10px}table{width:100%;border-collapse:collapse;margin:20px 0}th,td{padding:10px;text-align:left;border-bottom:1px solid #ddd}th{background:#f5f5f5}.r{text-align:right;font-weight:bold;color:#16a34a}.t{font-size:1.2em;color:#db2777}.custom{font-size:0.8em;color:#ea580c;margin-left:4px}.gift{font-size:0.8em;color:#22c55e;margin-left:4px}</style></head><body><h1>🖥️ 电脑配置单</h1><p style="text-align:center;color:#666">开平蓝动力电脑 报价表 ${new Date().toLocaleDateString()}</p><table><tr><th>配件</th><th>型号</th><th class="r">价格</th></tr>`;
items.forEach(([t, c]) => {
html += `<tr><td>${names[t]}</td><td>${c.name}${c.isCustom ? '<span class="custom">[自定义]</span>' : ''}${t === 'giftKbm' ? '<span class="gift">[赠送]</span>' : ''}</td><td class="r">${c.price > 0 ? '¥' + c.price.toLocaleString() : '免费'}</td></tr>`;
});
html += `<tr><td colspan="2">小计</td><td class="r">¥${sub.toLocaleString()}</td></tr><tr><td colspan="2">服务费</td><td class="r">¥${fee}</td></tr><tr><td colspan="2" class="t">总计</td><td class="r t">¥${(sub + fee).toLocaleString()}</td></tr>${note ? `<tr><td colspan="3">说明:${note}</td></tr>` : ''}`;
} else {
html = `<!DOCTYPE html><html><head><meta charset="UTF-8"><title>配置单</title><style>body{font-family:sans-serif;max-width:600px;margin:40px auto;padding:20px}h1{text-align:center;border-bottom:2px solid #0891b2;padding-bottom:10px}table{width:100%;border-collapse:collapse;margin:20px 0}th,td{padding:10px;text-align:left;border-bottom:1px solid #ddd}th{background:#f5f5f5}.r{text-align:right;font-weight:bold;color:#16a34a}.t{font-size:1.2em;color:#db2777}.custom{font-size:0.8em;color:#ea580c;margin-left:4px}.gift{font-size:0.8em;color:#22c55e;margin-left:4px}</style></head><body><h1>🖥️ 电脑配置单</h1><p style="text-align:center;color:#666">开平蓝动力电脑 报价表 ${new Date().toLocaleDateString()}</p><table><tr><th>配件</th><th>型号</th></tr>`;
items.forEach(([t, c]) => {
html += `<tr><td>${names[t]}</td><td>${c.name}${c.isCustom ? '<span class="custom">[自定义]</span>' : ''}${t === 'giftKbm' ? '<span class="gift">[赠送]</span>' : ''}</td></tr>`;
});
html += `<tr><td class="t">总计</td><td class="r t">¥${(sub + fee).toLocaleString()}</td></tr>${note ? `<tr><td colspan="2">说明:${note}</td></tr>` : ''}`;
}
html += `</table></body></html>`;
const a = document.createElement('a');
a.href = URL.createObjectURL(new Blob([html], {type:'text/html'}));
a.download = '配置单_' + (mode === 'full' ? '详细_' : '简洁_') + new Date().toISOString().slice(0,10) + '.html';
a.click();
toast(mode === 'full' ? '详细配置单已导出' : '简洁配置单已导出');
}
function toast(msg, icon = '✅') {
const t = document.getElementById('toast');
document.getElementById('toastMsg').textContent = msg;
document.getElementById('toastIcon').textContent = icon;
t.classList.add('show');
setTimeout(() => t.classList.remove('show'), 2000);
}
function initPartsData() {
const partTypes = ['cpu', 'mb', 'ram', 'gpu', 'ssd', 'psu', 'case', 'cooler', 'monitor', 'kbm', 'giftKbm'];
partTypes.forEach(type => {
const select = document.getElementById('sel-' + type);
if (select && partsData[type]) {
partsData[type].forEach(part => {
const option = document.createElement('option');
option.value = part.id;
option.dataset.p = part.price;
option.dataset.w = part.watt;
option.textContent = part.name + (part.price > 0 ? ' - ¥' + part.price.toLocaleString() : ' - 免费');
select.appendChild(option);
});
}
});
}
initPartsData();
initTheme();
initCustomParts();
document.querySelectorAll('.add-input').forEach(input => {
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter') confirmAdd(input.id.split('-')[1]);
});
});
</script>
</body>
</html>
数据data.js
html
const partsData = {
cpu: [
{ id: 'cpu1', name: 'Intel i5-8500 (6核6线程)', price: 390, watt: 65 },
{ id: 'cpu2', name: 'Intel i3-10105 (4核8线程)', price: 610, watt: 65 },
{ id: 'cpu3', name: 'i5-13600KF (14核20线程)', price: 1599, watt: 125 },
{ id: 'cpu4', name: 'i7-13700KF (16核24线程)', price: 2499, watt: 125 },
{ id: 'cpu5', name: 'i9-13900KF (24核32线程)', price: 3999, watt: 150 },
{ id: 'cpu6', name: 'R5 5600 (6核12线程)', price: 699, watt: 65 },
{ id: 'cpu7', name: 'R5 7600X (6核12线程)', price: 1299, watt: 105 },
{ id: 'cpu8', name: 'R7 7700X (8核16线程)', price: 1999, watt: 105 },
{ id: 'cpu9', name: 'R9 7900X (12核24线程)', price: 3299, watt: 170 },
{ id: 'cpu10', name: 'Intel i5-8500 (6核6线程)', price: 390, watt: 65 },
{ id: 'cpu11', name: 'i3-12100 散片 (4核8线程)', price: 965, watt: 65 }
],
mb: [
{ id: 'mb1', name: '昂达 9D3-DVH', price: 305, watt: 50 },
{ id: 'mb2', name: '昂达 H510E (支持10代U)', price: 300, watt: 50 },
{ id: 'mb3', name: '华硕 B760M-PLUS WiFi D5', price: 1299, watt: 60 },
{ id: 'mb4', name: '微星 Z790 EDGE WiFi', price: 1999, watt: 70 },
{ id: 'mb5', name: '华硕 B550M-K', price: 549, watt: 50 },
{ id: 'mb6', name: '微星 B550M MORTAR WiFi', price: 899, watt: 50 },
{ id: 'mb7', name: '华硕 B650M-PLUS WiFi', price: 1599, watt: 60 },
{ id: 'mb8', name: '华硕 X670E-E WiFi', price: 2999, watt: 80 },
{ id: 'mb9', name: '昂达 9D3-DVH', price: 305, watt: 50 },
{ id: 'mb10', name: '铭瑄 H610 M-R', price: 325, watt: 50 }
],
ram: [
{ id: 'ram1', name: '昂达 DDR3 8G', price: 150, watt: 5 },
{ id: 'ram2', name: '威刚 DDR4 8G 3200', price: 490, watt: 5 },
{ id: 'ram3', name: '32GB(16×2) DDR4 3600', price: 599, watt: 5 },
{ id: 'ram4', name: '16GB(8×2) DDR5 5200', price: 399, watt: 6 },
{ id: 'ram5', name: '32GB(16×2) DDR5 5600', price: 699, watt: 6 },
{ id: 'ram6', name: '32GB(16×2) DDR5 6000', price: 1299, watt: 8 },
{ id: 'ram7', name: '64GB(32×2) DDR5 6000', price: 1999, watt: 10 }
],
gpu: [
{ id: 'gpu1', name: 'RTX 3050 8GB', price: 899, watt: 130 },
{ id: 'gpu2', name: 'RTX 4060 8GB', price: 1799, watt: 170 },
{ id: 'gpu3', name: 'RTX 4060 Ti 8GB', price: 2999, watt: 200 },
{ id: 'gpu4', name: 'RTX 4070 12GB', price: 4499, watt: 285 },
{ id: 'gpu5', name: 'RTX 4070 Ti SUPER 16GB', price: 5999, watt: 320 },
{ id: 'gpu6', name: 'RTX 4080 SUPER 16GB', price: 9999, watt: 450 },
{ id: 'gpu7', name: 'RTX 4090 24GB', price: 13999, watt: 450 },
{ id: 'gpu8', name: 'RX 7600 8GB', price: 1599, watt: 150 },
{ id: 'gpu9', name: 'RX 7800 XT 16GB', price: 3299, watt: 263 },
{ id: 'gpu10', name: 'RX 7900 XTX 24GB', price: 5499, watt: 300 }
],
ssd: [
{ id: 'ssd1', name: '昂达 256G SATA固态', price: 295, watt: 5 },
{ id: 'ssd2', name: '三星 980 1TB NVMe', price: 499, watt: 5 },
{ id: 'ssd3', name: '三星 980 PRO 1TB PCIe4', price: 799, watt: 7 },
{ id: 'ssd4', name: '三星 990 PRO 2TB PCIe4', price: 1299, watt: 7 },
{ id: 'ssd5', name: '三星 990 PRO 4TB PCIe4', price: 2499, watt: 10 },
{ id: 'hdd1', name: '西数蓝盘 1TB 机械', price: 299, watt: 8 },
{ id: 'hdd2', name: '西数蓝盘 2TB 机械', price: 499, watt: 8 },
{ id: 'ssd7', name: '威刚 580 240G 固态', price: 368, watt: 3 },
{ id: 'ssd8', name: '威刚 M.2 256G 固态', price: 420, watt: 3 }
],
psu: [
{ id: 'psu1', name: '小牛 300W', price: 70, watt: 0 },
{ id: 'psu2', name: '航嘉 450W', price: 165, watt: 0 },
{ id: 'psu3', name: '海韵 650W 金牌', price: 549, watt: 0 },
{ id: 'psu4', name: '海韵 750W 金牌', price: 699, watt: 0 },
{ id: 'psu5', name: '海韵 850W 金牌', price: 899, watt: 0 },
{ id: 'psu6', name: '海韵 1000W 钛金', price: 1199, watt: 0 },
{ id: 'psu7', name: '海韵 1300W 钛金', price: 1599, watt: 0 },
{ id: 'psu8', name: '小牛 300W', price: 70, watt: 0 }
],
case: [
{ id: 'case1', name: '小机箱', price: 40, watt: 0 },
{ id: 'case2', name: '中机箱', price: 75, watt: 0 },
{ id: 'case3', name: '游戏机箱', price: 95, watt: 0 },
{ id: 'case4', name: '联力 O11D EVO', price: 799, watt: 0 },
{ id: 'case5', name: '追风者 P600S', price: 1299, watt: 0 },
{ id: 'case6', name: '华硕 ROG Helios', price: 1999, watt: 0 },
{ id: 'case7', name: '小机箱', price: 30, watt: 0 }
],
cooler: [
{ id: 'cl1', name: '青鸟3 散热器', price: 14, watt: 3 },
{ id: 'cl2', name: '4铜管 散热器', price: 85, watt: 3 },
{ id: 'cl3', name: '猫头鹰 NH-U12S', price: 299, watt: 3 },
{ id: 'cl4', name: '利民 FC140 双塔', price: 399, watt: 5 },
{ id: 'cl5', name: '九州风神 240水冷', price: 349, watt: 8 },
{ id: 'cl6', name: 'NZXT X53 240水冷', price: 599, watt: 10 },
{ id: 'cl7', name: '华硕 LC II 360水冷', price: 899, watt: 12 },
{ id: 'cl8', name: 'NZXT Z73 360水冷', price: 1499, watt: 15 }
],
monitor: [
{ id: 'mon1', name: 'AOC 24B36HE 24', price: 415, watt: 25 },
{ id: 'mon2', name: '联想 27寸 显示器', price: 515, watt: 35 },
{ id: 'mon3', name: '戴尔 S2722QC 27" 4K IPS', price: 1499, watt: 40 },
{ id: 'mon4', name: '华硕 VG28UQL1A 28" 4K 144Hz', price: 1999, watt: 45 },
{ id: 'mon5', name: 'LG 27GP850 27" 2K 180Hz NanoIPS', price: 2999, watt: 50 },
{ id: 'mon6', name: '三星 玄龙骑士 G7 32" 2K 240Hz', price: 3999, watt: 60 },
{ id: 'mon7', name: '华硕 ROG PG32UQ 32" 4K 144Hz', price: 5999, watt: 80 },
{ id: 'mon8', name: 'LG 42C3 42" OLED 4K 120Hz', price: 9999, watt: 100 }
],
kbm: [
{ id: 'kbm1', name: '双飞燕 有线键鼠', price: 55, watt: 2 },
{ id: 'kbm2', name: '罗技 MK270 无线键鼠套装', price: 149, watt: 3 },
{ id: 'kbm3', name: '雷蛇 噬魂金蝎 有线游戏套装', price: 249, watt: 5 },
{ id: 'kbm4', name: '罗技 G213+G102 游戏键鼠', price: 399, watt: 5 },
{ id: 'kbm5', name: '雷蛇 黑寡妇蜘蛛V3+毒蝰迷你', price: 599, watt: 8 },
{ id: 'kbm6', name: '海盗船 K70 RGB MK.2+M65 Pro', price: 899, watt: 10 },
{ id: 'kbm7', name: '罗技 G915 TKL+G Pro X Superlight', price: 1299, watt: 12 },
{ id: 'kbm8', name: '雷蛇 猎魂光蛛V2+毒蝰V2 Pro', price: 1999, watt: 15 }
],
giftKbm: [
{ id: 'gkbm1', name: '赠送: 有线键鼠套装', price: 0, watt: 2 },
{ id: 'gkbm2', name: '赠送: 键鼠套装+鼠标垫+排插+小音箱', price: 0, watt: 2 },
{ id: 'gkbm3', name: '赠送: 游戏键鼠套装', price: 0, watt: 3 },
{ id: 'gkbm4', name: '赠送: 机械键盘+游戏鼠标', price: 0, watt: 5 }
]
};