在移动端首页实现一个现代化的水墨画风格智能助手,包含浮动按钮和对话界面。
src/client/mobile/components/SmartAssistant/
├── FloatingButton.tsx # 浮动按钮组件
├── ChatWindow.tsx # 对话窗口组件
├── MessageBubble.tsx # 消息气泡组件
├── ChatInput.tsx # 输入区域组件
├── SmartAssistant.tsx # 主组件整合
└── styles/ # 样式文件
├── ink-styles.css # 水墨画风格样式
└── animations.css # 动画定义
.slide-up {
transform: translateY(100%);
transition: transform 0.3s ease-out;
}
.slide-up.active {
transform: translateY(0);
}
.icon-rotate {
transition: transform 0.3s ease;
}
.icon-rotate.active {
transform: rotate(45deg);
}
.message-enter {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.3s, transform 0.3s;
}
.message-enter-active {
opacity: 1;
transform: translateY(0);
}
// SmartAssistant.tsx
interface Message {
id: string;
text: string;
sender: 'user' | 'bot';
timestamp: Date;
}
interface SmartAssistantProps {
isOpen: boolean;
onToggle: () => void;
}
const SmartAssistant: React.FC<SmartAssistantProps> = ({ isOpen, onToggle }) => {
const [messages, setMessages] = useState<Message[]>([]);
const [inputText, setInputText] = useState('');
const messagesEndRef = useRef<HTMLDivElement>(null);
// 自动滚动到底部
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
};
// 发送消息
const handleSend = async (text: string) => {
if (!text.trim()) return;
const newMessage: Message = {
id: Date.now().toString(),
text,
sender: 'user',
timestamp: new Date()
};
setMessages(prev => [...prev, newMessage]);
setInputText('');
// 模拟自动回复
setTimeout(() => {
const botReply: Message = {
id: (Date.now() + 1).toString(),
text: generateBotReply(text),
sender: 'bot',
timestamp: new Date()
};
setMessages(prev => [...prev, botReply]);
}, 1500);
};
return (
<>
<FloatingButton isOpen={isOpen} onClick={onToggle} />
<ChatWindow
isOpen={isOpen}
messages={messages}
inputText={inputText}
onSend={handleSend}
onClose={onToggle}
onInputChange={setInputText}
messagesEndRef={messagesEndRef}
/>
</>
);
};
/* 水墨画风格 */
.ink-floating-button {
position: fixed;
bottom: 120px;
right: 20px;
width: 56px;
height: 56px;
border-radius: 50%;
background: rgba(245, 243, 240, 0.9);
border: 1px solid #d4c4a8;
box-shadow: 0 4px 12px rgba(139, 115, 85, 0.15);
backdrop-filter: blur(8px);
z-index: 1000;
transition: all 0.3s ease;
}
.ink-floating-button:hover {
transform: scale(1.1);
box-shadow: 0 6px 20px rgba(139, 115, 85, 0.25);
}
.ink-chat-window {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 70vh;
background: rgba(245, 243, 240, 0.95);
backdrop-filter: blur(20px);
border-radius: 20px 20px 0 0;
border: 1px solid #d4c4a8;
box-shadow: 0 -4px 20px rgba(139, 115, 85, 0.1);
z-index: 999;
transform: translateY(100%);
transition: transform 0.3s ease-out;
}
.ink-chat-window.open {
transform: translateY(0);
}
.message-bubble {
max-width: 80%;
padding: 12px 16px;
border-radius: 18px;
margin: 8px 0;
font-size: 14px;
line-height: 1.4;
word-wrap: break-word;
}
.message-bubble.user {
background: #4a6b7c;
color: white;
margin-left: auto;
border-bottom-right-radius: 4px;
}
.message-bubble.bot {
background: #d4c4a8;
color: #2f1f0f;
margin-right: auto;
border-bottom-left-radius: 4px;
}
在NewHomePage.tsx中添加:
const [isAssistantOpen, setIsAssistantOpen] = useState(false);
// 在return中添加
<SmartAssistant
isOpen={isAssistantOpen}
onToggle={() => setIsAssistantOpen(!isAssistantOpen)}
/>
在NewHomePage.tsx顶部添加:
import SmartAssistant from '../components/SmartAssistant/SmartAssistant';
import '../components/SmartAssistant/styles/ink-styles.css';