平时在CRM后台管理信息的时候,需要用AI写一此内容,每次跳转到DEEPSEEK官方去操作,有些麻烦,能不能直接集成到后台里操作呢,答案是可以的。而且集成之后不用担心数据的泄露和丢失,这样半私有化的开发,可以很方便的集成到后台对接各项数据,效率提升不少。
输入问题,提交之后稍等个十几二十秒,具体看网络和时段,忙时时间较久因为太多人调用,闲时和网络顺畅时会比较快。
如果觉得不好,再重新生成,觉得好想保存下来,直接在下方点击添加到文章保存,NICE,方便后面查询,简直不要太好用。
主要几个功能点:
一、前端主要界面
duihua.html包含所有功能集合在一起
<!--//模拟对话开始--> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>FLYING CRM AI助手</title> <style> @media (min-width: 920px) { /*PC*/ .waikuang{width:100%;border:0px solid red;height:auto;overflow:hidden;margin:0px auto;display:flex;} .zuo{min-width:500px;min-height:490px;float:left;height:auto;border:0px solid green;} .you{width:auto;min-width:1130px;max-width:1340px;position:absolute;right:25px;height:515px;border:0px solid blue;} } @media (max-width: 915px) { /*MOBILE*/ .waikuang{width:100%;border:1px solid red;height:5000px;margin:0px auto;} .zuo{min-width:98%;min-height:160px;float:left;height:auto;border:1px solid green;} .you{width:100%;float:right;max-width:1340px;height:400px;border:1px solid blue;} } :root { --primary-color: #0f172a; --secondary-color: #1e40af; --accent-color: #3b82f6; /*--bg-gradient: linear-gradient(135deg, #1a202c 0%, #2d3748 50%);*/ --bg-gradient: linear-gradient( 135deg, #1a202c 0%, #2d3748 50%, #4a5568 70% ); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell; } body { background: var(--bg-gradient); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; overflow: hidden; } .chat-container { width: 100%; max-width: 800px; height: 90vh; display: flex; flex-direction: column; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(12px); border-radius: 24px; overflow: hidden; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2); } .chat-header { background: var(--primary-color); padding: 1.5rem; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .header-title { color: white; font-size: 1.5rem; font-weight: 600; letter-spacing: 0.5px; } .chat-messages { flex: 1; padding: 2rem; overflow-y: auto; display: flex; flex-direction: column; gap: 1.2rem; } .message { max-width: 70%; padding: 1rem 1.5rem; border-radius: 18px; display: flex; align-items: center; gap: 1rem; position: relative; animation: slideIn 0.3s ease-out; } .user-message { background: linear-gradient(145deg, #4f46e5, #818cf8); color: white; margin-left: auto; border: 2px solid #6366f1; } .bot-response { background: linear-gradient(145deg, #e2e8f0, #edf2f7); color: #1a202c; border: 2px solid #cbd5e1; } .message-content { flex: 1; font-size: 1rem; line-height: 1.5; } .input-area { padding: 1.5rem; display: flex; gap: 1rem; background: var(--primary-color); border-top: 1px solid rgba(255, 255, 255, 0.1); } #messageInput { flex: 1; padding: 1rem 1.5rem; border: none; border-radius: 8px; background: rgba(255, 255, 255, 0.1); color: white; font-size: 1rem; transition: all 0.3s ease; } #messageInput:focus { outline: none; box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.2); } .send-btn { padding: 1rem 1.5rem; border: none; border-radius: 8px; background: var(--accent-color); color: white; cursor: pointer; transition: transform 0.2s ease; } .send-btn:hover { transform: translateY(-2px); } @keyframes slideIn { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } @media (max-width: 768px) { .chat-container { height: 80vh; border-radius: 16px; } .message { max-width: 85%; padding: 0.8rem 1.2rem; } #messageInput { padding: 0.8rem 1rem; } } </style> </head> <body> <div class="waikuang" style=""> <div class="zuo"> <form id="myForm"> <div class="chat-container"> <div class="chat-header"> <div class="header-title">DeepSeek智能助手</div> <div class="theme-toggle">🌓</div> </div> <div class="chat-messages" id="chatMessages"> <!-- 示例消息 --> <div class="message bot-response"> <div class="message-icon">🤖</div> <div class="message-content"> 你好!我是FLYING CRM AI助手,有什么可以帮助你的? </div> </div> </div> <div class="input-area"> <input type="text" id="messageInput" name="message" placeholder="输入你的问题..."> <button type="submit" class="send-btn" onclick="alert('发送成功')" >发送</button> <!--button type="submit">立即发送MOREN</button--> </div> </div> </form> <script> function sendMessage() { const input = document.getElementById('messageInput'); const message = input.value.trim(); if (message) { const chatMessages = document.getElementById('chatMessages'); const userMessage = document.createElement('div'); userMessage.className = 'message user-message'; userMessage.innerHTML = ` <div class="message-icon">👤</div> <div class="message-content">${message}</div> `; chatMessages.appendChild(userMessage); input.value = ''; // 模拟回复延迟 setTimeout(() => { const botMessage = document.createElement('div'); botMessage.className = 'message bot-response'; botMessage.innerHTML = ` <div class="message-icon">🤖</div> <div class="message-content">正在回答中...</div> `; chatMessages.appendChild(botMessage); chatMessages.scrollTop = chatMessages.scrollHeight; }, 1000);//alert("等待响应"); } } </script> </body> </html> </div> <div class="you"> <!-- 主页面 parent.html --> <style> iframe { width: 100%; border: none; transition: height 0.3s ease; /* 添加平滑过渡效果 */ height:auto; min-height:510px; } </style> <iframe id="mainFrame" src="http://60.205.189.167:9001/api/xianshiping.html"></iframe> <script> window.addEventListener('message', (event) => { // 安全校验(根据实际情况修改origin) if (event.origin !== window.location.origin) return; const iframe = document.getElementById('mainFrame'); // 添加5px缓冲空间防止滚动条 iframe.style.height = `${event.data + 5}px`; }); </script> </div> </div> <script src="http://python.lzychina.com:8000/static/xadmin/vendor/jquery/jquery.js"></script> <script> // 添加点击涟漪效果 document.querySelector('button').addEventListener('click', function(e) { const ripple = document.createElement('span'); ripple.classList.add('ripple'); // 获取点击位置 const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; this.appendChild(ripple); // 动画结束后移除元素 setTimeout(() => { ripple.remove(); }, 600); }); </script> </body> </html> <script> document.getElementById('myForm').addEventListener('submit', function(event) { event.preventDefault(); // 阻止默认提交行为 // 获取表单数据 const formData = new FormData(this); const jsonData = {}; // 转换为 JSON formData.forEach((value, key) => { jsonData[key] = value; }); // 发送 POST 请求 fetch('http://60.205.189.167:9001/api/chat/', { // 请替换为实际的API端点 method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(jsonData), }) .then(response => { if (!response.ok) { throw new Error(`HTTP错误! 状态码: ${response.status}`); } return response.json(); }) .then(data => { console.log('成功:', data); //chenggong = JSON.stringify(data, null, 2); chenggong = JSON.stringify(data); jieguo = data.reply; // 输出: John let jieguo2 = jieguo.replace(/\n/g, "<br />"); // 使用正则表达式替换所有换行符为html的换行 //打字机开始 aiResponse = jieguo2; let typingSpeed = 50; // 字符每秒 let isTyping = false; let currentText = ''; function startTyping() { if(isTyping) return; // 获取iframe元素 var iframe = document.getElementById('mainFrame'); // 通过contentWindow或contentDocument获取iframe内的文档 var iframeDocument = iframe.contentWindow.document || iframe.contentDocument; // 现在你可以在iframeDocument上使用getElementById来获取元素 var elementInIframe = iframeDocument.getElementById('output'); var elementInIframe2 = iframeDocument.getElementById('cursor'); const outputElement = elementInIframe; const cursorElement = elementInIframe2; isTyping = true; currentText = ''; outputElement.innerHTML = ''; cursorElement.style.display = 'inline-block'; // 模拟API响应延迟 setTimeout(() => { typeWriter(aiResponse, outputElement, cursorElement); }, 500); } function typeWriter(text, outputElement, cursorElement) { if(text.length === 0) { isTyping = false; cursorElement.style.display = 'none'; return; } // 逐个字符添加 const char = text.charAt(0); currentText += char; outputElement.innerHTML = currentText.replace(/\n/g, '<br>'); // 处理换行 // 递归调用实现连续输入 setTimeout(() => { typeWriter(text.substring(1), outputElement, cursorElement); }, 2000 / typingSpeed); // 自动滚动到底部 outputElement.parentElement.scrollTop = outputElement.parentElement.scrollHeight; } // 可选:自动复制功能 document.addEventListener('copy', (event) => { if(isTyping) { event.preventDefault(); alert('正在输入中,暂不支持复制'); } }); sendMessage(); startTyping(); //document.getElementById('MYcontrols').innerHTML = jieguo2; //$(".message-content").last().innerHTML = jieguo2; //打字机结束 // 可以在这里添加成功提示 //alert('表单提交成功!'); }) .catch(error => { console.error('失败:', error); // 可以在这里添加错误提示 alert(`提交失败: ${error.message}`); }); }); </script>
二、显示界面
views.py主要程序功能部分,包含DEEPSEEK的api KEY
from django.shortcuts import render # Create your views here. import requests import json from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt # 请替换成你的 DeepSeek API Key API_KEY = "sk-这里填写你申请的API KEY" API_URL = "https://api.deepseek.com/v1/chat/completions" @csrf_exempt def chat_with_deepseek(request): if request.method == "POST": try: data = json.loads(request.body) user_message = data.get("message", "") headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } payload = { "model": "deepseek-chat", "messages": [{"role": "user", "content": user_message}], "temperature": 0.7 } response = requests.post(API_URL, json=payload, headers=headers) if response.status_code == 200: reply = response.json()["choices"][0]["message"]["content"] #return JsonResponse({"reply": reply}) return JsonResponse({"reply": reply}) #return render(request, 'duihua.html', {"category_list":reply}) else: return JsonResponse({"error": response.text}, status=response.status_code) except Exception as e: return JsonResponse({"error": str(e)}, status=500) return JsonResponse({"error": "只支持POST请求"}, status=405) from django.http import HttpResponse def duihua(request): reply2 = 'Hello, world!' #response['Content-Security-Policy'] = "frame-src 'self' http://python.lzychina.com:8000/xadmin/;" #response['X-Frame-Options'] = 'SAMEORIGIN' return render(request, 'duihua.html', {"category_list":reply2}) #return response def xianshiping(request): return render(request, 'xianshiping.html') #return response
三、路由配置
urls.py配置需要显示的页面地址
from django.urls import path from .views import chat_with_deepseek from django.conf.urls import url from django.contrib import admin from chat import views as app2_views #博客分类引入 from django.conf.urls import url, include urlpatterns = [ path('chat/', chat_with_deepseek, name='chat'), url(r'^duihua', app2_views.duihua, name='duihua'), url(r'^xianshiping', app2_views.xianshiping, name='xianshiping'), ]
四、显示屏
xianshiping.html前端的静态显示页面,后台要进行调用。
<div id="MYcontrols" style="display:none;"></div> <div id="dataDisplay"></div> <div style="width:100%;margin:0px auto;"> <style> .typewriter-container { max-width: 100%; min-width:400px; min-height:430px; margin: 0 auto; padding: 2rem; background: #1a1a1a; border-radius: 10px; font-family: 'Courier New', monospace; color: #00ff00; position: relative; overflow-x: hidden; } .typewriter-text { white-space: pre-wrap; font-size: 1.1rem; line-height: 1.6; min-height: 1.5em; } .typewriter-cursor { /*display: inline-block;*/ width: 2px; height: 1.5em; background: #00ff00; animation: blink 0.7s step-end infinite; margin-left: 0.3em; } @keyframes blink { from, to { opacity: 1; } 50% { opacity: 0; } } .controls { margin-top: 1rem; text-align: center; } /* button { background: #2c3e50; color: #00ff00; border: 2px solid #00ff00; padding: 0.5rem 1.5rem; border-radius: 5px; cursor: pointer; transition: all 0.3s ease; } button:hover { background: #3498db; }*/ </style> <div class="typewriter-container"> <div class="typewriter-text" id="output"></div> <div class="typewriter-cursor" id="cursor"></div> </div> </div>
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(0)