fix: make CMS content live and migrate to MySQL

This commit is contained in:
Codex User
2026-09-08 13:55:30 +08:00
parent 3a99ae30c5
commit 60eb793299
17 changed files with 455 additions and 825 deletions
+25 -13
View File
@@ -1,8 +1,9 @@
import { useState } from 'react'
import { useState, useMemo } from 'react'
import { Link } from 'react-router-dom'
import GlobalCTA from '@/components/Layout/GlobalCTA'
import { useCMS, getCMSSelfCheck } from '@/services/cms'
type CheckItem = { id: string; question: string; dimension: string }
type CheckItem = { id: string; question: string; dimension: string; options?: string[] }
const CHECK_ITEMS: CheckItem[] = [
{ id: 'q1', question: '战略方向在团队中是否清晰一致?', dimension: '战略价值' },
@@ -12,6 +13,14 @@ const CHECK_ITEMS: CheckItem[] = [
]
export default function SelfCheck() {
const { data: cmsCheck } = useCMS(getCMSSelfCheck, null)
const items = useMemo(() => {
try {
const parsed = JSON.parse(cmsCheck?.questions || '[]')
if (!Array.isArray(parsed) || !parsed.length) return CHECK_ITEMS
return parsed.map((item: any, index: number) => ({ id: item.id || `q${index + 1}`, question: item.q || item.question || '', dimension: item.dimension || `价值维度 ${index + 1}`, options: item.options }))
} catch { return CHECK_ITEMS }
}, [cmsCheck])
const [answers, setAnswers] = useState<Record<string, string>>({})
const [showResult, setShowResult] = useState(false)
@@ -29,7 +38,7 @@ export default function SelfCheck() {
</div>
<h1></h1>
<p>
× A/M/B
{cmsCheck?.guide || '轻量自我对照工具,帮助你快速定位在四大价值 × A/M/B 的大致位置。'}
<br />
<strong style={{ color: '#fde68a' }}></strong>线
</p>
@@ -39,17 +48,19 @@ export default function SelfCheck() {
<section className="section">
<div className="container" style={{ maxWidth: 720 }}>
<div className="card">
<h3>4 </h3>
<h3>{items.length} </h3>
<p style={{ fontSize: 13, color: '#64748b' }}></p>
<div style={{ marginTop: 16, display: 'grid', gap: 16 }}>
{CHECK_ITEMS.map(item => (
{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' }}>
{['A 较清晰/顺畅', 'M 部分卡点', 'B 待构建'].map(opt => (
{(item.options || ['A 较清晰/顺畅', 'M 部分卡点', 'B 待构建']).map((opt: any) => {
const label = typeof opt === 'string' ? opt : opt.label
return (
<label
key={opt}
key={label}
style={{
border: answers[item.id] === opt ? '1px solid #163E70' : '1px solid #e2e8f0',
background: answers[item.id] === opt ? '#eff6ff' : '#fff',
@@ -59,10 +70,11 @@ export default function SelfCheck() {
cursor: 'pointer',
}}
>
<input type="radio" name={item.id} value={opt} checked={answers[item.id] === opt} onChange={() => set(item.id, opt)} style={{ marginRight: 6 }} />
{opt}
<input type="radio" name={item.id} value={label} checked={answers[item.id] === label} onChange={() => set(item.id, label)} style={{ marginRight: 6 }} />
{label}
</label>
))}
)
})}
</div>
</div>
))}
@@ -78,14 +90,14 @@ export default function SelfCheck() {
<div className="card" style={{ marginTop: 16, background: '#f8fafc' }}>
<h3></h3>
<p style={{ fontSize: 13, color: '#475569' }}>
{cmsCheck?.logic_text || '基于你的选择,系统提示关注维度:'}
<br />
{Object.entries(answers)
.map(([k, v]) => `${CHECK_ITEMS.find(i => i.id === k)?.dimension}${v}`)
.map(([k, v]) => `${items.find(i => i.id === k)?.dimension}${v}`)
.join('') || '(请选择后再查看)'}
</p>
<div className="placeholder" style={{ marginTop: 10 }}>
{cmsCheck?.next_guide || '此处仅为轻量对照提示,不生成诊断报告。深度诊断请预约陪跑。'}
</div>
<div style={{ display: 'flex', gap: 10, marginTop: 12, flexWrap: 'wrap' }}>
<Link to="/contact" className="btn btn-primary">