AI对话网站示例

简易的ai对话网站示例,使用gpt-4o-mini模型
需要连接vpn使用
展示图片:
在这里插入图片描述

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ChatGPT 中文界面</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
      display: flex;
      flex-direction: column;
      height: 100vh;
    }
    #chat-container {
      flex-grow: 1;
      padding: 20px;
      overflow-y: auto;
      background-color: #f5f5f5;
    }
    #chat-container .message {
      margin-bottom: 15px;
    }
    #chat-container .message.user {
      text-align: right;
    }
    #chat-container .message.user span {
      background-color: #0078d7;
      color: white;
      padding: 8px 12px;
      border-radius: 15px;
      display: inline-block;
    }
    #chat-container .message.assistant {
      position: relative;
    }
    #chat-container .message.assistant .markdown-content {
      background-color: #e0e0e0;
      color: black;
      padding: 8px 12px;
      border-radius: 15px;
      white-space: pre-wrap;
      overflow-x: auto;
    }
    #chat-container .message.assistant .copy-btn {
      position: absolute;
      top: 5px;
      right: 5px;
      background: #0078d7;
      color: white;
      border: none;
      padding: 5px 10px;
      border-radius: 3px;
      cursor: pointer;
    }
    #chat-container .message.assistant .copy-btn:hover {
      background: #005bb5;
    }
    #input-container {
      display: flex;
      padding: 10px;
      background-color: #ffffff;
      border-top: 1px solid #ddd;
    }
    #input-container input {
      flex-grow: 1;
      padding: 10px;
      font-size: 16px;
      border: 1px solid #ddd;
      border-radius: 5px;
    }
    #input-container button {
      margin-left: 10px;
      padding: 10px 20px;
      font-size: 16px;
      background-color: #0078d7;
      color: white;
      border: none;
      border-radius: 5px;
      cursor: pointer;
    }
    #input-container button:hover {
      background-color: #005bb5;
    }
    #context-toggle {
      position: absolute;
      top: 10px;
      right: 10px;
      background-color: #0078d7;
      color: white;
      border: none;
      padding: 10px;
      border-radius: 5px;
      cursor: pointer;
    }
    #context-toggle.active {
      background-color: #005bb5;
    }
    .loading {
      font-style: italic;
      color: #666;
      margin-top: 10px;
      animation: blink 1.2s infinite;
    }
    @keyframes blink {
      0% { opacity: 1; }
      50% { opacity: 0.5; }
      100% { opacity: 1; }
    }
  </style>
</head>
<body>
  <button id="context-toggle">联系上下文:关闭</button>
  <div id="chat-container"></div>
  <div id="input-container">
    <input type="text" id="user-input" placeholder="请输入您的问题..." />
    <button onclick="sendMessage()">发送</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
  <script>
    const apiKey = '你的openai api密钥填写在此';
    const chatContainer = document.getElementById('chat-container');
    const userInput = document.getElementById('user-input');
    const contextToggle = document.getElementById('context-toggle');
    let contextEnabled = false; // 是否启用上下文
    let messages = []; // 保存上下文的消息数组

    // 切换上下文功能
    contextToggle.addEventListener('click', () => {
      contextEnabled = !contextEnabled;
      contextToggle.textContent = `联系上下文:${contextEnabled ? '开启' : '关闭'}`;
      contextToggle.classList.toggle('active', contextEnabled);
      if (!contextEnabled) messages = []; // 如果关闭上下文,清空历史记录
    });

    async function sendMessage() {
      const userMessage = userInput.value.trim();
      if (!userMessage) return;

      // 显示用户消息
      addMessage(userMessage, 'user');
      userInput.value = '';

      // 保存用户消息到上下文
      if (contextEnabled) messages.push({ role: 'user', content: userMessage });

      // 显示加载动画
      const loadingMessage = document.createElement('div');
      loadingMessage.className = 'loading';
      loadingMessage.textContent = 'AI 正在思考中...';
      chatContainer.appendChild(loadingMessage);
      chatContainer.scrollTop = chatContainer.scrollHeight;

      try {
        // 调用 OpenAI API
        const response = await fetch('https://api.openai.com/v1/chat/completions', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${apiKey}`,
          },
          body: JSON.stringify({
            model: 'gpt-4o-mini',
            messages: contextEnabled ? messages : [{ role: 'user', content: userMessage }],
          }),
        });

        if (response.ok) {
          const data = await response.json();
          const reply = data.choices[0].message.content;
          loadingMessage.remove(); // 移除加载动画
          addAnimatedMessage(reply, 'assistant');
          if (contextEnabled) messages.push({ role: 'assistant', content: reply }); // 保存AI回复到上下文
        } else {
          const error = await response.json();
          loadingMessage.textContent = `错误:${error.error.message}`;
        }
      } catch (error) {
        loadingMessage.textContent = '错误:无法连接到服务器。';
      }
    }

    function addMessage(text, sender) {
      const messageDiv = document.createElement('div');
      messageDiv.className = `message ${sender}`;

      if (sender === 'assistant') {
        const markdownContent = document.createElement('div');
        markdownContent.className = 'markdown-content';
        markdownContent.innerHTML = marked.parse(text);

        const copyButton = document.createElement('button');
        copyButton.className = 'copy-btn';
        copyButton.textContent = '复制';
        copyButton.onclick = () => copyToClipboard(text);

        messageDiv.appendChild(copyButton);
        messageDiv.appendChild(markdownContent);
      } else {
        const messageContent = document.createElement('span');
        messageContent.textContent = text;
        messageDiv.appendChild(messageContent);
      }

      chatContainer.appendChild(messageDiv);
      chatContainer.scrollTop = chatContainer.scrollHeight;
    }

    function addAnimatedMessage(text, sender) {
      const messageDiv = document.createElement('div');
      messageDiv.className = `message ${sender}`;
      const markdownContent = document.createElement('div');
      markdownContent.className = 'markdown-content';
      messageDiv.appendChild(markdownContent);

      chatContainer.appendChild(messageDiv);
      chatContainer.scrollTop = chatContainer.scrollHeight;

      let index = 0;
      function typeWriter() {
        if (index < text.length) {
          markdownContent.innerHTML += text[index];
          index++;
          setTimeout(typeWriter, 30); // 控制逐字输出速度
        } else {
          markdownContent.innerHTML = marked.parse(text); // 最后格式化 Markdown
        }
      }
      typeWriter();
    }

    function copyToClipboard(text) {
      navigator.clipboard.writeText(text).then(() => {
        alert('内容已复制到剪贴板!');
      }).catch(err => {
        alert('复制失败:' + err);
      });
    }
  </script>
</body>
</html>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值