AI助手edit icon

作者:
ZGR
Fork(复制)
下载
嵌入
BUG反馈
index.html
现在支持上传本地图片了!
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>免费AI助手</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        :root {
            --primary-color: #6c5ce7;
            --secondary-color: #a29bfe;
            --light-color: #f7f9ff;
            --dark-color: #1a1c2c;
            --user-bubble: #6c5ce7;
            --ai-bubble: #f0f4ff;
            --success-color: #00cec9;
            --error-color: #ff7675;
        }
        
        body {
            background: linear-gradient(135deg, #74b9ff, #6c5ce7);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
            color: var(--dark-color);
        }
        
        .container {
            width: 100%;
            max-width: 900px;
            background: rgba(255, 255, 255, 0.97);
            border-radius: 20px;
            box-shadow: 0 15px 50px rgba(0, 0, 0, 0.2);
            overflow: hidden;
            display: flex;
            flex-direction: column;
            height: 90vh;
        }
        
        .header {
            background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
            color: white;
            padding: 20px;
            text-align: center;
            position: relative;
        }
        
        .header h1 {
            font-size: 1.8rem;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 10px;
            animation: pulse 2s infinite;
        }
        
        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }
        
        .header p {
            margin-top: 8px;
            opacity: 0.9;
            font-size: 0.9rem;
        }
        
        .features {
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
            gap: 15px;
            margin-top: 15px;
        }
        
        .feature {
            background: rgba(255, 255, 255, 0.2);
            padding: 8px 15px;
            border-radius: 30px;
            font-size: 0.85rem;
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .chat-container {
            flex: 1;
            overflow-y: auto;
            padding: 25px;
            display: flex;
            flex-direction: column;
            gap: 20px;
            background: var(--light-color);
        }
        
        .message {
            display: flex;
            gap: 15px;
            max-width: 85%;
            animation: fadeIn 0.3s ease;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }
        
        .user-message {
            align-self: flex-end;
            flex-direction: row-reverse;
        }
        
        .avatar {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-shrink: 0;
            font-weight: bold;
        }
        
        .user-avatar {
            background: var(--user-bubble);
            color: white;
            box-shadow: 0 4px 8px rgba(108, 92, 231, 0.3);
        }
        
        .ai-avatar {
            background: var(--primary-color);
            color: white;
            box-shadow: 0 4px 8px rgba(108, 92, 231, 0.3);
        }
        
        .message-content {
            padding: 15px 20px;
            border-radius: 18px;
            line-height: 1.5;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
            position: relative;
        }
        
        .user-message .message-content {
            background: var(--user-bubble);
            color: white;
            border-bottom-right-radius: 5px;
        }
        
        .ai-message .message-content {
            background: var(--ai-bubble);
            border-bottom-left-radius: 5px;
        }
        
        .ai-message .message-content pre {
            background: #282c34;
            color: #abb2bf;
            padding: 15px;
            border-radius: 8px;
            overflow-x: auto;
            margin-top: 10px;
        }
        
        .input-container {
            padding: 20px;
            background: white;
            border-top: 1px solid #eee;
            display: flex;
            gap: 15px;
            position: relative;
        }
        
        .message-input {
            flex: 1;
            padding: 15px 20px;
            border-radius: 30px;
            border: 2px solid #e0e0e0;
            outline: none;
            font-size: 1rem;
            transition: border-color 0.3s;
            padding-right: 50px;
        }
        
        .message-input:focus {
            border-color: var(--primary-color);
        }
        
        .send-btn {
            background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
            color: white;
            border: none;
            width: 50px;
            height: 50px;
            border-radius: 50%;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: transform 0.3s, opacity 0.3s;
            position: absolute;
            right: 25px;
            bottom: 25px;
            box-shadow: 0 4px 10px rgba(108, 92, 231, 0.4);
        }
        
        .send-btn:hover {
            transform: scale(1.05);
        }
        
        .send-btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
        }
        
        .typing-indicator {
            display: flex;
            align-items: center;
            gap: 5px;
            padding: 15px 20px;
            background: var(--ai-bubble);
            border-radius: 18px;
            width: fit-content;
            margin-top: 10px;
            opacity: 0;
            transition: opacity 0.3s;
        }
        
        .typing-indicator.show {
            opacity: 1;
        }
        
        .dot {
            width: 8px;
            height: 8px;
            background: var(--primary-color);
            border-radius: 50%;
            animation: bounce 1.5s infinite;
        }
        
        .dot:nth-child(2) {
            animation-delay: 0.2s;
        }
        
        .dot:nth-child(3) {
            animation-delay: 0.4s;
        }
        
        @keyframes bounce {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-5px); }
        }
        
        .info-box {
            background: #e3f2fd;
            border-left: 4px solid var(--primary-color);
            padding: 15px;
            border-radius: 0 8px 8px 0;
            margin-top: 10px;
            font-size: 0.9rem;
        }
        
        .info-box ul {
            padding-left: 20px;
            margin-top: 10px;
        }
        
        .info-box li {
            margin-bottom: 8px;
            line-height: 1.6;
        }
        
        .code-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: #1e1e1e;
            padding: 8px 15px;
            border-radius: 8px 8px 0 0;
            color: #9cdcfe;
            font-size: 0.9rem;
        }
        
        .copy-btn {
            background: #3a3a3a;
            color: white;
            border: none;
            padding: 5px 10px;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .copy-btn:hover {
            background: var(--primary-color);
        }
        
        .model-selector {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin-top: 15px;
            flex-wrap: wrap;
        }
        
        .model-btn {
            background: rgba(255, 255, 255, 0.2);
            border: none;
            color: white;
            padding: 8px 15px;
            border-radius: 30px;
            cursor: pointer;
            transition: all 0.3s;
            font-size: 0.9rem;
        }
        
        .model-btn.active {
            background: white;
            color: var(--primary-color);
            font-weight: bold;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        }
        
        .model-btn:hover:not(.active) {
            background: rgba(255, 255, 255, 0.3);
        }
        
        @media (max-width: 768px) {
            .container {
                height: 95vh;
            }
            
            .message {
                max-width: 95%;
            }
            
            .header h1 {
                font-size: 1.5rem;
            }
            
            .features {
                gap: 8px;
            }
            
            .feature {
                padding: 6px 12px;
                font-size: 0.8rem;
            }
        }
        
        .notification {
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: var(--success-color);
            color: white;
            padding: 12px 25px;
            border-radius: 30px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
            z-index: 1000;
            opacity: 0;
            transition: opacity 0.3s;
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        .notification.show {
            opacity: 1;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1><i class="fas fa-robot"></i> 免费AI助手</h1>
            <p>无需API密钥,直接使用多个免费AI服务</p>
            
            <div class="model-selector">
                <button class="model-btn active" data-model="huggingface">HuggingFace</button>
                <button class="model-btn" data-model="deepseek">DeepSeek</button>
                <button class="model-btn" data-model="cohere">Cohere</button>
            </div>
            
            <div class="features">
                <div class="feature"><i class="fas fa-code"></i> 代码生成</div>
                <div class="feature"><i class="fas fa-question-circle"></i> 问题解答</div>
                <div class="feature"><i class="fas fa-comment"></i> 自然对话</div>
                <div class="feature"><i class="fas fa-lightbulb"></i> 创意写作</div>
                <div class="feature"><i class="fas fa-graduation-cap"></i> 学习辅助</div>
            </div>
        </div>
        
        <div class="chat-container" id="chatContainer">
            <div class="message ai-message">
                <div class="avatar ai-avatar">
                    <i class="fas fa-robot"></i>
                </div>
                <div class="message-content">
                    <p>您好!我是您的免费AI助手。请问有什么可以帮您的?</p>
                    <div class="info-box">
                        <strong>使用说明:</strong>
                        <ul>
                            <li>在下方输入框输入问题或请求</li>
                            <li>我可以帮助解答问题、编写代码、解释概念等</li>
                            <li>支持多种AI模型,点击顶部按钮切换</li>
                            <li>示例问题:<br>
                                "用JavaScript实现快速排序"<br>
                                "解释一下CSS Flex布局"<br>
                                "如何用Python读取CSV文件?"
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="typing-indicator" id="typingIndicator">
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
        </div>
        
        <div class="input-container">
            <input type="text" class="message-input" id="messageInput" placeholder="输入您的问题或请求...">
            <button class="send-btn" id="sendBtn">
                <i class="fas fa-paper-plane"></i>
            </button>
        </div>
    </div>

    <div class="notification" id="notification">
        <i class="fas fa-check-circle"></i>
        <span>代码已复制到剪贴板!</span>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
    <script>
        // 页面加载完成后执行
        document.addEventListener('DOMContentLoaded', function() {
            const chatContainer = document.getElementById('chatContainer');
            const messageInput = document.getElementById('messageInput');
            const sendBtn = document.getElementById('sendBtn');
            const typingIndicator = document.getElementById('typingIndicator');
            const notification = document.getElementById('notification');
            const modelButtons = document.querySelectorAll('.model-btn');
            
            let currentModel = 'huggingface';
            
            // 设置当前模型
            modelButtons.forEach(button => {
                button.addEventListener('click', function() {
                    modelButtons.forEach(btn => btn.classList.remove('active'));
                    this.classList.add('active');
                    currentModel = this.dataset.model;
                    
                    // 添加系统消息
                    addMessage(`已切换到 ${getModelName(currentModel)} 模型`, 'ai');
                });
            });
            
            // 获取模型名称
            function getModelName(model) {
                const models = {
                    'huggingface': 'HuggingFace',
                    'deepseek': 'DeepSeek',
                    'cohere': 'Cohere'
                };
                return models[model] || '未知模型';
            }
            
            // 发送消息
            function sendMessage() {
                const message = messageInput.value.trim();
                if (!message) return;
                
                // 添加用户消息到聊天框
                addMessage(message, 'user');
                
                // 清空输入框
                messageInput.value = '';
                
                // 显示"正在输入"指示器
                typingIndicator.classList.add('show');
                
                // 调用AI API(模拟)
                simulateAIResponse(message);
            }
            
            // 添加消息到聊天框
            function addMessage(content, sender) {
                const messageDiv = document.createElement('div');
                messageDiv.className = `message ${sender}-message`;
                
                const avatarDiv = document.createElement('div');
                avatarDiv.className = `avatar ${sender}-avatar`;
                avatarDiv.innerHTML = sender === 'user' ? '<i class="fas fa-user"></i>' : '<i class="fas fa-robot"></i>';
                
                const contentDiv = document.createElement('div');
                contentDiv.className = 'message-content';
                
                // 检查内容是否包含代码块
                const hasCode = content.includes('```');
                if (hasCode) {
                    // 处理代码块
                    const parts = content.split('```');
                    let htmlContent = '';
                    
                    for (let i = 0; i < parts.length; i++) {
                        if (i % 2 === 0) {
                            // 普通文本
                            htmlContent += `<p>${formatText(parts[i])}</p>`;
                        } else {
                            // 代码块
                            const codeParts = parts[i].split('\n');
                            const language = codeParts[0].trim() || 'javascript';
                            const code = codeParts.slice(1).join('\n').trim();
                            
                            htmlContent += `
                                <div class="code-block">
                                    <div class="code-header">
                                        <span>${language}</span>
                                        <button class="copy-btn"><i class="fas fa-copy"></i> 复制</button>
                                    </div>
                                    <pre><code class="language-${language}">${escapeHtml(code)}</code></pre>
                                </div>
                            `;
                        }
                    }
                    
                    contentDiv.innerHTML = htmlContent;
                } else {
                    // 没有代码块
                    contentDiv.innerHTML = `<p>${formatText(content)}</p>`;
                }
                
                messageDiv.appendChild(avatarDiv);
                messageDiv.appendChild(contentDiv);
                chatContainer.appendChild(messageDiv);
                
                // 高亮代码块
                if (hasCode) {
                    document.querySelectorAll('pre code').forEach((block) => {
                        hljs.highlightElement(block);
                        
                        // 添加复制按钮功能
                        const copyBtn = block.parentElement.previousElementSibling.querySelector('.copy-btn');
                        if (copyBtn) {
                            copyBtn.addEventListener('click', function() {
                                const codeText = block.innerText;
                                navigator.clipboard.writeText(codeText).then(() => {
                                    showNotification('代码已复制到剪贴板!');
                                });
                            });
                        }
                    });
                }
                
                // 滚动到底部
                chatContainer.scrollTop = chatContainer.scrollHeight;
            }
            
            // 显示通知
            function showNotification(message) {
                notification.querySelector('span').textContent = message;
                notification.classList.add('show');
                setTimeout(() => {
                    notification.classList.remove('show');
                }, 3000);
            }
            
            // 格式化文本(将换行符转换为<br>)
            function formatText(text) {
                return text.replace(/\n/g, '<br>');
            }
            
            // 转义HTML特殊字符
            function escapeHtml(unsafe) {
                return unsafe
                    .replace(/&/g, "&amp;")
                    .replace(/</g, "&lt;")
                    .replace(/>/g, "&gt;")
                    .replace(/"/g, "&quot;")
                    .replace(/'/g, "&#039;");
            }
            
            // 模拟AI响应
            function simulateAIResponse(message) {
                // 模拟延迟
                setTimeout(() => {
                    // 隐藏"正在输入"指示器
                    typingIndicator.classList.remove('show');
                    
                    // 根据用户问题生成模拟响应
                    let response = '';
                    
                    if (message.toLowerCase().includes('hello') || message.toLowerCase().includes('你好')) {
                        response = "你好!我是AI助手,有什么我可以帮助您的吗?";
                    } else if (message.toLowerCase().includes('javascript') && message.toLowerCase().includes('排序')) {
                        response = `当然,这是一个用JavaScript实现的快速排序算法:
                        
\`\`\`javascript
function quickSort(arr) {
  if (arr.length <= 1) return arr;
  
  const pivot = arr[0];
  const left = [];
  const right = [];
  
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  
  return [...quickSort(left), pivot, ...quickSort(right)];
}

// 示例用法
const unsortedArray = [3, 6, 8, 10, 1, 2, 1];
const sortedArray = quickSort(unsortedArray);
console.log(sortedArray); // 输出: [1, 1, 2, 3, 6, 8, 10]
\`\`\`
这个实现使用了递归和分治策略,时间复杂度为O(n log n)。`;
                    } else if (message.toLowerCase().includes('python') && message.toLowerCase().includes('csv')) {
                        response = `在Python中读取CSV文件可以使用内置的csv模块。以下是一个示例:
                        
\`\`\`python
import csv

# 读取CSV文件
with open('data.csv', 'r', newline='', encoding='utf-8') as file:
    reader = csv.reader(file)
    header = next(reader)  # 读取标题行
    data = [row for row in reader]

# 打印数据
print("标题:", header)
for i, row in enumerate(data, 1):
    print(f"行 {i}: {row}")
\`\`\`

对于更复杂的数据处理,也可以使用pandas库:
\`\`\`python
import pandas as pd

# 读取CSV文件
df = pd.read_csv('data.csv')

# 显示前5行
print(df.head())
\`\`\``;
                    } else if (message.toLowerCase().includes('flex')) {
                        response = `CSS Flex布局是一种一维布局模型,用于在容器中对项目进行排列和分配空间。以下是关键概念:
                        
1. **Flex容器**:通过设置 \`display: flex;\` 的元素
2. **Flex项目**:Flex容器中的直接子元素
3. **主轴**:项目排列的主要方向(由 \`flex-direction\` 设置)
4. **交叉轴**:垂直于主轴的轴

常用容器属性:
- \`flex-direction\`: 设置主轴方向 (row, row-reverse, column, column-reverse)
- \`justify-content\`: 主轴对齐方式 (flex-start, center, flex-end, space-between, space-around)
- \`align-items\`: 交叉轴对齐方式 (stretch, flex-start, center, flex-end, baseline)
- \`flex-wrap\`: 是否换行 (nowrap, wrap, wrap-reverse)

示例:
\`\`\`css
.container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  gap: 10px;
}

.item {
  flex: 1; /* 项目均匀分配空间 */
}
\`\`\``;
                    } else {
                        // 通用响应
                        response = `感谢您的查询!基于您的问题:"${message}",我可以提供以下信息:
                        
在${getModelName(currentModel)}模型下,我理解您需要帮助解决这个问题。虽然这是一个模拟响应,但在真实环境中,我会通过以下步骤帮助您:

1. 分析您的问题关键词:${extractKeywords(message)}
2. 搜索相关知识库
3. 生成结构化的回答
4. 提供代码示例(如需要)

如果您需要更具体的帮助,请尝试包含更多细节,例如:
- 您使用的编程语言
- 相关技术栈
- 期望的输出结果
- 您已经尝试过的解决方案

例如:"如何用JavaScript实现一个倒计时组件?"`;
                    }
                    
                    addMessage(response, 'ai');
                }, 1500);
            }
            
            // 提取关键词(简化版)
            function extractKeywords(message) {
                const words = message.split(' ');
                return words.slice(0, 5).join(', ');
            }
            
            // 发送按钮点击事件
            sendBtn.addEventListener('click', sendMessage);
            
            // 输入框回车事件
            messageInput.addEventListener('keypress', function(e) {
                if (e.key === 'Enter') {
                    sendMessage();
                }
            });
        });
    </script>
</body>
</html>
        
编辑器加载中
预览
控制台