feat: merge V1.3 CMS content support

This commit is contained in:
Codex User
2026-09-09 10:34:10 +08:00
parent 7608dc5415
commit 4e87dcb849
9 changed files with 96 additions and 53 deletions
+9 -7
View File
@@ -1,18 +1,21 @@
import { Link } from 'react-router-dom'
import { PRIMARY_NAV } from '@/data/nav'
import { getCMSConfig, useCMS, useCMSTexts } from '@/services/cms'
export default function Footer() {
const { data: config } = useCMS(getCMSConfig, null)
const { data: texts } = useCMSTexts()
return (
<footer className="site-footer">
<div className="container footer-grid">
<div>
<div className="footer-brand">成都阿美巴企业管理咨询有限公司</div>
<div className="footer-brand">{texts['footer.company'] || '成都阿美巴企业管理咨询有限公司'}</div>
<p className="footer-desc">
以“企业进化”为核心主张,以四大价值坐标与 A/M/B 状态坐标为观察系,陪跑企业体系化增长落地。
{texts['footer.description'] || config?.slogan || '帮助企业看清位置、找到方向、持续进化。'}
</p>
</div>
<div>
<h4>一级导航(冻结6项)</h4>
<h4>{texts['footer.navigation_title'] || '网站导航'}</h4>
<ul>
{PRIMARY_NAV.map(n => (
<li key={n.key}>
@@ -22,7 +25,7 @@ export default function Footer() {
</ul>
</div>
<div>
<h4>常驻行动入口</h4>
<h4>{texts['footer.action_title'] || '行动入口'}</h4>
<ul>
<li>
<Link to="/self-check">看看你的企业(轻量对照)</Link>
@@ -31,12 +34,11 @@ export default function Footer() {
<Link to="/contact">咨询获取方案</Link>
</li>
</ul>
<h4 style={{ marginTop: 16 }}>部署</h4>
<p className="footer-desc">复用现有服务器与域名 · 旧站完整备份可回滚</p>
{(config?.hotline || config?.contact_email) && <p className="footer-desc" style={{marginTop:16}}>{[config.hotline, config.contact_email].filter(Boolean).join(' · ')}</p>}
</div>
</div>
<div className="container footer-bottom">
<p>© 2026 成都阿美巴企业管理咨询有限公司 | aiameiba.com · ameiba.cn</p>
<p>{texts['footer.copyright'] || '© 2026 成都阿美巴企业管理咨询有限公司 | aiameiba.com · ameiba.cn'}</p>
<p className="footer-links">
<Link to="/contact">联系我们</Link> · <Link to="/self-check">看看你的企业</Link>
</p>
+3 -1
View File
@@ -1,5 +1,5 @@
import { Link } from 'react-router-dom'
import { useCMSTexts } from '@/services/cms'
import { useCMS, useCMSTexts, getCMSConfig } from '@/services/cms'
interface Props {
title?: string
@@ -19,6 +19,7 @@ export default function GlobalCTA({
secondaryTo = '/self-check',
}: Props) {
const { data: texts } = useCMSTexts()
const { data: config } = useCMS(getCMSConfig, null)
title = texts['global_cta.title'] || title
desc = texts['global_cta.description'] || desc
primaryLabel = texts['global_cta.primary'] || primaryLabel
@@ -31,6 +32,7 @@ export default function GlobalCTA({
<p>{desc}</p>
</div>
<div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
{config?.qr_image_url && <a href={config.qr_target_url || config.qr_image_url} target="_blank" rel="noreferrer" title={config.qr_label || '扫码咨询'}><img src={config.qr_image_url} alt={config.qr_label || '咨询二维码'} style={{width:56,height:56,objectFit:'contain',background:'#fff',borderRadius:6,padding:3}}/></a>}
<Link to={primaryTo} className="btn" style={{ background: '#fff', color: '#163E70' }}>
{primaryLabel} →
</Link>
+7 -2
View File
@@ -1,9 +1,10 @@
import { useState } from 'react'
import { Link } from 'react-router-dom'
import { useCMSTexts } from '@/services/cms'
import { useCMS, useCMSTexts, getCMSConfig } from '@/services/cms'
export default function Contact() {
const { data: texts } = useCMSTexts()
const { data: config } = useCMS(getCMSConfig, null)
const [form, setForm] = useState({ name: '', company: '', phone: '', need: '' })
const [submitted, setSubmitted] = useState(false)
const [error, setError] = useState('')
@@ -100,7 +101,11 @@ export default function Contact() {
</div>
<div style={{ display: 'grid', gap: 16, alignContent: 'start' }}>
<div className="card">
<h3>其他通道</h3>
<h3>{texts['contact.channels_title'] || '其他通道'}</h3>
{config?.hotline && <p><strong>{texts['contact.hotline_label'] || '联系电话'}:</strong>{config.hotline}</p>}
{config?.contact_email && <p><strong>{texts['contact.email_label'] || '联系邮箱'}:</strong>{config.contact_email}</p>}
{config?.contact_address && <p><strong>{texts['contact.address_label'] || '联系地址'}:</strong>{config.contact_address}</p>}
{config?.qr_image_url && <a href={config.qr_target_url || config.qr_image_url} target="_blank" rel="noreferrer" style={{display:'inline-grid',gap:8,marginTop:8,color:'inherit'}}><img src={config.qr_image_url} alt={config.qr_label || '联系二维码'} style={{width:140,height:140,objectFit:'contain',borderRadius:8}}/><span style={{fontSize:13}}>{config.qr_label || texts['contact.qr_default_label'] || '扫码联系我们'}</span></a>}
</div>
<div className="card">
<h3>快速路径</h3>
+11 -1
View File
@@ -1,10 +1,11 @@
import { Link } from 'react-router-dom'
import { METHODS as FALLBACK_METHODS } from '@/data/mock'
import { useCMS, useCMSTexts, getCMSMethods } from '@/services/cms'
import { useCMS, useCMSTexts, getCMSMethods, getCMSEvolutionProcess } from '@/services/cms'
import GlobalCTA from '@/components/Layout/GlobalCTA'
export default function Methods() {
const { data: METHODS } = useCMS(getCMSMethods, FALLBACK_METHODS)
const { data: process } = useCMS(getCMSEvolutionProcess, null)
const { data: texts } = useCMSTexts()
return (
<div>
@@ -22,6 +23,15 @@ export default function Methods() {
</div>
<section className="section">
<div className="container">
{process && (process.description || process.steps || process.scenarios) && (
<div className="card" style={{ marginBottom: 24 }}>
<p className="eyebrow">{texts['methods.process_eyebrow'] || '企业进化梳理'}</p>
<h2>{texts['methods.process_title'] || '从看清现状到持续进化'}</h2>
{process.description && <p>{process.description}</p>}
{process.steps && <p style={{ fontWeight: 700, color: '#163E70', marginTop: 14 }}>{process.steps}</p>}
{process.scenarios && <p style={{ fontSize: 13, color: '#64748b', marginTop: 10 }}><strong>{texts['methods.process_scenario_label'] || '适用场景'}:</strong>{process.scenarios}</p>}
</div>
)}
<div className="grid-2">
{METHODS.map(m => (
<Link key={m.id} to={`/methods/${m.slug}`} className="card" style={{ display: 'block' }}>
+14 -16
View File
@@ -6,10 +6,10 @@ import { useCMS, useCMSTexts, getCMSSelfCheck } from '@/services/cms'
type CheckItem = { id: string; question: string; dimension: string; options?: string[] }
const CHECK_ITEMS: CheckItem[] = [
{ id: 'q1', question: '战略方向在团队中是否清晰一致?', dimension: '战略价值' },
{ id: 'q2', question: '组织协同是否顺畅、职责是否清晰?', dimension: '组织价值' },
{ id: 'q3', question: '经营机制(目标/复盘/数据)是否闭环?', dimension: '经营价值' },
{ id: 'q4', question: '团队是否具备经营意识与成长机制?', dimension: '人的价值' },
{ id: 'q1', question: '当客户需求发生变化时,你通常如何发现这种变化?', dimension: '价值创造' },
{ id: 'q2', question: '一个第一次认识你的客户,通常需要通过什么方式理解你与其他企业有什么不同?', dimension: '价值传递' },
{ id: 'q3', question: '客户完成一次合作后,你通常如何判断他是否真正获得了你承诺的价值?', dimension: '价值交付' },
{ id: 'q4', question: '当团队遇到新挑战时,你通常依靠什么来支撑下一步行动?', dimension: '价值支持' },
]
export default function SelfCheck() {
@@ -37,7 +37,7 @@ export default function SelfCheck() {
</Link>{' '}
/ 看看你的企业
</div>
<h1>看看你的企业</h1>
<h1>{texts['selfcheck.title'] || '看看你的企业'}</h1>
<p>
{cmsCheck?.guide || '轻量自我对照工具,帮助你快速定位在四大价值 × A/M/B 的大致位置。'}
<br />
@@ -49,22 +49,22 @@ export default function SelfCheck() {
<section className="section">
<div className="container" style={{ maxWidth: 720 }}>
<div className="card">
<h3>轻量对照({items.length} 题)</h3>
<p style={{ fontSize: 13, color: '#64748b' }}>每题选择最贴近现状的选项,结果仅作自我对照参考,不生成诊断报告。</p>
<h3>{texts['selfcheck.form_title'] || '企业进化自我观察'}({items.length} 题)</h3>
<p style={{ fontSize: 13, color: '#64748b' }}>{texts['selfcheck.form_description'] || '每题选择最贴近现状的状态,用于帮助你观察企业,不用于评分或排名。'}</p>
<div style={{ marginTop: 16, display: 'grid', gap: 16 }}>
{items.map(item => (
<div key={item.id} style={{ border: '1px solid #e2e8f0', borderRadius: 10, padding: 16 }}>
<div style={{ fontSize: 12, color: '#0f6b5b', fontWeight: 800 }}>{item.dimension}</div>
<div style={{ fontWeight: 700, marginTop: 4 }}>{item.question}</div>
<div style={{ display: 'flex', gap: 8, marginTop: 10, flexWrap: 'wrap' }}>
{(item.options || ['A 较清晰/顺畅', 'M 部分卡点', 'B 待构建']).map((opt: any) => {
{(item.options || ['A态·入态', 'M态·优态', 'B态·越态']).map((opt: any) => {
const label = typeof opt === 'string' ? opt : opt.label
return (
<label
key={label}
style={{
border: answers[item.id] === opt ? '1px solid #163E70' : '1px solid #e2e8f0',
background: answers[item.id] === opt ? '#eff6ff' : '#fff',
border: answers[item.id] === label ? '1px solid #163E70' : '1px solid #e2e8f0',
background: answers[item.id] === label ? '#eff6ff' : '#fff',
padding: '8px 12px',
borderRadius: 999,
fontSize: 13,
@@ -82,7 +82,7 @@ export default function SelfCheck() {
</div>
<button className="btn btn-primary" style={{ width: '100%', marginTop: 20 }} onClick={() => setShowResult(true)}>
查看轻量对照结果
{texts['selfcheck.submit'] || '查看自我观察结果'}
</button>
<p style={{ fontSize: 11, color: '#94a3b8', marginTop: 8, textAlign: 'center' }}>{texts['selfcheck.storage_note'] || '结果仅本地展示,不存储。'}</p>
</div>
@@ -102,18 +102,16 @@ export default function SelfCheck() {
</div>
<div style={{ display: 'flex', gap: 10, marginTop: 12, flexWrap: 'wrap' }}>
<Link to="/contact" className="btn btn-primary">
预约深度诊断
{texts['selfcheck.contact_cta'] || '咨询获取更多观察视角'}
</Link>
<Link to="/evolution" className="btn btn-ghost">
了解进化坐标
{texts['selfcheck.evolution_cta'] || '了解企业进化坐标'}
</Link>
</div>
</div>
)}
<div className="placeholder" style={{ marginTop: 16 }}>
快速路径:看看你的企业 → 轻量对照 → 预约咨询 / 深度路径:企业进化 → 四大价值 → A/M/B → 联系我们(全链路已打通)
</div>
{texts['selfcheck.path_note'] && <div className="placeholder" style={{ marginTop: 16 }}>{texts['selfcheck.path_note']}</div>}
</div>
</section>