From 3340b6ace33f6ede95faf9e7b79105ba45a49090 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 23 Feb 2026 15:51:30 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20v3.0=E5=B0=81=E7=89=88=E2=80=94?= =?UTF-8?q?=E2=80=94=E6=B7=B7=E5=90=88=E9=A2=98=E5=9E=8B=E6=B0=94=E6=B3=A1?= =?UTF-8?q?UI=EF=BC=8CSession=E6=96=87=E4=BB=B6=E6=8C=81=E4=B9=85=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E6=8A=A5=E5=91=8A=E7=94=9F=E6=88=90=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=EF=BC=8C=E5=B7=B2=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8=E8=B7=B3?= =?UTF-8?q?=E6=8A=A5=E5=91=8A=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + app/chat/page.jsx | 243 ++++++++++++++++++++----------------- server.js | 303 +++++++++++++++++++++++++--------------------- 3 files changed, 298 insertions(+), 249 deletions(-) diff --git a/.gitignore b/.gitignore index d781a65..dd76867 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules/ .next/ .env *.tar.gz +data/ diff --git a/app/chat/page.jsx b/app/chat/page.jsx index 4ef9611..aa5cfc3 100644 --- a/app/chat/page.jsx +++ b/app/chat/page.jsx @@ -2,7 +2,6 @@ import { useEffect, useRef, useState } from 'react'; import { useRouter } from 'next/navigation'; -// ── 星空Canvas ────────────────────────────────────────── function Starfield() { const canvasRef = useRef(null); useEffect(() => { @@ -62,16 +61,9 @@ function Starfield() { window.removeEventListener('resize', resize); }; }, []); - return ( - - ); + return ; } -// ── 淡入淡出文字组件 ────────────────────────────────────── function FadeText({ text, visible, className = '' }) { return (
{ const timers = [ setTimeout(() => setPhase(1), 600), @@ -100,24 +90,10 @@ function Intro({ onDone }) { return (
- - -
= 5 ? 1 : 0, transform: phase >= 5 ? 'translateY(0)' : 'translateY(12px)' }} - > -
@@ -125,34 +101,50 @@ function Intro({ onDone }) { ); } -// ── 单问题沉浸视图 ──────────────────────────────────────── -function QuestionView({ question, onAnswer, questionIndex, total }) { +const fixedOptions = { + fixed_gender: ['男生', '女生', '不想说'], + fixed_age: ['20以下', '20-25', '26-30', '31-40', '40以上'], + fixed_birth_month: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], + fixed_birth_day: Array.from({ length: 31 }, (_, i) => `${i + 1}日`), +}; + +function QuestionView({ prompt, onAnswer }) { const [visible, setVisible] = useState(false); const [input, setInput] = useState(''); const [leaving, setLeaving] = useState(false); + const [picked, setPicked] = useState(''); const inputRef = useRef(null); useEffect(() => { setVisible(false); setInput(''); setLeaving(false); + setPicked(''); const t = setTimeout(() => { setVisible(true); - setTimeout(() => inputRef.current?.focus(), 600); + if ((prompt?.type || 'text') === 'text') { + setTimeout(() => inputRef.current?.focus(), 600); + } }, 100); return () => clearTimeout(t); - }, [question]); + }, [prompt]); - const submit = () => { - if (!input.trim()) return; + const submit = (val) => { + const answer = (val || '').trim(); + if (!answer) return; setLeaving(true); - setTimeout(() => onAnswer(input.trim()), 800); + setTimeout(() => onAnswer(answer), 700); }; + const type = prompt?.type || 'text'; + const isChoice = type === 'choice' || type.startsWith('fixed_'); + const question = prompt?.question || prompt?.reply || ''; + const options = type === 'choice' ? (prompt.options || []) : (fixedOptions[type] || []); + const compact = type === 'fixed_birth_day'; + return (
-
- {/* 问题 */} +
- {/* 输入 */} -
-