feat: 更新咨询表单和后端服务

- 优化表单布局:姓氏+下拉、公司、手机、邮箱、关注目标对齐
- 后端服务适配新表单字段(title, company, concern)
- 数据保存到项目目录下的 data/ 文件夹
- 飞书同步字段适配新表单结构
This commit is contained in:
chiguyong 2026-05-25 14:40:36 +08:00
parent 21386ac5bb
commit 4476e7adf3
10 changed files with 704 additions and 196 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

BIN
assets/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
assets/logo-b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -105,12 +105,12 @@ class ConsultService:
def __init__(self):
self.feishu_config = FeishuConfig()
self.data_dir = "/opt/ai-landing/data"
self.data_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
os.makedirs(self.data_dir, exist_ok=True)
# 初始化飞书客户端
self.bitable_client = None
if self.feishu_config.APP_ID and self.feishu_config.BITABLE_APP_TOKEN:
if self.feishu_config.APP_ID and self.feishu_config.APP_SECRET and self.feishu_config.BITABLE_APP_TOKEN and self.feishu_config.BITABLE_TABLE_ID:
try:
self.bitable_client = FeishuBitableClient(self.feishu_config)
print("✓ 飞书多维表格客户端初始化成功")
@ -145,8 +145,12 @@ class ConsultService:
"""
# 提取字段
name = data.get("name", "").strip()
title = data.get("title", "先生").strip()
phone = data.get("phone", "").strip()
email = data.get("email", "").strip()
company = data.get("company", "").strip()
concern = data.get("concern", []) # 关注目标
# 兼容旧字段
current_system = data.get("current_system", [])
system_name = data.get("system_name", "").strip()
message = data.get("message", "").strip()
@ -170,8 +174,11 @@ class ConsultService:
record = {
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"name": name,
"title": title,
"phone": phone,
"email": email,
"company": company,
"concern": ",".join(concern) if concern else "",
"current_system": ",".join(current_system) if current_system else "",
"system_name": system_name,
"message": message,
@ -221,22 +228,21 @@ class ConsultService:
return
try:
# 构建飞书字段格式
# 构建飞书字段格式(适配新表单字段)
fields = {
"姓名": record["name"],
"姓名": record["name"] + record["title"],
"手机": record["phone"],
"咨询内容": record["message"],
"处理状态": "待联系" # 默认状态
}
if record["email"]:
fields["邮箱"] = record["email"]
if record["current_system"]:
fields["当前使用系统"] = record["current_system"].split(",")
if record["company"]:
fields["公司"] = record["company"]
if record["system_name"]:
fields["系统名称"] = record["system_name"]
if record["concern"]:
fields["关注目标"] = record["concern"].split(",")
# 创建记录
result = self.bitable_client.create_record(fields)
@ -249,7 +255,8 @@ class ConsultService:
def _send_feishu_notification(self, record: Dict[str, Any]):
"""发送飞书机器人通知"""
try:
systems_text = record["current_system"] or "未填写"
concern_text = record["concern"] or "未填写"
company_text = record["company"] or "未填写"
msg = {
"msg_type": "interactive",
@ -266,25 +273,12 @@ class ConsultService:
"tag": "markdown",
"content": (
f"**客户信息**\n"
f"- 姓名:{record['name']}\n"
f"- 姓名:{record['name']}{record['title']}\n"
f"- 电话:{record['phone']}\n"
f"- 邮箱:{record['email'] or '未填写'}\n\n"
f"**业务信息**\n"
f"- 当前系统:{systems_text}\n"
f"- 系统名称:{record['system_name'] or ''}\n\n"
f"**咨询内容**\n{record['message'] or ''}\n\n"
f"- 公司:{company_text}\n\n"
f"**关注目标**\n{concern_text}\n\n"
f"⏰ 时间:{record['time']}"
)
},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "📞 立即联系"},
"type": "primary"
}
]
}
]
}

15
data/2026-05.json Normal file
View File

@ -0,0 +1,15 @@
[
{
"time": "2026-05-25 14:38:38",
"name": "张三",
"title": "先生",
"phone": "13800138000",
"email": "test@example.com",
"company": "测试公司",
"concern": "智能获客,智能增效",
"current_system": "",
"system_name": "",
"message": "",
"source": "官网表单"
}
]

View File

@ -277,34 +277,6 @@
.testimonials {
background: var(--bg-soft); padding: 80px 32px;
}
.testimonials-inner { max-width: var(--max-width); margin: 0 auto; }
.testimonials-header { text-align: center; margin-bottom: 48px; }
.testimonials-header h2 {
font-family: 'Space Grotesk', sans-serif; font-size: 36px; font-weight: 700;
}
.testimonial-grid {
display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;
}
.testimonial-card {
padding: 32px; background: var(--bg);
border: 1px solid var(--divider); border-radius: var(--radius-lg);
}
.testimonial-card p {
font-size: 15px; color: var(--text-2); line-height: 1.7;
margin-bottom: 20px;
}
.testimonial-author {
display: flex; align-items: center; gap: 12px;
}
.testimonial-avatar {
width: 40px; height: 40px; border-radius: 50%;
background: linear-gradient(135deg, var(--brand), var(--brand-light));
display: flex; align-items: center; justify-content: center;
color: #fff; font-size: 14px; font-weight: 700;
}
.testimonial-author div { font-size: 14px; }
.testimonial-author div span { display: block; color: var(--text-3); font-size: 12px; }
/* ========== CTA ========== */
.cta {
padding: 80px 32px; max-width: var(--max-width); margin: 0 auto;
@ -320,6 +292,172 @@
}
.cta p { color: var(--text-2); font-size: 17px; margin-bottom: 32px; }
/* ========== CONTACT FORM ========== */
.contact {
padding: 80px 32px;
max-width: 800px;
margin: 0 auto;
}
.contact-header {
text-align: center;
margin-bottom: 48px;
}
.contact-header h2 {
font-family: 'Space Grotesk', 'Noto Sans SC', sans-serif;
font-size: 36px;
font-weight: 700;
margin-bottom: 16px;
}
.contact-header p {
color: var(--text-2);
font-size: 17px;
max-width: 600px;
margin: 0 auto;
}
.contact-form {
background: var(--bg);
border: 1px solid var(--divider);
border-radius: var(--radius-lg);
padding: 40px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.name-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.name-row .name-part {
display: grid;
grid-template-columns: 1fr 80px;
gap: 12px;
}
.checkbox-group {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
}
.form-group input,
.form-group select {
padding: 12px 16px;
font-size: 15px;
border: 1px solid var(--divider);
border-radius: var(--radius);
background: var(--bg);
color: var(--text-1);
transition: border-color 0.2s, box-shadow 0.2s;
box-sizing: border-box;
font-family: inherit;
}
.form-group select {
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
padding-right: 36px;
}
.form-group {
margin-bottom: 24px;
}
.form-group label {
display: block;
font-size: 14px;
font-weight: 500;
color: var(--text-1);
margin-bottom: 8px;
}
.form-group .required {
color: #ef4444;
}
.form-group input,
.form-group textarea {
width: 100%;
padding: 12px 16px;
font-size: 15px;
border: 1px solid var(--divider);
border-radius: var(--radius);
background: var(--bg);
color: var(--text-1);
transition: border-color 0.2s, box-shadow 0.2s;
box-sizing: border-box;
font-family: inherit;
}
.form-group input:focus,
.form-group textarea:focus {
outline: none;
border-color: var(--brand);
box-shadow: 0 0 0 3px var(--brand-soft);
}
.form-group input::placeholder,
.form-group textarea::placeholder {
color: var(--text-3);
}
.form-group textarea {
resize: vertical;
min-height: 100px;
}
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.checkbox-label {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
padding: 8px 16px;
border: 1px solid var(--divider);
border-radius: var(--radius);
font-size: 14px;
color: var(--text-2);
transition: all 0.2s;
}
.checkbox-label:hover {
border-color: var(--brand);
color: var(--brand);
}
.checkbox-label input {
display: none;
}
.checkbox-label input:checked + span {
color: var(--brand);
}
.checkbox-label:has(input:checked) {
background: var(--brand-soft);
border-color: var(--brand);
}
.form-actions {
display: flex;
justify-content: center;
margin-top: 8px;
}
.btn-submit {
padding: 14px 48px;
font-size: 16px;
}
.form-message {
margin-top: 16px;
padding: 12px 16px;
border-radius: var(--radius);
font-size: 14px;
text-align: center;
display: none;
}
.form-message.success {
display: block;
background: #dcfce7;
color: #166534;
}
.form-message.error {
display: block;
background: #fee2e2;
color: #991b1b;
}
/* ========== FOOTER ========== */
.footer {
border-top: 1px solid var(--divider); padding: 48px 32px;
@ -343,14 +481,14 @@
.service-row.reverse .service-text { order: 1; }
.service-row.reverse .service-img { order: 2; }
.how-steps { grid-template-columns: repeat(2, 1fr); }
.testimonial-grid { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
.nav-links { display: none; }
.features-grid { grid-template-columns: 1fr; }
.how-steps { grid-template-columns: 1fr; }
.service-metric { flex-direction: column; gap: 16px; }
.cta-box { padding: 40px 24px; }
.form-row { grid-template-columns: 1fr; }
.contact-form { padding: 24px; }
.footer { flex-direction: column; gap: 16px; text-align: center; }
}
</style>
@ -366,8 +504,7 @@
<a href="#features">核心能力</a>
<a href="#services">解决方案</a>
<a href="#how">实施流程</a>
<a href="#testimonials">客户评价</a>
<a href="#contact" class="nav-cta">预约诊断</a>
<a href="#contact">预约咨询</a>
</nav>
</div>
</header>
@ -468,12 +605,13 @@
<section class="services" id="services">
<div class="services-inner">
<div class="services-header">
<h2>不同部门,不同解法</h2>
<p>看看你的部门适合哪种方案</p>
<h2>不同场景,不同解法</h2>
<p>看看你的业务适合哪种方案</p>
</div>
<!-- 智能获客 -->
<div class="service-row">
<div class="service-text">
<span class="service-tag">适合市场部、销售部</span>
<span class="service-tag">智能获客 · 适合市场部、销售部</span>
<h3>线索不够?客户跟不过来?</h3>
<p>市场部写内容太慢、SEO没效果销售部线索质量差、跟进不及时。我们用GEO优化让你的品牌出现在AI搜索结果里同时给CRM加个智能层——自动清洗线索、提醒跟进、生成客户画像。市场部少花冤枉钱销售部多成单。</p>
<div class="service-metric">
@ -488,12 +626,13 @@
</div>
</div>
<div class="service-img">
<img src="https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=800&h=500&fit=crop" alt="营销获客">
<img src="https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=800&h=500&fit=crop" alt="智能获客">
</div>
</div>
<!-- 智能增效 -->
<div class="service-row reverse">
<div class="service-text">
<span class="service-tag">适合生产部、质检部</span>
<span class="service-tag">智能增效 · 适合生产部、质检部</span>
<h3>产量上不去?质量问题反复?</h3>
<p>生产计划靠经验、设备坏了才修、质检漏检率高。我们在现有MES/ERP系统上加个智能层——预测设备故障提前修、自动排产减少换线、质检数据实时分析找规律。产量稳住质量提升不用加人。</p>
<div class="service-metric">
@ -508,32 +647,13 @@
</div>
</div>
<div class="service-img">
<img src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&h=500&fit=crop" alt="提质增效">
<img src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&h=500&fit=crop" alt="智能增效">
</div>
</div>
<!-- 智能助手 -->
<div class="service-row">
<div class="service-text">
<span class="service-tag">适合老板、管理层</span>
<h3>报表等太久?决策靠感觉?</h3>
<p>每周一等报表、数据散落在各个系统、发现问题已经晚了。我们把所有系统的数据接进来,老板随时问"这个月哪个区域利润最高""库存有没有风险",秒出答案。不用等周报,不用催下属,打开手机就能看。</p>
<div class="service-metric">
<div class="metric-item">
<h4>一问即答</h4>
<span>自然语言查数据</span>
</div>
<div class="metric-item">
<h4>风险预警</h4>
<span>提前发现问题</span>
</div>
</div>
</div>
<div class="service-img">
<img src="https://images.unsplash.com/photo-1553877522-43269d4ea984?w=800&h=500&fit=crop" alt="决策支持">
</div>
</div>
<div class="service-row reverse">
<div class="service-text">
<span class="service-tag">适合财务部、人事行政</span>
<span class="service-tag">智能助手 · 适合财务部、人事行政</span>
<h3>对账对到眼花?表格做不完?</h3>
<p>财务月底对账要加班、报销单据堆成山;人事算考勤算绩效、行政管资产管采购,全是重复劳动。我们在现有财务/人事系统上加个自动化层——自动对账、智能报销审核、考勤异常自动标记、资产到期自动提醒。减少80%重复工作。</p>
<div class="service-metric">
@ -548,7 +668,28 @@
</div>
</div>
<div class="service-img">
<img src="https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?w=800&h=500&fit=crop" alt="数据处理">
<img src="https://images.unsplash.com/photo-1553877522-43269d4ea984?w=800&h=500&fit=crop" alt="智能助手">
</div>
</div>
<!-- 智能洞察 -->
<div class="service-row reverse">
<div class="service-text">
<span class="service-tag">智能洞察 · 适合老板、管理层</span>
<h3>报表等太久?决策靠感觉?</h3>
<p>每周一等报表、数据散落在各个系统、发现问题已经晚了。我们把所有系统的数据接进来,老板随时问"这个月哪个区域利润最高""库存有没有风险",秒出答案。不用等周报,不用催下属,打开手机就能看。</p>
<div class="service-metric">
<div class="metric-item">
<h4>一问即答</h4>
<span>自然语言查数据</span>
</div>
<div class="metric-item">
<h4>风险预警</h4>
<span>提前发现问题</span>
</div>
</div>
</div>
<div class="service-img">
<img src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&h=500&fit=crop" alt="智能洞察">
</div>
</div>
</div>
@ -584,44 +725,63 @@
</div>
</section>
<!-- Testimonials -->
<section class="testimonials" id="testimonials">
<div class="testimonials-inner">
<div class="testimonials-header">
<h2>客户原话</h2>
<!-- Contact Form -->
<section class="contact" id="contact">
<div class="contact-inner">
<div class="contact-header">
<h2>先聊聊,不花钱</h2>
<p>30分钟电话说说你们现在哪个环节最头疼。我们看看能不能帮上忙。</p>
</div>
<div class="testimonial-grid">
<div class="testimonial-card">
<p>"销售部之前每天花2小时填表现在系统自动生成跟进记录他们终于有时间见客户了。"</p>
<div class="testimonial-author">
<div class="testimonial-avatar"></div>
<div>某制造企业 <span>销售总监</span></div>
<form class="contact-form" id="consultForm">
<div class="form-group">
<label>我怎么称呼您</label>
<div class="name-row">
<div class="name-part">
<input type="text" name="name" placeholder="姓氏" required>
<select name="title">
<option value="先生">先生</option>
<option value="女士">女士</option>
</select>
</div>
<input type="text" name="company" placeholder="公司名称">
</div>
</div>
<div class="testimonial-card">
<p>"以前月底对账要加班3天现在系统自动对财务部的姑娘说终于能准时下班了。"</p>
<div class="testimonial-author">
<div class="testimonial-avatar"></div>
<div>某贸易公司 <span>财务经理</span></div>
<div class="form-group">
<label>我怎么联系您</label>
<div class="name-row">
<input type="tel" name="phone" placeholder="手机" required>
<input type="email" name="email" placeholder="邮箱">
</div>
</div>
<div class="testimonial-card">
<p>"老板以前周一早上催报表,现在他自己手机上看实时数据,不找我要了。"</p>
<div class="testimonial-author">
<div class="testimonial-avatar"></div>
<div>某零售企业 <span>运营经理</span></div>
<div class="form-group">
<label>关注目标</label>
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" name="concern" value="智能获客">
<span>智能获客</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="concern" value="智能增效">
<span>智能增效</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="concern" value="智能助手">
<span>智能助手</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="concern" value="智能洞察">
<span>智能洞察</span>
</label>
</div>
</div>
</div>
</div>
</section>
<!-- CTA -->
<section class="cta" id="contact">
<div class="cta-box">
<h2>先聊聊,不花钱</h2>
<p>30分钟电话说说你们现在用什么系统、哪个环节最头疼。我们看看能不能帮上忙。</p>
<a href="mailto:contact@fischerai.cn" class="btn btn-primary">预约免费诊断</a>
<div class="form-actions">
<button type="submit" class="btn btn-primary btn-submit">
<span class="btn-text">提交咨询</span>
<span class="btn-loading" style="display:none">提交中...</span>
</button>
</div>
<div class="form-message" id="formMessage"></div>
</form>
</div>
</section>
@ -674,12 +834,85 @@
});
});
// Animate testimonials
gsap.utils.toArray('.testimonial-card').forEach((card, i) => {
gsap.from(card, {
y: 20, opacity: 0, duration: 0.5, delay: i * 0.1,
scrollTrigger: { trigger: card, start: 'top 85%' }
});
// Animate contact section
gsap.from('.contact-header', {
y: 20, opacity: 0, duration: 0.5,
scrollTrigger: { trigger: '.contact', start: 'top 80%' }
});
gsap.from('.contact-form', {
y: 30, opacity: 0, duration: 0.6,
scrollTrigger: { trigger: '.contact', start: 'top 80%' }
});
// Form submission
const form = document.getElementById('consultForm');
const formMessage = document.getElementById('formMessage');
const submitBtn = form.querySelector('.btn-submit');
const btnText = submitBtn.querySelector('.btn-text');
const btnLoading = submitBtn.querySelector('.btn-loading');
form.addEventListener('submit', async (e) => {
e.preventDefault();
// Get form data
const formData = new FormData(form);
const title = formData.get('title') || '先生';
const name = formData.get('name') || '';
const data = {
name: name,
title: title,
phone: formData.get('phone'),
email: formData.get('email') || '',
company: formData.get('company') || '',
concern: formData.getAll('concern')
};
// Format display name
const displayName = name + title;
// Validate
if (!data.name || data.name.length < 2) {
formMessage.className = 'form-message error';
formMessage.textContent = '请输入正确的姓名至少2个字符';
return;
}
if (!data.phone || !/^1\d{10}$/.test(data.phone)) {
formMessage.className = 'form-message error';
formMessage.textContent = '请输入正确的手机号11位数字';
return;
}
// Show loading
btnText.style.display = 'none';
btnLoading.style.display = 'inline';
submitBtn.disabled = true;
try {
const response = await fetch('/api/consult', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const result = await response.json();
if (response.ok) {
formMessage.className = 'form-message success';
formMessage.textContent = '提交成功!我们会尽快联系您。';
form.reset();
} else {
formMessage.className = 'form-message error';
formMessage.textContent = result.error || '提交失败,请稍后重试。';
}
} catch (err) {
formMessage.className = 'form-message error';
formMessage.textContent = '网络错误,请稍后重试。';
}
// Reset button
btnText.style.display = 'inline';
btnLoading.style.display = 'none';
submitBtn.disabled = false;
});
</script>
</body>

View File

@ -320,6 +320,177 @@
}
.cta p { color: var(--text-2); font-size: 17px; margin-bottom: 32px; }
/* ========== CONTACT FORM ========== */
.contact {
padding: 80px 32px;
max-width: 800px;
margin: 0 auto;
}
.contact-header {
text-align: center;
margin-bottom: 48px;
}
.contact-header h2 {
font-family: 'Space Grotesk', 'Noto Sans SC', sans-serif;
font-size: 36px;
font-weight: 700;
margin-bottom: 16px;
}
.contact-header p {
color: var(--text-2);
font-size: 17px;
max-width: 600px;
margin: 0 auto;
}
.contact-form {
background: var(--bg);
border: 1px solid var(--divider);
border-radius: var(--radius-lg);
padding: 40px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.name-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.name-row .name-part {
display: grid;
grid-template-columns: 1fr 80px;
gap: 12px;
}
.contact-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.checkbox-group {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
}
.form-group input,
.form-group select {
padding: 12px 16px;
font-size: 15px;
border: 1px solid var(--divider);
border-radius: var(--radius);
background: var(--bg);
color: var(--text-1);
transition: border-color 0.2s, box-shadow 0.2s;
box-sizing: border-box;
font-family: inherit;
}
.form-group select {
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
padding-right: 36px;
}
.form-group {
margin-bottom: 24px;
}
.form-group label {
display: block;
font-size: 14px;
font-weight: 500;
color: var(--text-1);
margin-bottom: 8px;
}
.form-group .required {
color: #ef4444;
}
.form-group input,
.form-group textarea {
width: 100%;
padding: 12px 16px;
font-size: 15px;
border: 1px solid var(--divider);
border-radius: var(--radius);
background: var(--bg);
color: var(--text-1);
transition: border-color 0.2s, box-shadow 0.2s;
box-sizing: border-box;
font-family: inherit;
}
.form-group input:focus,
.form-group textarea:focus {
outline: none;
border-color: var(--brand);
box-shadow: 0 0 0 3px var(--brand-soft);
}
.form-group input::placeholder,
.form-group textarea::placeholder {
color: var(--text-3);
}
.form-group textarea {
resize: vertical;
min-height: 100px;
}
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.checkbox-label {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
padding: 8px 16px;
border: 1px solid var(--divider);
border-radius: var(--radius);
font-size: 14px;
color: var(--text-2);
transition: all 0.2s;
}
.checkbox-label:hover {
border-color: var(--brand);
color: var(--brand);
}
.checkbox-label input {
display: none;
}
.checkbox-label input:checked + span {
color: var(--brand);
}
.checkbox-label:has(input:checked) {
background: var(--brand-soft);
border-color: var(--brand);
}
.form-actions {
display: flex;
justify-content: center;
margin-top: 8px;
}
.btn-submit {
padding: 14px 48px;
font-size: 16px;
}
.form-message {
margin-top: 16px;
padding: 12px 16px;
border-radius: var(--radius);
font-size: 14px;
text-align: center;
display: none;
}
.form-message.success {
display: block;
background: #dcfce7;
color: #166534;
}
.form-message.error {
display: block;
background: #fee2e2;
color: #991b1b;
}
/* ========== FOOTER ========== */
.footer {
border-top: 1px solid var(--divider); padding: 48px 32px;
@ -343,14 +514,14 @@
.service-row.reverse .service-text { order: 1; }
.service-row.reverse .service-img { order: 2; }
.how-steps { grid-template-columns: repeat(2, 1fr); }
.testimonial-grid { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
.nav-links { display: none; }
.features-grid { grid-template-columns: 1fr; }
.how-steps { grid-template-columns: 1fr; }
.service-metric { flex-direction: column; gap: 16px; }
.cta-box { padding: 40px 24px; }
.form-row { grid-template-columns: 1fr; }
.contact-form { padding: 24px; }
.footer { flex-direction: column; gap: 16px; text-align: center; }
}
</style>
@ -366,8 +537,7 @@
<a href="#features">核心能力</a>
<a href="#services">解决方案</a>
<a href="#how">实施流程</a>
<a href="#testimonials">客户评价</a>
<a href="#contact" class="nav-cta">预约诊断</a>
<a href="#contact">预约咨询</a>
</nav>
</div>
</header>
@ -468,12 +638,13 @@
<section class="services" id="services">
<div class="services-inner">
<div class="services-header">
<h2>不同部门,不同解法</h2>
<p>看看你的部门适合哪种方案</p>
<h2>不同场景,不同解法</h2>
<p>看看你的业务适合哪种方案</p>
</div>
<!-- 智能获客 -->
<div class="service-row">
<div class="service-text">
<span class="service-tag">适合市场部、销售部</span>
<span class="service-tag">智能获客 · 适合市场部、销售部</span>
<h3>线索不够?客户跟不过来?</h3>
<p>市场部写内容太慢、SEO没效果销售部线索质量差、跟进不及时。我们用GEO优化让你的品牌出现在AI搜索结果里同时给CRM加个智能层——自动清洗线索、提醒跟进、生成客户画像。市场部少花冤枉钱销售部多成单。</p>
<div class="service-metric">
@ -488,12 +659,13 @@
</div>
</div>
<div class="service-img">
<img src="https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=800&h=500&fit=crop" alt="营销获客">
<img src="https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=800&h=500&fit=crop" alt="智能获客">
</div>
</div>
<!-- 智能增效 -->
<div class="service-row reverse">
<div class="service-text">
<span class="service-tag">适合生产部、质检部</span>
<span class="service-tag">智能增效 · 适合生产部、质检部</span>
<h3>产量上不去?质量问题反复?</h3>
<p>生产计划靠经验、设备坏了才修、质检漏检率高。我们在现有MES/ERP系统上加个智能层——预测设备故障提前修、自动排产减少换线、质检数据实时分析找规律。产量稳住质量提升不用加人。</p>
<div class="service-metric">
@ -508,32 +680,13 @@
</div>
</div>
<div class="service-img">
<img src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&h=500&fit=crop" alt="提质增效">
<img src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&h=500&fit=crop" alt="智能增效">
</div>
</div>
<!-- 智能助手 -->
<div class="service-row">
<div class="service-text">
<span class="service-tag">适合老板、管理层</span>
<h3>报表等太久?决策靠感觉?</h3>
<p>每周一等报表、数据散落在各个系统、发现问题已经晚了。我们把所有系统的数据接进来,老板随时问"这个月哪个区域利润最高""库存有没有风险",秒出答案。不用等周报,不用催下属,打开手机就能看。</p>
<div class="service-metric">
<div class="metric-item">
<h4>一问即答</h4>
<span>自然语言查数据</span>
</div>
<div class="metric-item">
<h4>风险预警</h4>
<span>提前发现问题</span>
</div>
</div>
</div>
<div class="service-img">
<img src="https://images.unsplash.com/photo-1553877522-43269d4ea984?w=800&h=500&fit=crop" alt="决策支持">
</div>
</div>
<div class="service-row reverse">
<div class="service-text">
<span class="service-tag">适合财务部、人事行政</span>
<span class="service-tag">智能助手 · 适合财务部、人事行政</span>
<h3>对账对到眼花?表格做不完?</h3>
<p>财务月底对账要加班、报销单据堆成山;人事算考勤算绩效、行政管资产管采购,全是重复劳动。我们在现有财务/人事系统上加个自动化层——自动对账、智能报销审核、考勤异常自动标记、资产到期自动提醒。减少80%重复工作。</p>
<div class="service-metric">
@ -548,7 +701,28 @@
</div>
</div>
<div class="service-img">
<img src="https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?w=800&h=500&fit=crop" alt="数据处理">
<img src="https://images.unsplash.com/photo-1553877522-43269d4ea984?w=800&h=500&fit=crop" alt="智能助手">
</div>
</div>
<!-- 智能洞察 -->
<div class="service-row reverse">
<div class="service-text">
<span class="service-tag">智能洞察 · 适合老板、管理层</span>
<h3>报表等太久?决策靠感觉?</h3>
<p>每周一等报表、数据散落在各个系统、发现问题已经晚了。我们把所有系统的数据接进来,老板随时问"这个月哪个区域利润最高""库存有没有风险",秒出答案。不用等周报,不用催下属,打开手机就能看。</p>
<div class="service-metric">
<div class="metric-item">
<h4>一问即答</h4>
<span>自然语言查数据</span>
</div>
<div class="metric-item">
<h4>风险预警</h4>
<span>提前发现问题</span>
</div>
</div>
</div>
<div class="service-img">
<img src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&h=500&fit=crop" alt="智能洞察">
</div>
</div>
</div>
@ -584,44 +758,63 @@
</div>
</section>
<!-- Testimonials -->
<section class="testimonials" id="testimonials">
<div class="testimonials-inner">
<div class="testimonials-header">
<h2>客户原话</h2>
<!-- Contact Form -->
<section class="contact" id="contact">
<div class="contact-inner">
<div class="contact-header">
<h2>先聊聊,不花钱</h2>
<p>30分钟电话说说你们现在哪个环节最头疼。我们看看能不能帮上忙。</p>
</div>
<div class="testimonial-grid">
<div class="testimonial-card">
<p>"销售部之前每天花2小时填表现在系统自动生成跟进记录他们终于有时间见客户了。"</p>
<div class="testimonial-author">
<div class="testimonial-avatar"></div>
<div>某制造企业 <span>销售总监</span></div>
<form class="contact-form" id="consultForm">
<div class="form-group">
<label>我怎么称呼您</label>
<div class="name-row">
<div class="name-part">
<input type="text" name="name" placeholder="姓氏" required>
<select name="title">
<option value="先生">先生</option>
<option value="女士">女士</option>
</select>
</div>
<input type="text" name="company" placeholder="公司名称">
</div>
</div>
<div class="testimonial-card">
<p>"以前月底对账要加班3天现在系统自动对财务部的姑娘说终于能准时下班了。"</p>
<div class="testimonial-author">
<div class="testimonial-avatar"></div>
<div>某贸易公司 <span>财务经理</span></div>
<div class="form-group">
<label>我怎么联系您</label>
<div class="contact-row">
<input type="tel" name="phone" placeholder="手机" required>
<input type="email" name="email" placeholder="邮箱">
</div>
</div>
<div class="testimonial-card">
<p>"老板以前周一早上催报表,现在他自己手机上看实时数据,不找我要了。"</p>
<div class="testimonial-author">
<div class="testimonial-avatar"></div>
<div>某零售企业 <span>运营经理</span></div>
<div class="form-group">
<label>关注目标</label>
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" name="concern" value="智能获客">
<span>智能获客</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="concern" value="智能增效">
<span>智能增效</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="concern" value="智能助手">
<span>智能助手</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="concern" value="智能洞察">
<span>智能洞察</span>
</label>
</div>
</div>
</div>
</div>
</section>
<!-- CTA -->
<section class="cta" id="contact">
<div class="cta-box">
<h2>先聊聊,不花钱</h2>
<p>30分钟电话说说你们现在用什么系统、哪个环节最头疼。我们看看能不能帮上忙。</p>
<a href="mailto:contact@fischerai.cn" class="btn btn-primary">预约免费诊断</a>
<div class="form-actions">
<button type="submit" class="btn btn-primary btn-submit">
<span class="btn-text">提交咨询</span>
<span class="btn-loading" style="display:none">提交中...</span>
</button>
</div>
<div class="form-message" id="formMessage"></div>
</form>
</div>
</section>
@ -674,12 +867,85 @@
});
});
// Animate testimonials
gsap.utils.toArray('.testimonial-card').forEach((card, i) => {
gsap.from(card, {
y: 20, opacity: 0, duration: 0.5, delay: i * 0.1,
scrollTrigger: { trigger: card, start: 'top 85%' }
});
// Animate contact section
gsap.from('.contact-header', {
y: 20, opacity: 0, duration: 0.5,
scrollTrigger: { trigger: '.contact', start: 'top 80%' }
});
gsap.from('.contact-form', {
y: 30, opacity: 0, duration: 0.6,
scrollTrigger: { trigger: '.contact', start: 'top 80%' }
});
// Form submission
const form = document.getElementById('consultForm');
const formMessage = document.getElementById('formMessage');
const submitBtn = form.querySelector('.btn-submit');
const btnText = submitBtn.querySelector('.btn-text');
const btnLoading = submitBtn.querySelector('.btn-loading');
form.addEventListener('submit', async (e) => {
e.preventDefault();
// Get form data
const formData = new FormData(form);
const title = formData.get('title') || '先生';
const name = formData.get('name') || '';
const data = {
name: name,
title: title,
phone: formData.get('phone'),
email: formData.get('email') || '',
company: formData.get('company') || '',
concern: formData.getAll('concern')
};
// Format display name
const displayName = name + title;
// Validate
if (!data.name || data.name.length < 2) {
formMessage.className = 'form-message error';
formMessage.textContent = '请输入正确的姓名至少2个字符';
return;
}
if (!data.phone || !/^1\d{10}$/.test(data.phone)) {
formMessage.className = 'form-message error';
formMessage.textContent = '请输入正确的手机号11位数字';
return;
}
// Show loading
btnText.style.display = 'none';
btnLoading.style.display = 'inline';
submitBtn.disabled = true;
try {
const response = await fetch('/api/consult', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const result = await response.json();
if (response.ok) {
formMessage.className = 'form-message success';
formMessage.textContent = '提交成功!我们会尽快联系您。';
form.reset();
} else {
formMessage.className = 'form-message error';
formMessage.textContent = result.error || '提交失败,请稍后重试。';
}
} catch (err) {
formMessage.className = 'form-message error';
formMessage.textContent = '网络错误,请稍后重试。';
}
// Reset button
btnText.style.display = 'inline';
btnLoading.style.display = 'none';
submitBtn.disabled = false;
});
</script>
</body>