Build AI servo sample sales prototype
This commit is contained in:
741
app/page.tsx
Normal file
741
app/page.tsx
Normal file
@@ -0,0 +1,741 @@
|
||||
"use client";
|
||||
|
||||
import { FormEvent, useMemo, useState } from "react";
|
||||
|
||||
type Gear = "塑料齿" | "半金属齿" | "金属齿";
|
||||
|
||||
type Product = {
|
||||
id: string;
|
||||
name: string;
|
||||
subtitle: string;
|
||||
weight: number;
|
||||
torque: number;
|
||||
speed: number;
|
||||
voltageMin: number;
|
||||
voltageMax: number;
|
||||
gear: Gear;
|
||||
price: number;
|
||||
size: string;
|
||||
image: string;
|
||||
applications: string[];
|
||||
code: string;
|
||||
};
|
||||
|
||||
type Requirements = {
|
||||
application: string;
|
||||
torque: number;
|
||||
voltage: number;
|
||||
weightLimit: number;
|
||||
gear: "不限" | Gear;
|
||||
annualVolume: string;
|
||||
currentModel: string;
|
||||
painPoint: string;
|
||||
};
|
||||
|
||||
const PRODUCTS: Product[] = [
|
||||
{
|
||||
id: "17g",
|
||||
name: "1.7克超微型舵机",
|
||||
subtitle: "极致轻量,适合微型结构",
|
||||
weight: 1.7,
|
||||
torque: 0.09,
|
||||
speed: 0.12,
|
||||
voltageMin: 2.7,
|
||||
voltageMax: 5,
|
||||
gear: "塑料齿",
|
||||
price: 30,
|
||||
size: "13.40 × 6.15 × 16.00 mm",
|
||||
image: "/products/servo-17g.png",
|
||||
applications: ["AI毛绒", "智能玩具", "微型机器人", "云台/航模"],
|
||||
code: "4.A.01.A0060",
|
||||
},
|
||||
{
|
||||
id: "2g",
|
||||
name: "2克塑料齿舵机",
|
||||
subtitle: "快速响应的微型执行方案",
|
||||
weight: 2,
|
||||
torque: 0.4,
|
||||
speed: 0.08,
|
||||
voltageMin: 3.5,
|
||||
voltageMax: 6,
|
||||
gear: "塑料齿",
|
||||
price: 14.4,
|
||||
size: "16.25 × 8.30 × 16.90 mm",
|
||||
image: "/products/servo-2g.jpg",
|
||||
applications: ["AI毛绒", "智能玩具", "微型机器人", "云台/航模"],
|
||||
code: "4.A.01.A0004",
|
||||
},
|
||||
{
|
||||
id: "37g",
|
||||
name: "3.7克塑料齿舵机",
|
||||
subtitle: "轻量玩具与科创教育通用",
|
||||
weight: 3.7,
|
||||
torque: 0.8,
|
||||
speed: 0.09,
|
||||
voltageMin: 3.5,
|
||||
voltageMax: 6,
|
||||
gear: "塑料齿",
|
||||
price: 14.7,
|
||||
size: "20.40 × 8.70 × 20.32 mm",
|
||||
image: "/products/servo-37g.jpg",
|
||||
applications: ["AI毛绒", "智能玩具", "教育/积木", "云台/航模"],
|
||||
code: "4.A.01.A0003",
|
||||
},
|
||||
{
|
||||
id: "9p",
|
||||
name: "9克塑料齿舵机",
|
||||
subtitle: "成本优先的标准轻载方案",
|
||||
weight: 9,
|
||||
torque: 2.1,
|
||||
speed: 0.11,
|
||||
voltageMin: 4.8,
|
||||
voltageMax: 6,
|
||||
gear: "塑料齿",
|
||||
price: 13.1,
|
||||
size: "23.00 × 12.36 × 28.50 mm",
|
||||
image: "/products/servo-9g-plastic.jpg",
|
||||
applications: ["智能玩具", "教育/积木", "微型机器人", "云台/航模"],
|
||||
code: "4.A.01.A0009",
|
||||
},
|
||||
{
|
||||
id: "9h",
|
||||
name: "9克半金属齿舵机",
|
||||
subtitle: "耐久与成本兼顾",
|
||||
weight: 9,
|
||||
torque: 3.2,
|
||||
speed: 0.13,
|
||||
voltageMin: 4.8,
|
||||
voltageMax: 6,
|
||||
gear: "半金属齿",
|
||||
price: 18,
|
||||
size: "23.00 × 12.36 × 28.50 mm",
|
||||
image: "/products/servo-9g-hybrid.jpg",
|
||||
applications: ["智能玩具", "教育/积木", "微型机器人", "云台/航模"],
|
||||
code: "4.A.01.B0001",
|
||||
},
|
||||
{
|
||||
id: "9m",
|
||||
name: "9克全金属齿舵机",
|
||||
subtitle: "高频使用与冲击负载优选",
|
||||
weight: 9,
|
||||
torque: 3.2,
|
||||
speed: 0.13,
|
||||
voltageMin: 4.8,
|
||||
voltageMax: 6,
|
||||
gear: "金属齿",
|
||||
price: 28.7,
|
||||
size: "23.00 × 12.36 × 28.50 mm",
|
||||
image: "/products/servo-9g-metal.jpg",
|
||||
applications: ["教育/积木", "微型机器人", "云台/航模", "工业设备"],
|
||||
code: "4.A.01.B0026",
|
||||
},
|
||||
{
|
||||
id: "17p",
|
||||
name: "17克塑料齿舵机",
|
||||
subtitle: "玩具机构的高性价比选择",
|
||||
weight: 17,
|
||||
torque: 5,
|
||||
speed: 0.1,
|
||||
voltageMin: 4.8,
|
||||
voltageMax: 6,
|
||||
gear: "塑料齿",
|
||||
price: 14.9,
|
||||
size: "28.60 × 13.00 × 31.00 mm",
|
||||
image: "/products/servo-17g-plastic.jpg",
|
||||
applications: ["智能玩具", "教育/积木", "微型机器人"],
|
||||
code: "4.A.01.A0002",
|
||||
},
|
||||
{
|
||||
id: "17m",
|
||||
name: "17克金属齿舵机",
|
||||
subtitle: "宽电压、高扭矩、耐冲击",
|
||||
weight: 17,
|
||||
torque: 8.8,
|
||||
speed: 0.18,
|
||||
voltageMin: 4.8,
|
||||
voltageMax: 8.4,
|
||||
gear: "金属齿",
|
||||
price: 27.8,
|
||||
size: "28.60 × 13.00 × 31.00 mm",
|
||||
image: "/products/servo-17g-metal.jpg",
|
||||
applications: ["智能玩具", "微型机器人", "云台/航模", "工业设备"],
|
||||
code: "4.A.01.B0007",
|
||||
},
|
||||
{
|
||||
id: "25p",
|
||||
name: "25克塑料齿舵机",
|
||||
subtitle: "中等负载的经济型方案",
|
||||
weight: 25,
|
||||
torque: 7.5,
|
||||
speed: 0.15,
|
||||
voltageMin: 4.8,
|
||||
voltageMax: 6,
|
||||
gear: "塑料齿",
|
||||
price: 16.4,
|
||||
size: "36.00 × 15.20 × 29.50 mm",
|
||||
image: "/products/servo-25g-plastic.jpg",
|
||||
applications: ["智能玩具", "教育/积木", "微型机器人"],
|
||||
code: "4.A.01.A0001",
|
||||
},
|
||||
{
|
||||
id: "25m",
|
||||
name: "25克金属齿舵机",
|
||||
subtitle: "中型机器人和高频机构",
|
||||
weight: 25,
|
||||
torque: 8.2,
|
||||
speed: 0.15,
|
||||
voltageMin: 4.8,
|
||||
voltageMax: 8.4,
|
||||
gear: "金属齿",
|
||||
price: 44.7,
|
||||
size: "36.00 × 15.20 × 29.50 mm",
|
||||
image: "/products/servo-25g-metal.jpg",
|
||||
applications: ["微型机器人", "云台/航模", "工业设备"],
|
||||
code: "4.A.01.B0014",
|
||||
},
|
||||
{
|
||||
id: "37p",
|
||||
name: "37克塑料齿舵机",
|
||||
subtitle: "标准尺寸、大负载经济型",
|
||||
weight: 37,
|
||||
torque: 6.8,
|
||||
speed: 0.22,
|
||||
voltageMin: 4.8,
|
||||
voltageMax: 6,
|
||||
gear: "塑料齿",
|
||||
price: 18.4,
|
||||
size: "40.85 × 20.15 × 39.15 mm",
|
||||
image: "/products/servo-37g-plastic.jpg",
|
||||
applications: ["智能玩具", "微型机器人", "工业设备"],
|
||||
code: "4.A.01.B0015",
|
||||
},
|
||||
{
|
||||
id: "37h",
|
||||
name: "37克半金属齿舵机",
|
||||
subtitle: "大扭矩与成本的平衡点",
|
||||
weight: 37,
|
||||
torque: 11.2,
|
||||
speed: 0.26,
|
||||
voltageMin: 4.8,
|
||||
voltageMax: 6,
|
||||
gear: "半金属齿",
|
||||
price: 32.9,
|
||||
size: "40.85 × 20.15 × 39.15 mm",
|
||||
image: "/products/servo-37g-hybrid.jpg",
|
||||
applications: ["微型机器人", "云台/航模", "工业设备"],
|
||||
code: "4.A.01.B0005",
|
||||
},
|
||||
{
|
||||
id: "37m",
|
||||
name: "37克金属齿舵机",
|
||||
subtitle: "24kgf·cm级强劲输出",
|
||||
weight: 37,
|
||||
torque: 24,
|
||||
speed: 0.22,
|
||||
voltageMin: 4.8,
|
||||
voltageMax: 8.4,
|
||||
gear: "金属齿",
|
||||
price: 37.6,
|
||||
size: "40.85 × 20.15 × 39.15 mm",
|
||||
image: "/products/servo-37g-metal.jpg",
|
||||
applications: ["机器人/机械臂", "云台/航模", "工业设备"],
|
||||
code: "4.A.01.B0017",
|
||||
},
|
||||
];
|
||||
|
||||
const APPLICATIONS = [
|
||||
{ name: "AI毛绒", note: "头部、耳朵、手臂等轻量动作" },
|
||||
{ name: "智能玩具", note: "互动机构、表情和行走结构" },
|
||||
{ name: "教育/积木", note: "STEAM套件与积木动力模块" },
|
||||
{ name: "微型机器人", note: "关节、夹爪和小型机械臂" },
|
||||
{ name: "云台/航模", note: "飞行控制、云台与模型机构" },
|
||||
{ name: "工业设备", note: "控制机构与定制传动组件" },
|
||||
];
|
||||
|
||||
const DEFAULT_REQUIREMENTS: Requirements = {
|
||||
application: "",
|
||||
torque: 2,
|
||||
voltage: 5,
|
||||
weightLimit: 40,
|
||||
gear: "不限",
|
||||
annualVolume: "5000–50000件",
|
||||
currentModel: "",
|
||||
painPoint: "交期",
|
||||
};
|
||||
|
||||
function getMatches(requirements: Requirements) {
|
||||
return PRODUCTS.map((product) => {
|
||||
let score = 34;
|
||||
const reasons: string[] = [];
|
||||
|
||||
if (product.applications.includes(requirements.application)) {
|
||||
score += 18;
|
||||
reasons.push(`适合${requirements.application}场景`);
|
||||
}
|
||||
|
||||
if (product.torque >= requirements.torque) {
|
||||
score += 25;
|
||||
const margin = Math.round((product.torque / requirements.torque - 1) * 100);
|
||||
reasons.push(`扭矩满足,约有${Math.max(0, margin)}%余量`);
|
||||
} else {
|
||||
score -= 70;
|
||||
}
|
||||
|
||||
if (
|
||||
requirements.voltage >= product.voltageMin &&
|
||||
requirements.voltage <= product.voltageMax
|
||||
) {
|
||||
score += 14;
|
||||
reasons.push(`${requirements.voltage}V供电兼容`);
|
||||
} else {
|
||||
score -= 35;
|
||||
}
|
||||
|
||||
if (product.weight <= requirements.weightLimit) {
|
||||
score += 10;
|
||||
reasons.push(`重量不超过${requirements.weightLimit}g`);
|
||||
} else {
|
||||
score -= 45;
|
||||
}
|
||||
|
||||
if (requirements.gear === "不限" || requirements.gear === product.gear) {
|
||||
score += requirements.gear === "不限" ? 4 : 12;
|
||||
if (requirements.gear !== "不限") reasons.push(`${product.gear}符合偏好`);
|
||||
} else if (requirements.gear === "金属齿" && product.gear !== "金属齿") {
|
||||
score -= 22;
|
||||
}
|
||||
|
||||
if (requirements.painPoint === "成本" && product.gear === "塑料齿") score += 8;
|
||||
if (requirements.painPoint === "耐久" && product.gear === "金属齿") score += 8;
|
||||
if (requirements.painPoint === "体积" && product.weight <= 9) score += 8;
|
||||
|
||||
return {
|
||||
product,
|
||||
score,
|
||||
confidence: Math.max(52, Math.min(96, score)),
|
||||
reasons: reasons.slice(0, 3),
|
||||
};
|
||||
}).sort((a, b) => b.score - a.score);
|
||||
}
|
||||
|
||||
function Metric({ label, value }: { label: string; value: string }) {
|
||||
return (
|
||||
<div className="metric">
|
||||
<span>{label}</span>
|
||||
<strong>{value}</strong>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
const [stage, setStage] = useState(0);
|
||||
const [requirements, setRequirements] = useState(DEFAULT_REQUIREMENTS);
|
||||
const [showSampleForm, setShowSampleForm] = useState(false);
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
const [leadId, setLeadId] = useState("");
|
||||
|
||||
const matches = useMemo(() => getMatches(requirements), [requirements]);
|
||||
const topMatches = matches.slice(0, 3);
|
||||
const top = topMatches[0];
|
||||
const needsEngineer =
|
||||
top.score < 60 ||
|
||||
requirements.annualVolume === "50000件以上" ||
|
||||
requirements.application === "工业设备";
|
||||
|
||||
function update<K extends keyof Requirements>(key: K, value: Requirements[K]) {
|
||||
setRequirements((current) => ({ ...current, [key]: value }));
|
||||
}
|
||||
|
||||
function reset() {
|
||||
setStage(1);
|
||||
setRequirements(DEFAULT_REQUIREMENTS);
|
||||
setShowSampleForm(false);
|
||||
setSubmitted(false);
|
||||
}
|
||||
|
||||
function submitLead(event: FormEvent<HTMLFormElement>) {
|
||||
event.preventDefault();
|
||||
const id = `GDL-${new Date().toISOString().slice(5, 10).replace("-", "")}-${String(
|
||||
Date.now(),
|
||||
).slice(-4)}`;
|
||||
setLeadId(id);
|
||||
setSubmitted(true);
|
||||
}
|
||||
|
||||
return (
|
||||
<main>
|
||||
<header className="site-header">
|
||||
<a className="brand" href="#top" aria-label="高徳乐 AI选型首页">
|
||||
<span className="brand-mark">G</span>
|
||||
<span>
|
||||
<strong>GAUDELOT</strong>
|
||||
<small>高徳乐 · 精密传动</small>
|
||||
</span>
|
||||
</a>
|
||||
<nav aria-label="主导航">
|
||||
<a href="#selector">AI选型</a>
|
||||
<a href="#products">产品能力</a>
|
||||
<a href="#how">服务流程</a>
|
||||
</nav>
|
||||
<button className="header-cta" type="button" onClick={() => setStage(1)}>
|
||||
开始选型 <span>→</span>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<section className="hero" id="top">
|
||||
<div className="hero-copy">
|
||||
<div className="eyebrow"><span /> AI 智能选型 · 工程师复核</div>
|
||||
<h1>
|
||||
3分钟,找到<br />
|
||||
<em>适合你的舵机</em>
|
||||
</h1>
|
||||
<p className="hero-lead">
|
||||
告诉我们应用、扭矩与结构限制。AI从高徳乐标准产品中生成候选方案,
|
||||
同步准备样品与替代选型摘要。
|
||||
</p>
|
||||
<div className="hero-actions">
|
||||
<button className="primary-action" type="button" onClick={() => setStage(1)}>
|
||||
免费开始选型 <span>→</span>
|
||||
</button>
|
||||
<a href="#products" className="text-action">查看能力范围</a>
|
||||
</div>
|
||||
<div className="trust-row">
|
||||
<span><b>13</b> 款标准样品</span>
|
||||
<span><b>0.09–24</b> kgf·cm</span>
|
||||
<span><b>48h</b> 方案响应</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="selector-shell" id="selector">
|
||||
<div className="selector-topbar">
|
||||
<div>
|
||||
<span className="live-dot" /> AI 选型助手
|
||||
</div>
|
||||
<span className="secure-note">仅作初选建议</span>
|
||||
</div>
|
||||
|
||||
{stage === 0 && (
|
||||
<div className="welcome-panel">
|
||||
<div className="assistant-avatar">AI</div>
|
||||
<p className="assistant-label">高徳乐选型助手</p>
|
||||
<h2>你好,我来帮你缩小选型范围。</h2>
|
||||
<p>回答3组问题,即可获得推荐型号、匹配理由和样品申请入口。</p>
|
||||
<button className="panel-primary" type="button" onClick={() => setStage(1)}>
|
||||
开始回答 <span>预计3分钟</span>
|
||||
</button>
|
||||
<div className="privacy-note">✓ 无需注册即可查看选型结果</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{stage > 0 && stage < 4 && (
|
||||
<div className="question-panel">
|
||||
<div className="progress-wrap" aria-label={`选型进度 ${stage}/3`}>
|
||||
<div className="progress-labels">
|
||||
<span>需求识别</span>
|
||||
<strong>{stage} / 3</strong>
|
||||
</div>
|
||||
<div className="progress-track"><i style={{ width: `${stage * 33.33}%` }} /></div>
|
||||
</div>
|
||||
|
||||
{stage === 1 && (
|
||||
<div className="question-step">
|
||||
<p className="step-kicker">第一步 · 使用场景</p>
|
||||
<h2>舵机将用在什么产品上?</h2>
|
||||
<p className="step-help">选择最接近的一项,后续可以补充具体结构。</p>
|
||||
<div className="choice-grid">
|
||||
{APPLICATIONS.map((item) => (
|
||||
<button
|
||||
type="button"
|
||||
key={item.name}
|
||||
className={`choice-card ${requirements.application === item.name ? "selected" : ""}`}
|
||||
onClick={() => update("application", item.name)}
|
||||
>
|
||||
<b>{item.name}</b>
|
||||
<small>{item.note}</small>
|
||||
<span className="choice-check">✓</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{stage === 2 && (
|
||||
<div className="question-step">
|
||||
<p className="step-kicker">第二步 · 核心参数</p>
|
||||
<h2>需要多大的输出能力?</h2>
|
||||
<p className="step-help">不确定时可填写估算值,工程师会在送样前复核。</p>
|
||||
<div className="field-stack">
|
||||
<label className="field-label" htmlFor="torque">
|
||||
最低堵转扭矩 <strong>{requirements.torque} kgf·cm</strong>
|
||||
</label>
|
||||
<input
|
||||
id="torque"
|
||||
className="range-input"
|
||||
type="range"
|
||||
min="0.1"
|
||||
max="24"
|
||||
step="0.1"
|
||||
value={requirements.torque}
|
||||
onChange={(event) => update("torque", Number(event.target.value))}
|
||||
/>
|
||||
<div className="range-scale"><span>0.1</span><span>5</span><span>10</span><span>15</span><span>24</span></div>
|
||||
</div>
|
||||
<div className="two-fields">
|
||||
<label className="select-field">
|
||||
<span>系统工作电压</span>
|
||||
<select
|
||||
value={requirements.voltage}
|
||||
onChange={(event) => update("voltage", Number(event.target.value))}
|
||||
>
|
||||
<option value={3.7}>3.7V</option>
|
||||
<option value={4.2}>4.2V</option>
|
||||
<option value={5}>5.0V</option>
|
||||
<option value={6}>6.0V</option>
|
||||
<option value={7.4}>7.4V</option>
|
||||
<option value={8.4}>8.4V</option>
|
||||
</select>
|
||||
</label>
|
||||
<label className="select-field">
|
||||
<span>单只重量上限</span>
|
||||
<select
|
||||
value={requirements.weightLimit}
|
||||
onChange={(event) => update("weightLimit", Number(event.target.value))}
|
||||
>
|
||||
<option value={2}>2g以内</option>
|
||||
<option value={4}>4g以内</option>
|
||||
<option value={10}>10g以内</option>
|
||||
<option value={20}>20g以内</option>
|
||||
<option value={40}>40g以内</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{stage === 3 && (
|
||||
<div className="question-step">
|
||||
<p className="step-kicker">第三步 · 项目信息</p>
|
||||
<h2>最后,告诉我采购侧的偏好。</h2>
|
||||
<p className="step-help">这些信息用于计算推荐优先级,不会改变公开参考价。</p>
|
||||
<div className="field-group">
|
||||
<span className="field-title">齿轮偏好</span>
|
||||
<div className="pill-row">
|
||||
{(["不限", "塑料齿", "半金属齿", "金属齿"] as const).map((gear) => (
|
||||
<button
|
||||
type="button"
|
||||
key={gear}
|
||||
className={requirements.gear === gear ? "active" : ""}
|
||||
onClick={() => update("gear", gear)}
|
||||
>{gear}</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="two-fields">
|
||||
<label className="select-field">
|
||||
<span>预计年度用量</span>
|
||||
<select
|
||||
value={requirements.annualVolume}
|
||||
onChange={(event) => update("annualVolume", event.target.value)}
|
||||
>
|
||||
<option>500件以内</option>
|
||||
<option>500–5000件</option>
|
||||
<option>5000–50000件</option>
|
||||
<option>50000件以上</option>
|
||||
</select>
|
||||
</label>
|
||||
<label className="select-field">
|
||||
<span>最想解决的问题</span>
|
||||
<select
|
||||
value={requirements.painPoint}
|
||||
onChange={(event) => update("painPoint", event.target.value)}
|
||||
>
|
||||
<option>交期</option>
|
||||
<option>成本</option>
|
||||
<option>耐久</option>
|
||||
<option>体积</option>
|
||||
<option>一致性</option>
|
||||
<option>二供替代</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<label className="text-field">
|
||||
<span>当前使用型号(选填)</span>
|
||||
<input
|
||||
value={requirements.currentModel}
|
||||
onChange={(event) => update("currentModel", event.target.value)}
|
||||
placeholder="例如:SG90 / DS-E001 / 自定义型号"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="panel-nav">
|
||||
<button className="back-button" type="button" onClick={() => setStage(stage - 1)}>← 返回</button>
|
||||
<button
|
||||
className="next-button"
|
||||
type="button"
|
||||
disabled={stage === 1 && !requirements.application}
|
||||
onClick={() => setStage(stage + 1)}
|
||||
>
|
||||
{stage === 3 ? "生成选型方案" : "继续"} <span>→</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{stage === 4 && top && (
|
||||
<div className="result-panel">
|
||||
<div className="result-heading">
|
||||
<div>
|
||||
<p className="step-kicker">AI 初选结果</p>
|
||||
<h2>找到 {topMatches.length} 个候选方案</h2>
|
||||
</div>
|
||||
<button type="button" className="restart-button" onClick={reset}>重新选型</button>
|
||||
</div>
|
||||
|
||||
<div className="best-match">
|
||||
<div className="match-image-wrap">
|
||||
<img src={top.product.image} alt={top.product.name} />
|
||||
<span className="match-badge">首选推荐</span>
|
||||
</div>
|
||||
<div className="match-content">
|
||||
<div className="match-score"><span>匹配度</span><strong>{top.confidence}%</strong></div>
|
||||
<p className="product-code">{top.product.code}</p>
|
||||
<h3>{top.product.name}</h3>
|
||||
<p className="product-subtitle">{top.product.subtitle}</p>
|
||||
<div className="metric-grid">
|
||||
<Metric label="堵转扭矩" value={`${top.product.torque} kgf·cm`} />
|
||||
<Metric label="空载速度" value={`≤${top.product.speed}s/60°`} />
|
||||
<Metric label="工作电压" value={`${top.product.voltageMin}–${top.product.voltageMax}V`} />
|
||||
<Metric label="齿轮材质" value={top.product.gear} />
|
||||
</div>
|
||||
<ul className="reason-list">
|
||||
{top.reasons.map((reason) => <li key={reason}>✓ {reason}</li>)}
|
||||
</ul>
|
||||
<div className="price-line">
|
||||
<span>商城参考价</span>
|
||||
<strong>¥{top.product.price.toFixed(1)}</strong>
|
||||
<small>/ 只 · 批量价需确认</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{needsEngineer && (
|
||||
<div className="engineer-alert">
|
||||
<span>工程师复核</span>
|
||||
<p>你的项目包含高用量、工业场景或边界参数,系统已标记为优先人工复核。</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="alternative-list">
|
||||
{topMatches.slice(1).map((match) => (
|
||||
<div className="alternative-card" key={match.product.id}>
|
||||
<img src={match.product.image} alt={match.product.name} />
|
||||
<div>
|
||||
<span>{match.confidence}% 匹配</span>
|
||||
<h4>{match.product.name}</h4>
|
||||
<p>{match.product.torque} kgf·cm · {match.product.gear} · ¥{match.product.price.toFixed(1)}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{!showSampleForm && (
|
||||
<div className="result-actions">
|
||||
<button className="panel-primary" type="button" onClick={() => setShowSampleForm(true)}>
|
||||
申请样品与工程师复核 <span>→</span>
|
||||
</button>
|
||||
<button className="outline-button" type="button" onClick={() => window.print()}>打印 / 保存方案</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showSampleForm && !submitted && (
|
||||
<form className="sample-form" onSubmit={submitLead}>
|
||||
<div>
|
||||
<p className="step-kicker">样品申请</p>
|
||||
<h3>留下项目联系方式</h3>
|
||||
<p>演示版会生成一张线索卡;正式版可接入CRM、企微或商城订单。</p>
|
||||
</div>
|
||||
<div className="form-grid">
|
||||
<label><span>公司名称</span><input required name="company" placeholder="请输入公司名称" /></label>
|
||||
<label><span>联系人</span><input required name="name" placeholder="姓名" /></label>
|
||||
<label><span>手机号</span><input required name="phone" inputMode="tel" placeholder="用于样品确认" /></label>
|
||||
<label><span>样品数量</span><select name="quantity"><option>1–2只</option><option>3–5只</option><option>6–10只</option></select></label>
|
||||
</div>
|
||||
<label className="full-field"><span>补充说明</span><textarea name="notes" placeholder="安装尺寸、线长、角度、控制协议或测试时间要求" /></label>
|
||||
<button className="panel-primary" type="submit">生成样品申请单 <span>→</span></button>
|
||||
<small className="demo-disclaimer">当前为内部演示,不会向外部系统发送信息。</small>
|
||||
</form>
|
||||
)}
|
||||
|
||||
{submitted && (
|
||||
<div className="success-card">
|
||||
<div className="success-icon">✓</div>
|
||||
<p className="step-kicker">线索卡已生成</p>
|
||||
<h3>申请编号 {leadId}</h3>
|
||||
<p>推荐型号:{top.product.name}。正式版上线后,此处将自动进入CRM并触发技术复核。</p>
|
||||
<button type="button" className="outline-button" onClick={reset}>继续测试另一组需求</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="capability-strip" aria-label="高徳乐能力">
|
||||
<div><strong>2万㎡</strong><span>研发与制造基地</span></div>
|
||||
<div><strong>137台</strong><span>精密注塑设备</span></div>
|
||||
<div><strong>1万台/天</strong><span>单线自动化产能</span></div>
|
||||
<div><strong>IATF 16949</strong><span>汽车行业质量体系</span></div>
|
||||
</section>
|
||||
|
||||
<section className="products-section" id="products">
|
||||
<div className="section-heading">
|
||||
<div>
|
||||
<p className="eyebrow"><span /> 标准样品范围</p>
|
||||
<h2>从超微型到24kgf·cm</h2>
|
||||
</div>
|
||||
<p>原型首批接入13款标准舵机。定制协议、特殊尺寸和更大扭矩项目将自动转入工程师方案。</p>
|
||||
</div>
|
||||
<div className="product-band">
|
||||
{[
|
||||
{ name: "微型轻量", range: "1.7g–3.7g", note: "AI毛绒 · 微型机构", image: "/products/servo-2g.jpg" },
|
||||
{ name: "通用标准", range: "9g–17g", note: "玩具 · 教育 · 航模", image: "/products/servo-9g-hybrid.jpg" },
|
||||
{ name: "中等负载", range: "25g–37g", note: "机器人 · 工业机构", image: "/products/servo-37g-metal.jpg" },
|
||||
].map((item) => (
|
||||
<article key={item.name}>
|
||||
<img src={item.image} alt={item.name} />
|
||||
<div><span>{item.name}</span><h3>{item.range}</h3><p>{item.note}</p></div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="how-section" id="how">
|
||||
<div className="how-copy">
|
||||
<p className="eyebrow light"><span /> 无人销售边界</p>
|
||||
<h2>标准需求自动完成,<br />复杂项目及时接管。</h2>
|
||||
<p>AI负责需求采集、初选、说明和线索评分。工程师负责最终适配、认证和技术承诺,销售负责大客户商业条件。</p>
|
||||
<button className="primary-action light-button" type="button" onClick={() => { setStage(1); window.scrollTo({ top: 0, behavior: "smooth" }); }}>
|
||||
体验完整流程 <span>→</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="flow-list">
|
||||
<div><b>01</b><span><strong>客户自助描述需求</strong><small>应用、参数、数量和现用型号</small></span></div>
|
||||
<div><b>02</b><span><strong>AI生成候选方案</strong><small>匹配理由、参考价格和风险提示</small></span></div>
|
||||
<div><b>03</b><span><strong>标准样品自动申请</strong><small>形成结构化线索卡和跟进计划</small></span></div>
|
||||
<div><b>04</b><span><strong>复杂项目人工接管</strong><small>技术复核、测试、报价和量产</small></span></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div className="brand footer-brand">
|
||||
<span className="brand-mark">G</span>
|
||||
<span><strong>GAUDELOT</strong><small>高徳乐 · 精密传动</small></span>
|
||||
</div>
|
||||
<p>AI选型结果仅供初步筛选,最终型号、价格、交期与适配结果以工程师和正式文件确认为准。</p>
|
||||
<span>内部原型 · V1</span>
|
||||
</footer>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user