高级编程助手聊天界面

发布于 2025-04-25 浏览 126 人次

一个复杂的聊天界面布局,包含您要求的所有功能。这个实现将使用现代CSS技术(CSS变量、Flexbox、Grid)和JavaScript交互,同时保持代码结构清晰可维护。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>高级编程助手聊天界面</title>
    <style>
        :root {
            /* 默认主题变量 - 紫色 */
            --primary-color: #8a2be2;
            --primary-light: #b57eed;
            --primary-dark: #6a1b9a;
            --bg-color: #f9f5ff;
            --text-color: #333;
            --text-light: #666;
            --text-on-primary: #fff;
            --card-bg: #fff;
            --border-radius: 10px;
            --shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
            --transition: all 0.3s ease;
        }

        /* 暗色主题 */
        [data-theme="dark"] {
            --bg-color: #1a1a2e;
            --text-color: #e6e6e6;
            --text-light: #b3b3b3;
            --card-bg: #16213e;
            --shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
        }

        /* 圆角预设 */
        [data-radius="none"] {
            --border-radius: 0px;
        }
        [data-radius="medium"] {
            --border-radius: 10px;
        }
        [data-radius="full"] {
            --border-radius: 100px;
        }

        /* 预设颜色主题 */
        .theme-blue {
            --primary-color: #3f51b5;
            --primary-light: #757de8;
            --primary-dark: #002984;
        }
        .theme-yellow {
            --primary-color: #ffc107;
            --primary-light: #ffd54f;
            --primary-dark: #c79100;
            --text-on-primary: #333;
        }
        .theme-green {
            --primary-color: #4caf50;
            --primary-light: #81c784;
            --primary-dark: #087f23;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--bg-color);
            color: var(--text-color);
            transition: var(--transition);
            line-height: 1.6;
            height: 100vh;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        /* 导航栏 */
        .navbar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 1rem 2rem;
            background-color: var(--primary-color);
            color: var(--text-on-primary);
            box-shadow: var(--shadow);
            z-index: 100;
            position: relative;
            transition: var(--transition);
        }

        .logo {
            font-weight: bold;
            font-size: 1.5rem;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }

        .logo-icon {
            width: 24px;
            height: 24px;
            background-color: var(--text-on-primary);
            border-radius: 50%;
            display: inline-block;
        }

        .nav-controls {
            display: flex;
            gap: 1rem;
            align-items: center;
        }

        .toggle-btn {
            background: none;
            border: none;
            color: var(--text-on-primary);
            cursor: pointer;
            font-size: 1.2rem;
            padding: 0.5rem;
            border-radius: var(--border-radius);
            transition: var(--transition);
        }

        .toggle-btn:hover {
            background-color: rgba(255, 255, 255, 0.2);
        }

        /* 主内容区 */
        .main-container {
            display: flex;
            flex: 1;
            overflow: hidden;
        }

        /* 左侧边栏 */
        .sidebar {
            width: 280px;
            background-color: var(--card-bg);
            border-right: 1px solid rgba(0, 0, 0, 0.1);
            padding: 1.5rem;
            overflow-y: auto;
            transition: var(--transition);
            transform: translateX(0);
            z-index: 10;
            box-shadow: var(--shadow);
        }

        .sidebar-section {
            margin-bottom: 2rem;
        }

        .sidebar-title {
            font-size: 1rem;
            font-weight: bold;
            margin-bottom: 1rem;
            color: var(--primary-color);
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }

        .theme-options {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 0.5rem;
            margin-bottom: 1rem;
        }

        .theme-option {
            width: 100%;
            height: 40px;
            border-radius: var(--border-radius);
            cursor: pointer;
            border: 2px solid transparent;
            transition: var(--transition);
        }

        .theme-option:hover {
            transform: translateY(-2px);
            box-shadow: var(--shadow);
        }

        .theme-option.active {
            border-color: var(--text-color);
        }

        .theme-option.purple {
            background-color: #8a2be2;
        }

        .theme-option.blue {
            background-color: #3f51b5;
        }

        .theme-option.yellow {
            background-color: #ffc107;
        }

        .theme-option.green {
            background-color: #4caf50;
        }

        .radius-options {
            display: flex;
            gap: 0.5rem;
            margin-bottom: 1rem;
        }

        .radius-btn {
            flex: 1;
            padding: 0.5rem;
            border: none;
            background-color: var(--card-bg);
            border: 1px solid var(--primary-light);
            border-radius: 4px;
            cursor: pointer;
            transition: var(--transition);
        }

        .radius-btn:hover {
            background-color: var(--primary-light);
            color: var(--text-on-primary);
        }

        .radius-btn.active {
            background-color: var(--primary-color);
            color: var(--text-on-primary);
        }

        .custom-color {
            width: 100%;
            margin-bottom: 1rem;
        }

        .color-picker {
            width: 100%;
            height: 40px;
            border: none;
            cursor: pointer;
            background: transparent;
        }

        /* 聊天区域 */
        .chat-container {
            flex: 1;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            position: relative;
        }

        .chat-area {
            flex: 1;
            overflow-y: auto;
            padding: 1.5rem;
            scroll-behavior: smooth;
        }

        .message {
            display: flex;
            margin-bottom: 1.5rem;
            animation: fadeIn 0.3s ease-out;
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(10px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .message-avatar {
            width: 36px;
            height: 36px;
            border-radius: 50%;
            background-color: var(--primary-light);
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 1rem;
            flex-shrink: 0;
            color: var(--text-on-primary);
            font-weight: bold;
        }

        .message-content {
            max-width: 80%;
        }

        .message-bubble {
            padding: 0.8rem 1.2rem;
            border-radius: var(--border-radius);
            background-color: var(--card-bg);
            box-shadow: var(--shadow);
            position: relative;
            transition: var(--transition);
        }

        .user .message-bubble {
            background-color: var(--primary-color);
            color: var(--text-on-primary);
            border-top-right-radius: 0;
        }

        .assistant .message-bubble {
            border-top-left-radius: 0;
        }

        .message-time {
            font-size: 0.75rem;
            color: var(--text-light);
            margin-top: 0.5rem;
            display: block;
        }

        .user {
            justify-content: flex-end;
        }

        .user .message-content {
            display: flex;
            flex-direction: column;
            align-items: flex-end;
        }

        /* 代码预览区域 */
        .code-preview {
            width: 350px;
            background-color: var(--card-bg);
            border-left: 1px solid rgba(0, 0, 0, 0.1);
            padding: 1rem;
            overflow-y: auto;
            transition: var(--transition);
            transform: translateX(0);
            box-shadow: var(--shadow);
        }

        .code-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 1rem;
        }

        .code-title {
            font-weight: bold;
            color: var(--primary-color);
        }

        .close-code {
            background: none;
            border: none;
            color: var(--text-light);
            cursor: pointer;
            font-size: 1.2rem;
            transition: var(--transition);
        }

        .close-code:hover {
            color: var(--primary-color);
        }

        pre {
            background-color: #282c34;
            color: #abb2bf;
            padding: 1rem;
            border-radius: var(--border-radius);
            overflow-x: auto;
            font-family: 'Courier New', Courier, monospace;
            font-size: 0.9rem;
            line-height: 1.5;
        }

        /* 输入区域 */
        .input-container {
            padding: 1rem;
            background-color: var(--card-bg);
            border-top: 1px solid rgba(0, 0, 0, 0.1);
            box-shadow: var(--shadow);
            z-index: 10;
        }

        .input-area {
            display: flex;
            gap: 0.5rem;
        }

        .message-input {
            flex: 1;
            padding: 0.8rem 1.2rem;
            border: 1px solid var(--primary-light);
            border-radius: var(--border-radius);
            font-family: inherit;
            font-size: 1rem;
            resize: none;
            background-color: var(--card-bg);
            color: var(--text-color);
            transition: var(--transition);
            max-height: 150px;
        }

        .message-input:focus {
            outline: none;
            border-color: var(--primary-color);
            box-shadow: 0 0 0 2px rgba(138, 43, 226, 0.2);
        }

        .send-btn {
            padding: 0 1.2rem;
            background-color: var(--primary-color);
            color: var(--text-on-primary);
            border: none;
            border-radius: var(--border-radius);
            cursor: pointer;
            font-weight: bold;
            transition: var(--transition);
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .send-btn:hover {
            background-color: var(--primary-dark);
            transform: translateY(-2px);
        }

        .send-btn:active {
            transform: translateY(0);
        }

        .send-icon {
            font-size: 1.2rem;
        }

        /* 功能按钮 */
        .function-buttons {
            display: flex;
            gap: 0.5rem;
            margin-top: 0.5rem;
            flex-wrap: wrap;
        }

        .func-btn {
            padding: 0.5rem 1rem;
            background-color: var(--card-bg);
            border: 1px solid var(--primary-light);
            border-radius: var(--border-radius);
            cursor: pointer;
            font-size: 0.8rem;
            transition: var(--transition);
            display: flex;
            align-items: center;
            gap: 0.3rem;
        }

        .func-btn:hover {
            background-color: var(--primary-light);
            color: var(--text-on-primary);
        }

        .func-btn.active {
            background-color: var(--primary-color);
            color: var(--text-on-primary);
            border-color: var(--primary-color);
        }

        /* 移动端适配 */
        @media (max-width: 992px) {
            .sidebar {
                position: absolute;
                left: 0;
                top: 0;
                bottom: 0;
                transform: translateX(-100%);
            }

            .sidebar.active {
                transform: translateX(0);
            }

            .code-preview {
                position: absolute;
                right: 0;
                top: 0;
                bottom: 0;
                transform: translateX(100%);
            }

            .code-preview.active {
                transform: translateX(0);
            }
        }

        @media (max-width: 768px) {
            .navbar {
                padding: 1rem;
            }

            .logo {
                font-size: 1.2rem;
            }

            .message-content {
                max-width: 90%;
            }

            .code-preview {
                width: 100%;
            }
        }

        /* 工具类 */
        .hidden {
            display: none !important;
        }

        /* 加载动画 */
        .typing-indicator {
            display: flex;
            padding: 1rem;
            gap: 0.5rem;
        }

        .typing-dot {
            width: 8px;
            height: 8px;
            background-color: var(--primary-light);
            border-radius: 50%;
            animation: typingAnimation 1.4s infinite ease-in-out;
        }

        .typing-dot:nth-child(1) {
            animation-delay: 0s;
        }

        .typing-dot:nth-child(2) {
            animation-delay: 0.2s;
        }

        .typing-dot:nth-child(3) {
            animation-delay: 0.4s;
        }

        @keyframes typingAnimation {
            0%, 60%, 100% {
                transform: translateY(0);
            }
            30% {
                transform: translateY(-5px);
            }
        }
    </style>
</head>
<body>
    <!-- 导航栏 -->
    <nav class="navbar">
        <div class="logo">
            <span class="logo-icon"></span>
            <span>编程助手</span>
        </div>
        <div class="nav-controls">
            <button class="toggle-btn" id="toggleSidebar">☰</>
            <button class="toggle-btn" id="toggleTheme🌓</button>
            <button class="toggle-btn" id="toggleCodePanel">💻</button>
        </div>
    </nav>

    <!-- 主容器 -->
    <div class="main-container">
        <!-- 左侧边栏 -->
        <aside class="sidebar" id="sidebar">
            <div class="sidebar-section">
                <h3 class="sidebar-title">🎨 主题设置</h3>
                <div class="theme-options">
                    <div class="theme-option purple active" data-theme-class="default"></div>
                    <div class="theme-option blue" data-theme-class="theme-blue"></div>
                    <div class="theme-option yellow" data-theme-class="theme-yellow"></div>
                    <div class="theme-option green" data-theme-class="theme-green"></div>
                </div>
                <input type="color" class="custom-color" id="customColor" value="#8a2be2">
            </div>

            <div class="sidebar-section">
                <h3 class="sidebar-title">🔵 圆角设置</h3>
                <div class="radius-options">
                    <button class="radius-btn" data-radius="none">直角</button>
                    <button class="radius-btn active" data-radius="medium">中等</button>
                    <button class="radius-btn" data-radius="full">圆形</button>
                </div>
            </div>

            <div class="sidebar-section">
                <h3 class="sidebar-title">⚙️ 其他设置</h3>
                <div class="function-buttons">
                    <button class="func-btn" data-func="clear">清空聊天</button>
                    <button class="func-btn" data-func="export">导出记录</button>
                </div>
            </div>
        </aside>

        <!-- 聊天区域 -->
        <main class="chat-container">
            <div class="chat-area" id="chatArea">
                <!-- 消息将通过JavaScript动态添加 -->
            </div>

            <!-- 输入区域 -->
            <div class="input-container">
                <div class="input-area">
                    <textarea class="message-input" id="messageInput" placeholder="输入您的消息..." rows="1"></textarea>
                    <button class="send-btn" id="sendBtn">
                        <span class="send-icon">✉️</span>
                    </button>
                </div>
                <div class="function-buttons">
                    <button class="func-btn" data-type="html">HTML</button>
                    <button class="func-btn" data-type="css">CSS</button>
                    <button class="func-btn" data-type="javascript">JavaScript</button>
                    <button class="func-btn" data-type="python">Python</button>
                </div>
            </div>
        </main>

        <!-- 代码预览区域 -->
        <aside class="code-preview" id="codePreview">
            <div class="code-header">
                <h3 class="code-title">代码预览</h3>
                <button class="close-code" id="closeCode">×</button>
            </div>
            <pre id="codeContent"><code>// 您的代码将在这里显示</code></pre>
        </aside>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // DOM元素
            const chatArea = document.getElementById('chatArea');
            const messageInput = document.getElementById('messageInput');
            const sendBtn = document.getElementById('sendBtn');
            const toggleSidebar = document.getElementById('toggleSidebar');
            const sidebar = document.getElementById('sidebar');
            const toggleTheme = document.getElementById('toggleTheme');
            const toggleCodePanel = document.getElementById('toggleCodePanel');
            const codePreview = document.getElementById('codePreview');
            const closeCode = document.getElementById('closeCode');
            const codeContent = document.getElementById('codeContent');
            
            // 主题控制
            const themeOptions = document.querySelectorAll('.theme-option');
            const radiusButtons = document.querySelectorAll('.radius-btn');
            const customColor = document.getElementById('customColor');
            
            // 功能按钮
            const funcButtons = document.querySelectorAll('.func-btn[data-type]');
            const actionButtons = document.querySelectorAll('.func-btn[data-func]');
            
            // 当前状态
            let currentTheme = 'default';
            let currentRadius = 'medium';
            let darkMode = false;
            let codePanelVisible = false;
            let sidebarVisible = false;
            let selectedCodeType = null;
            
            // 初始化
            init();
            
            function init() {
                // 从本地存储加载设置
                loadSettings();
                
                // 设置事件监听器
                setupEventListeners();
                
                // 添加欢迎消息
                addWelcomeMessage();
                
                // 自动调整输入框高度
                autoResizeTextarea();
            }
            
            function loadSettings() {
                // 从本地存储加载主题设置
                if (localStorage.getItem('darkMode') === 'true') {
                    toggleDarkMode();
                }
                
                if (localStorage.getItem('currentTheme')) {
                    currentTheme = localStorage.getItem('currentTheme');
                    document.documentElement.classList.add(currentTheme);
                    
                    // 更新活动主题按钮
                    themeOptions.forEach(option => {
                        if (option.dataset.themeClass === currentTheme) {
                            option.classList.add('active');
                        } else {
                            option.classList.remove('active');
                        }
                    });
                }
                
                if (localStorage.getItem('currentRadius')) {
                    currentRadius = localStorage.getItem('currentRadius');
                    document.documentElement.setAttribute('data-radius', currentRadius);
                    
                    // 更新活动圆角按钮
                    radiusButtons.forEach(btn => {
                        if (btn.dataset.radius === currentRadius) {
                            btn.classList.add('active');
                        } else {
                            btn.classList.remove('active');
                        }
                    });
                }
                
                if (localStorage.getItem('sidebarVisible') === 'true') {
                    toggleSidebarVisibility();
                }
                
                if (localStorage.getItem('codePanelVisible') === 'true') {
                    toggleCodePanelVisibility();
                }
            }
            
            function saveSettings() {
                localStorage.setItem('darkMode', darkMode);
                localStorage.setItem('currentTheme', currentTheme);
                localStorage.setItem('currentRadius', currentRadius);
                localStorage.setItem('sidebarVisible', sidebarVisible);
                localStorage.setItem('codePanelVisible', codePanelVisible);
            }
            
            function setupEventListeners() {
                // 发送消息
                sendBtn.addEventListener('click', sendMessage);
                messageInput.addEventListener('keydown', function(e) {
                    if (e.key === 'Enter' && !e.shiftKey) {
                        e.preventDefault();
                        sendMessage();
                    }
                });
                
                // 切换侧边栏
                toggleSidebar.addEventListener('click', toggleSidebarVisibility);
                
                // 切换主题
                toggleTheme.addEventListener('click', toggleDarkMode);
                
                // 切换代码面板
                toggleCodePanel.addEventListener('click', toggleCodePanelVisibility);
                closeCode.addEventListener('click', toggleCodePanelVisibility);
                
                // 主题选项
                themeOptions.forEach(option => {
                    option.addEventListener('click', function() {
                        // 移除当前主题类
                        document.documentElement.classList.remove(currentTheme);
                        
                        // 设置新主题
                        currentTheme = this.dataset.themeClass;
                        document.documentElement.classList.add(currentTheme);
                        
                        // 更新活动按钮
                        themeOptions.forEach(opt => opt.classList.remove('active'));
                        this.classList.add('active');
                        
                        // 保存设置
                        saveSettings();
                    });
                });
                
                // 自定义颜色
                customColor.addEventListener('input', function() {
                    document.documentElement.style.setProperty('--primary-color', this.value);
                    document.documentElement.style.setProperty('--primary-light', lightenColor(this.value, 20));
                    document.documentElement.style.setProperty('--primary-dark', darkenColor(this.value, 20));
                    
                    // 移除预设主题类
                    document.documentElement.classList.remove(currentTheme);
                    currentTheme = 'custom';
                    
                    // 更新主题按钮状态
                    themeOptions.forEach(opt => opt.classList.remove('active'));
                    
                    // 保存设置
                    saveSettings();
                });
                
                // 圆角选项
                radiusButtons.forEach(btn => {
                    btn.addEventListener('click', function() {
                        currentRadius = this.dataset.radius;
                        document.documentElement.setAttribute('data-radius', currentRadius);
                        
                        // 更新活动按钮
                        radiusButtons.forEach(b => b.classList.remove('active'));
                        this.classList.add('active');
                        
                        // 保存设置
                        saveSettings();
                    });
                });
                
                // 代码类型选择
                funcButtons.forEach(btn => {
                    btn.addEventListener('click', function() {
                        selectedCodeType = this.dataset.type;
                        
                        // 更新活动按钮
                        funcButtons.forEach(b => b.classList.remove('active'));
                        this.classList.add('active');
                    });
                });
                
                // 功能按钮
                actionButtons.forEach(btn => {
                    btn.addEventListener('click', function() {
                        const action = this.dataset.func;
                        
                        if (action === 'clear') {
                            clearChat();
                        } else if (action === 'export') {
                            exportChat();
                        }
                    });
                });
            }
            
            function toggleSidebarVisibility() {
                sidebarVisible = !sidebarVisible;
                sidebar.classList.toggle('active', sidebarVisible);
                saveSettings();
            }
            
            function toggleCodePanelVisibility() {
                codePanelVisible = !codePanelVisible;
                codePreview.classList.toggle('active', codePanelVisible);
                saveSettings();
            }
            
            function toggleDarkMode() {
                darkMode = !darkMode;
                document.documentElement.setAttribute('data-theme', darkMode ? 'dark' : 'light');
                saveSettings();
            }
            
            function addWelcomeMessage() {
                const welcomeMessage = `
                    <div class="message assistant">
                        <div class="message-avatar">AI</div>
                        <div class="message-content">
                            <div class="message-bubble">
                                您好!我是您的编程助手。我可以帮助您解决编程问题、解释概念、调试代码等。
                                <br><br>
                                您可以通过左侧面板自定义界面外观,包括主题颜色、圆角大小等。
                                <br><br>
                                有什么我可以帮助您的吗?
                                <div class="message-time">${formatTime(new Date())}</div>
                            </div>
                        </div>
                    </div>
                `;
                
                chatArea.insertAdjacentHTML('beforeend', welcomeMessage);
                scrollToBottom();
            }
            
            function sendMessage() {
                const message = messageInput.value.trim();
                if (!message) return;
                
                // 添加用户消息
                addMessage(message, 'user');
                messageInput.value = '';
                autoResizeTextarea();
                
                // 显示AI正在输入
                showTypingIndicator();
                
                // 模拟AI回复(实际应用中这里应该是API调用)
                setTimeout(() => {
                    removeTypingIndicator();
                    
                    // 根据消息类型生成回复
                    let reply = generateReply(message);
                    
                    // 添加AI回复
                    addMessage(reply.text, 'assistant');
                    
                    // 如果有代码,更新代码预览
                    if (reply.code) {
                        updateCodePreview(reply.code, reply.language || 'javascript');
                    }
                }, 1000 + Math.random() * 2000); // 随机延迟模拟思考时间
            }
            
            function addMessage(text, sender) {
                const messageHTML = `
                    <div class="message ${sender}">
                        <div class="message-avatar">${sender === 'user' ? '你' : 'AI'}</div>
                        <div class="message-content">
                            <div class="message-bubble">
                                ${text}
                                <div class="message-time">${formatTime(new Date())}</div>
                            </div>
                        </div>
                    </div>
                `;
                
                chatArea.insertAdjacentHTML('beforeend', messageHTML);
                scrollToBottom();
            }
            
            function showTypingIndicator() {
                const typingHTML = `
                    <div class="message assistant" id="typingIndicator">
                        <div class="message-avatar">AI</div>
                        <div class="message-content">
                            <div class="message-bubble">
                                <div class="typing-indicator">
                                    <div class="typing-dot"></div>
                                    <div class="typing-dot"></div>
                                    <div class="typing-dot"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                `;
                
                chatArea.insertAdjacentHTML('beforeend', typingHTML);
                scrollToBottom();
            }
            
            function removeTypingIndicator() {
                const indicator = document.getElementById('typingIndicator');
                if (indicator) {
                    indicator.remove();
                }
            }
            
            function updateCodePreview(code, language) {
                if (!codePanelVisible) {
                    toggleCodePanelVisibility();
                }
                
                // 简单的语法高亮(实际应用中可以使用highlight.js等库)
                let highlightedCode = code;
                
                // 更新代码内容和语言标识
                codeContent.textContent = highlightedCode;
                codeContent.className = language;
                
                // 添加运行按钮(如果是HTML/CSS/JS)
                if (language === 'html') {
                    const runButton = document.createElement('button');
                    runButton.textContent = '运行代码';
                    runButton.className = 'func-btn';
                    runButton.style.marginTop = '1rem';
                    runButton.addEventListener('click', function() {
                        const newWindow = window.open('', '_blank');
                        newWindow.document.write(code);
                        newWindow.document.close();
                    });
                    
                    // 确保只添加一个运行按钮
                    const existingButton = codePreview.querySelector('.run-code-btn');
                    if (existingButton) existingButton.remove();
                    
                    runButton.classList.add('run-code-btn');
                    codePreview.appendChild(runButton);
                }
            }
            
            function clearChat() {
                chatArea.innerHTML = '';
                addWelcomeMessage();
            }
            
            function exportChat() {
                const messages = chatArea.querySelectorAll('.message-bubble');
                let exportText = '';
                
                messages.forEach(message => {
                    const sender = message.closest('.message').classList.contains('user') ? '你' : 'AI';
                    const content = message.textContent.trim();
                    const time = message.querySelector('.message-time').textContent;
                    
                    exportText += `[${time}] ${sender}: ${content}\n\n`;
                });
                
                const blob = new Blob([exportText], { type: 'text/plain' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = `编程助手聊天记录_${formatDate(new Date())}.txt`;
                a.click();
                URL.revokeObjectURL(url);
            }
            
            function generateReply(message) {
                // 这是一个简化的回复生成器
                // 实际应用中应该调用API获取真实回复
                
                const lowerMessage = message.toLowerCase();
                
                if (lowerMessage.includes('你好') || lowerMessage.includes('hi') || lowerMessage.includes('hello')) {
                    return {
                        text: '你好!有什么编程问题我可以帮助您解决吗?',
                        code: null
                    };
                }
                
                if (lowerMessage.includes('html') || selectedCodeType === 'html') {
                    return {
                        text: '这是一个简单的HTML示例代码:',
                        code: '<!DOCTYPE html>\n<html>\n<head>\n    <title>示例页面</title>\n</head>\n<body>\n    <h1>欢迎来到我的网站</h1>\n    <p>这是一个段落。</p>\n</body>\n</html>',
                        language: 'html'
                    };
                }
                
                if (lowerMessage.includes('css') || selectedCodeType === 'css') {
                    return {
                        text: '这是一个CSS示例代码:',
                        code: 'body {\n    font-family: Arial, sans-serif;\n    margin: 0;\n    padding: 20px;\n    background-color: #f5f5f5;\n}\n\nh1 {\n    color: #333;\n    text-align: center;\n}\n\n.container {\n    max-width: 800px;\n    margin: 0 auto;\n    background: white;\n    padding: 20px;\n    border-radius: 5px;\n    box-shadow: 0 2px 5px rgba(0,0,0,0.1);\n}',
                        language: 'css'
                    };
                }
                
                if (lowerMessage.includes('javascript') || lowerMessage.includes('js') || selectedCodeType === 'javascript') {
                    return {
                        text: '这是一个JavaScript示例代码:',
                        code: '// 简单的数组操作\nconst numbers = [1, 2, 3, 4, 5];\n\n// 使用map方法创建新数组\nconst doubled = numbers.map(num => num * 2);\nconsole.log(doubled); // [2, 4, 6, 8, 10]\n\n// 使用filter方法筛选数组\nconst evens = numbers.filter(num => num % 2 === 0);\nconsole.log(evens); // [2, 4]\n\n// 使用reduce方法计算总和\nconst sum = numbers.reduce((total, num) => total + num, 0);\nconsole.log(sum); // 15',
                        language: 'javascript'
                    };
                }
                
                if (lowerMessage.includes('python') || selectedCodeType === 'python') {
                    return {
                        text: '这是一个Python示例代码:',
                        code: '# 简单的Python函数示例\ndef greet(name):\n    """向用户打招呼"""\n    return f"Hello, {name}!"\n\n# 使用列表推导式\nnumbers = [1, 2, 3, 4, 5]\nsquares = [x**2 for x in numbers]\nprint(squares)  # [1, 4, 9, 16, 25]\n\n# 调用函数\nprint(greet("Alice"))  # Hello, Alice!',
                        language: 'python'
                    };
                }
                
                // 默认回复
                return {
                    text: '我理解您的问题是关于编程的。如果您能提供更多细节,我可以给出更具体的帮助。\n\n例如,您可以询问特定编程语言的问题,或者描述您遇到的错误。',
                    code: null
                };
            }
            
            // 辅助函数
            function scrollToBottom() {
                chatArea.scrollTop = chatArea.scrollHeight;
            }
            
            function formatTime(date) {
                return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
            }
            
            function formatDate(date) {
                return date.toISOString().split('T')[0].replace(/-/g, '');
            }
            
            function lightenColor(color, percent) {
                // 简化版的颜色变亮函数
                return color; // 实际应用中应该实现完整的颜色处理逻辑
            }
            
            function darkenColor(color, percent) {
                // 简化版的颜色变暗函数
                return color; // 实际应用中应该实现完整的颜色处理逻辑
            }
            
            function autoResizeTextarea() {
                messageInput.style.height = 'auto';
                messageInput.style.height = (messageInput.scrollHeight) + 'px';
            }
            
            // 监听输入框内容变化
            messageInput.addEventListener('input', autoResizeTextarea);
        });
    </script>
</body>
</html>

功能说明

  1. 布局结构

    • 左侧边栏:主题设置、圆角控制、功能按钮
    • 中间聊天区:消息显示区域
    • 右侧代码预览区:可查看和运行代码(默认隐藏)
  2. 主题系统

    • 4种预设主题(紫色、蓝色、黄色、绿色)
    • 自定义颜色选择器
    • 亮/暗模式切换
    • 3种圆角预设(直角、中等、圆形)
  3. 交互功能

    • 消息发送和显示(区分用户/AI消息)
    • 代码类型选择(HTML/CSS/JS/Python)
    • 聊天记录导出
    • 清空聊天记录
    • 代码运行功能(HTML代码)
  4. 响应式设计

    • 移动端适配(侧边栏和代码面板变为滑动抽屉)
    • 不同屏幕尺寸的布局调整
  5. 动画效果

    • 消息加载动画
    • 按钮悬停效果
    • 主题切换过渡
    • AI输入指示器
  6. 本地存储

    • 保存用户偏好设置(主题、圆角、面板状态)

这个实现使用了现代CSS技术(CSS变量、Flexbox、Grid)和纯JavaScript,没有依赖任何外部库,保持了代码的独立性和可维护性。