update
This commit is contained in:
		
							
								
								
									
										190
									
								
								web/src/apps/muse/prompts/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								web/src/apps/muse/prompts/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,190 @@
 | 
			
		||||
import React, { useState, useRef, useEffect } from 'react';
 | 
			
		||||
import { Send, Bot, User } from 'lucide-react';
 | 
			
		||||
 | 
			
		||||
interface Message {
 | 
			
		||||
  id: string;
 | 
			
		||||
  content: string;
 | 
			
		||||
  role: 'user' | 'assistant';
 | 
			
		||||
  timestamp: Date;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const ChatInterface: React.FC = () => {
 | 
			
		||||
  const [messages, setMessages] = useState<Message[]>([
 | 
			
		||||
    {
 | 
			
		||||
      id: '1',
 | 
			
		||||
      content: '你好!我是AI助手,有什么可以帮助您的吗?',
 | 
			
		||||
      role: 'assistant',
 | 
			
		||||
      timestamp: new Date()
 | 
			
		||||
    }
 | 
			
		||||
  ]);
 | 
			
		||||
  const [inputValue, setInputValue] = useState('');
 | 
			
		||||
  const [isLoading, setIsLoading] = useState(false);
 | 
			
		||||
  const messagesEndRef = useRef<HTMLDivElement>(null);
 | 
			
		||||
  const inputRef = useRef<HTMLTextAreaElement>(null);
 | 
			
		||||
 | 
			
		||||
  // 自动滚动到最新消息
 | 
			
		||||
  const scrollToBottom = () => {
 | 
			
		||||
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    scrollToBottom();
 | 
			
		||||
  }, [messages]);
 | 
			
		||||
 | 
			
		||||
  // 发送消息
 | 
			
		||||
  const handleSend = async () => {
 | 
			
		||||
    if (!inputValue.trim() || isLoading) return;
 | 
			
		||||
 | 
			
		||||
    const userMessage: Message = {
 | 
			
		||||
      id: Date.now().toString(),
 | 
			
		||||
      content: inputValue.trim(),
 | 
			
		||||
      role: 'user',
 | 
			
		||||
      timestamp: new Date()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    setMessages(prev => [...prev, userMessage]);
 | 
			
		||||
    setInputValue('');
 | 
			
		||||
    setIsLoading(true);
 | 
			
		||||
 | 
			
		||||
    // 模拟AI回复
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      const aiMessage: Message = {
 | 
			
		||||
        id: (Date.now() + 1).toString(),
 | 
			
		||||
        content: `我收到了您的消息:"${userMessage.content}"。这里是我的回复,您还有其他问题吗?`,
 | 
			
		||||
        role: 'assistant',
 | 
			
		||||
        timestamp: new Date()
 | 
			
		||||
      };
 | 
			
		||||
      setMessages(prev => [...prev, aiMessage]);
 | 
			
		||||
      setIsLoading(false);
 | 
			
		||||
    }, 1000);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // 处理键盘事件
 | 
			
		||||
  const handleKeyDown = (e: React.KeyboardEvent) => {
 | 
			
		||||
    if (e.key === 'Enter' && !e.shiftKey) {
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      handleSend();
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // 格式化时间
 | 
			
		||||
  const formatTime = (date: Date) => {
 | 
			
		||||
    return date.toLocaleTimeString('zh-CN', { 
 | 
			
		||||
      hour: '2-digit', 
 | 
			
		||||
      minute: '2-digit' 
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="h-full flex flex-col bg-gray-50">
 | 
			
		||||
      {/* 头部 */}
 | 
			
		||||
      <div className="bg-white border-b border-gray-200 p-4 shadow-sm">
 | 
			
		||||
        <div className="flex items-center gap-3">
 | 
			
		||||
          <div className="w-10 h-10 bg-blue-500 rounded-full flex items-center justify-center">
 | 
			
		||||
            <Bot className="w-6 h-6 text-white" />
 | 
			
		||||
          </div>
 | 
			
		||||
          <div>
 | 
			
		||||
            <h1 className="text-xl font-semibold text-gray-900">AI 助手</h1>
 | 
			
		||||
            <p className="text-sm text-gray-500">在线 · 随时为您服务</p>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      {/* 对话列表区域 */}
 | 
			
		||||
      <div className="flex-1 overflow-y-auto p-4 space-y-4">
 | 
			
		||||
        {messages.map((message) => (
 | 
			
		||||
          <div
 | 
			
		||||
            key={message.id}
 | 
			
		||||
            className={`flex gap-3 ${
 | 
			
		||||
              message.role === 'user' ? 'justify-end' : 'justify-start'
 | 
			
		||||
            }`}
 | 
			
		||||
          >
 | 
			
		||||
            {message.role === 'assistant' && (
 | 
			
		||||
              <div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center flex-shrink-0">
 | 
			
		||||
                <Bot className="w-5 h-5 text-white" />
 | 
			
		||||
              </div>
 | 
			
		||||
            )}
 | 
			
		||||
            
 | 
			
		||||
            <div
 | 
			
		||||
              className={`max-w-[70%] rounded-lg px-4 py-2 ${
 | 
			
		||||
                message.role === 'user'
 | 
			
		||||
                  ? 'bg-blue-500 text-white'
 | 
			
		||||
                  : 'bg-white text-gray-900 shadow-sm border border-gray-200'
 | 
			
		||||
              }`}
 | 
			
		||||
            >
 | 
			
		||||
              <div className="text-sm leading-relaxed whitespace-pre-wrap">
 | 
			
		||||
                {message.content}
 | 
			
		||||
              </div>
 | 
			
		||||
              <div
 | 
			
		||||
                className={`text-xs mt-1 ${
 | 
			
		||||
                  message.role === 'user' ? 'text-blue-100' : 'text-gray-500'
 | 
			
		||||
                }`}
 | 
			
		||||
              >
 | 
			
		||||
                {formatTime(message.timestamp)}
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            {message.role === 'user' && (
 | 
			
		||||
              <div className="w-8 h-8 bg-gray-600 rounded-full flex items-center justify-center flex-shrink-0">
 | 
			
		||||
                <User className="w-5 h-5 text-white" />
 | 
			
		||||
              </div>
 | 
			
		||||
            )}
 | 
			
		||||
          </div>
 | 
			
		||||
        ))}
 | 
			
		||||
 | 
			
		||||
        {/* 加载状态 */}
 | 
			
		||||
        {isLoading && (
 | 
			
		||||
          <div className="flex gap-3 justify-start">
 | 
			
		||||
            <div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center flex-shrink-0">
 | 
			
		||||
              <Bot className="w-5 h-5 text-white" />
 | 
			
		||||
            </div>
 | 
			
		||||
            <div className="bg-white rounded-lg px-4 py-2 shadow-sm border border-gray-200">
 | 
			
		||||
              <div className="flex space-x-1">
 | 
			
		||||
                <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div>
 | 
			
		||||
                <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.1s' }}></div>
 | 
			
		||||
                <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.2s' }}></div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        )}
 | 
			
		||||
 | 
			
		||||
        <div ref={messagesEndRef} />
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      {/* 输入框区域 */}
 | 
			
		||||
      <div className="bg-white border-t border-gray-200 p-4">
 | 
			
		||||
        <div className="flex gap-3 items-end">
 | 
			
		||||
          <div className="flex-1 relative">
 | 
			
		||||
            <textarea
 | 
			
		||||
              ref={inputRef}
 | 
			
		||||
              value={inputValue}
 | 
			
		||||
              onChange={(e) => setInputValue(e.target.value)}
 | 
			
		||||
              onKeyDown={handleKeyDown}
 | 
			
		||||
              placeholder="输入您的消息... (按 Enter 发送,Shift+Enter 换行)"
 | 
			
		||||
              className="w-full px-4 py-3 border border-gray-300 rounded-lg resize-none focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
 | 
			
		||||
              rows={1}
 | 
			
		||||
              style={{ minHeight: '96px', maxHeight: '180px' }}
 | 
			
		||||
              disabled={isLoading}
 | 
			
		||||
            />
 | 
			
		||||
          </div>
 | 
			
		||||
          <button
 | 
			
		||||
            onClick={handleSend}
 | 
			
		||||
            disabled={!inputValue.trim() || isLoading}
 | 
			
		||||
            className={`p-3 rounded-lg flex items-center justify-center transition-colors ${
 | 
			
		||||
              !inputValue.trim() || isLoading
 | 
			
		||||
                ? 'bg-gray-300 cursor-not-allowed'
 | 
			
		||||
                : 'bg-blue-500 hover:bg-blue-600 text-white'
 | 
			
		||||
            }`}
 | 
			
		||||
          >
 | 
			
		||||
            <Send className="w-5 h-5" />
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
        {/* 提示文本 */}
 | 
			
		||||
        <div className="mt-2 text-xs text-gray-500 text-center">
 | 
			
		||||
          AI助手会根据您的输入生成回复,请文明使用
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user