mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-17 22:03:39 +00:00
feat: 全局格式化代码
This commit is contained in:
@@ -18,7 +18,7 @@ body {
|
||||
.container {
|
||||
background: white;
|
||||
border-radius: 15px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
||||
width: 90%;
|
||||
max-width: 1200px;
|
||||
height: 80vh;
|
||||
@@ -89,7 +89,7 @@ body {
|
||||
.message > div {
|
||||
max-width: 70%;
|
||||
padding: 12px 16px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.message-role {
|
||||
@@ -263,7 +263,7 @@ body {
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 12px;
|
||||
margin: 15px 0;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
@@ -447,18 +447,32 @@ body {
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0%, 50% { opacity: 1; }
|
||||
51%, 100% { opacity: 0.5; }
|
||||
0%, 50% {
|
||||
opacity: 1;
|
||||
}
|
||||
51%, 100% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(-10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
|
||||
@@ -12,7 +12,7 @@ const loading = document.getElementById('loading');
|
||||
const status = document.getElementById('status');
|
||||
|
||||
// 全局错误处理
|
||||
window.addEventListener('error', function(event) {
|
||||
window.addEventListener('error', function (event) {
|
||||
console.error('Global JavaScript error:', event.error);
|
||||
if (event.error && event.error.message && event.error.message.includes('userMessage')) {
|
||||
console.error('Detected userMessage error, this might be a variable scope issue');
|
||||
@@ -40,7 +40,7 @@ async function sendMessage() {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ message: message })
|
||||
body: JSON.stringify({message: message})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
@@ -104,7 +104,7 @@ function quickAction(message) {
|
||||
// 清除历史
|
||||
async function clearHistory() {
|
||||
try {
|
||||
await fetch('/api/chat/clear', { method: 'POST' });
|
||||
await fetch('/api/chat/clear', {method: 'POST'});
|
||||
messagesContainer.innerHTML = '';
|
||||
showStatus('History cleared', 'success');
|
||||
} catch (error) {
|
||||
@@ -232,61 +232,61 @@ function handleStreamResponse(userMessage) {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ message: userMessage })
|
||||
body: JSON.stringify({message: userMessage})
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
function readStream() {
|
||||
return reader.read().then(({ done, value }) => {
|
||||
if (done) {
|
||||
console.log('✅ 流式响应完成');
|
||||
streamIndicator.style.display = 'none';
|
||||
streamContainer.classList.remove('streaming');
|
||||
showStatus('流式对话完成', 'success');
|
||||
return;
|
||||
}
|
||||
|
||||
const chunk = decoder.decode(value, { stream: true });
|
||||
console.log('📨 收到流式数据块:', chunk);
|
||||
|
||||
// 处理SSE格式的数据
|
||||
const lines = chunk.split('\n');
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data: ')) {
|
||||
const data = line.substring(6);
|
||||
if (data === '[DONE]') {
|
||||
console.log('✅ 流式响应完成');
|
||||
streamIndicator.style.display = 'none';
|
||||
streamContainer.classList.remove('streaming');
|
||||
showStatus('流式对话完成', 'success');
|
||||
return;
|
||||
}
|
||||
|
||||
// 追加内容
|
||||
fullContent += data;
|
||||
streamContent.textContent = fullContent;
|
||||
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
||||
function readStream() {
|
||||
return reader.read().then(({done, value}) => {
|
||||
if (done) {
|
||||
console.log('✅ 流式响应完成');
|
||||
streamIndicator.style.display = 'none';
|
||||
streamContainer.classList.remove('streaming');
|
||||
showStatus('流式对话完成', 'success');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return readStream();
|
||||
});
|
||||
}
|
||||
const chunk = decoder.decode(value, {stream: true});
|
||||
console.log('📨 收到流式数据块:', chunk);
|
||||
|
||||
return readStream();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('❌ 流式响应错误:', error);
|
||||
const errorMessage = error && error.message ? error.message : 'Unknown stream error';
|
||||
streamIndicator.innerHTML = '<span class="error">连接错误: ' + errorMessage + '</span>';
|
||||
showStatus('流式对话连接错误: ' + errorMessage, 'error');
|
||||
});
|
||||
// 处理SSE格式的数据
|
||||
const lines = chunk.split('\n');
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data: ')) {
|
||||
const data = line.substring(6);
|
||||
if (data === '[DONE]') {
|
||||
console.log('✅ 流式响应完成');
|
||||
streamIndicator.style.display = 'none';
|
||||
streamContainer.classList.remove('streaming');
|
||||
showStatus('流式对话完成', 'success');
|
||||
return;
|
||||
}
|
||||
|
||||
// 追加内容
|
||||
fullContent += data;
|
||||
streamContent.textContent = fullContent;
|
||||
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
return readStream();
|
||||
});
|
||||
}
|
||||
|
||||
return readStream();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('❌ 流式响应错误:', error);
|
||||
const errorMessage = error && error.message ? error.message : 'Unknown stream error';
|
||||
streamIndicator.innerHTML = '<span class="error">连接错误: ' + errorMessage + '</span>';
|
||||
showStatus('流式对话连接错误: ' + errorMessage, 'error');
|
||||
});
|
||||
}
|
||||
|
||||
// 移除等待状态卡片
|
||||
@@ -298,7 +298,7 @@ function removeWaitingToolCard() {
|
||||
}
|
||||
|
||||
// 事件监听器
|
||||
messageInput.addEventListener('keypress', function(e) {
|
||||
messageInput.addEventListener('keypress', function (e) {
|
||||
if (e.key === 'Enter' && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
sendMessage();
|
||||
@@ -320,7 +320,7 @@ function debugVariables() {
|
||||
}
|
||||
|
||||
// 页面加载完成后聚焦输入框
|
||||
window.addEventListener('load', function() {
|
||||
window.addEventListener('load', function () {
|
||||
messageInput.focus();
|
||||
|
||||
// 确保函数在全局作用域中可用
|
||||
|
||||
@@ -47,7 +47,7 @@ class ToolLogDisplay {
|
||||
addToolStart(logEvent) {
|
||||
// 移除等待状态卡片(如果存在)
|
||||
removeWaitingToolCard();
|
||||
|
||||
|
||||
const toolCard = this.createToolCard(logEvent);
|
||||
const content = this.container.querySelector('.tool-log-content');
|
||||
content.appendChild(toolCard);
|
||||
|
||||
@@ -2,108 +2,115 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<title>SpringAI Alibaba Copilot</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<link href="/css/main.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>🤖 SpringAI Alibaba 编码助手</h1>
|
||||
<p>AI助手将分析您的需求,制定执行计划,并逐步完成任务</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>🤖 SpringAI Alibaba 编码助手</h1>
|
||||
<p>AI助手将分析您的需求,制定执行计划,并逐步完成任务</p>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="chat-area">
|
||||
<div class="messages" id="messages">
|
||||
<div class="message assistant">
|
||||
<div>
|
||||
<div class="message-role">Assistant</div>
|
||||
<div class="message-content">
|
||||
👋 Hello! I'm your AI file operations assistant. I can help you:
|
||||
<br><br>
|
||||
📁 <strong>Read files</strong> - View file contents with pagination support
|
||||
<br>✏️ <strong>Write files</strong> - Create new files or overwrite existing ones
|
||||
<br>🔧 <strong>Edit files</strong> - Make precise edits with diff preview
|
||||
<br>📋 <strong>List directories</strong> - Browse directory structure
|
||||
<br><br>
|
||||
Try asking me to create a simple project, read a file, or explore the workspace!
|
||||
<br><br>
|
||||
<em>Workspace: /workspace</em>
|
||||
</div>
|
||||
<div class="main-content">
|
||||
<div class="chat-area">
|
||||
<div class="messages" id="messages">
|
||||
<div class="message assistant">
|
||||
<div>
|
||||
<div class="message-role">Assistant</div>
|
||||
<div class="message-content">
|
||||
👋 Hello! I'm your AI file operations assistant. I can help you:
|
||||
<br><br>
|
||||
📁 <strong>Read files</strong> - View file contents with pagination support
|
||||
<br>✏️ <strong>Write files</strong> - Create new files or overwrite existing ones
|
||||
<br>🔧 <strong>Edit files</strong> - Make precise edits with diff preview
|
||||
<br>📋 <strong>List directories</strong> - Browse directory structure
|
||||
<br><br>
|
||||
Try asking me to create a simple project, read a file, or explore the workspace!
|
||||
<br><br>
|
||||
<em>Workspace: /workspace</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="loading" id="loading">
|
||||
<div>🤔 AI is thinking...</div>
|
||||
<div class="loading" id="loading">
|
||||
<div>🤔 AI is thinking...</div>
|
||||
</div>
|
||||
|
||||
<div class="input-area">
|
||||
<input id="messageInput" placeholder="Ask me to create files, read content, or manage your project..."
|
||||
type="text"/>
|
||||
<button id="sendBtn" onclick="sendMessage()">Send</button>
|
||||
<button class="clear-btn" id="clearBtn" onclick="clearHistory()">Clear</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar">
|
||||
<h3>🚀 Quick Actions</h3>
|
||||
<div class="quick-actions">
|
||||
<div class="quick-action" onclick="quickAction('List the workspace directory')">
|
||||
📁 List workspace directory
|
||||
</div>
|
||||
|
||||
<div class="input-area">
|
||||
<input type="text" id="messageInput" placeholder="Ask me to create files, read content, or manage your project..." />
|
||||
<button onclick="sendMessage()" id="sendBtn">Send</button>
|
||||
<button onclick="clearHistory()" class="clear-btn" id="clearBtn">Clear</button>
|
||||
<div class="quick-action" onclick="quickAction('Create a simple Java Hello World project')">
|
||||
☕ Create Java Hello World
|
||||
</div>
|
||||
<div class="quick-action" onclick="quickAction('Create a simple web project with HTML, CSS and JS')">
|
||||
🌐 Create web project
|
||||
</div>
|
||||
<div class="quick-action" onclick="quickAction('Create a README.md file for this project')">
|
||||
📝 Create README.md
|
||||
</div>
|
||||
<div class="quick-action"
|
||||
onclick="quickAction('Show me the structure of the current directory recursively')">
|
||||
🌳 Show directory tree
|
||||
</div>
|
||||
<div class="quick-action"
|
||||
onclick="quickAction('Create a simple Python script that prints hello world')">
|
||||
🐍 Create Python script
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar">
|
||||
<h3>🚀 Quick Actions</h3>
|
||||
<div class="quick-actions">
|
||||
<div class="quick-action" onclick="quickAction('List the workspace directory')">
|
||||
📁 List workspace directory
|
||||
</div>
|
||||
<div class="quick-action" onclick="quickAction('Create a simple Java Hello World project')">
|
||||
☕ Create Java Hello World
|
||||
</div>
|
||||
<div class="quick-action" onclick="quickAction('Create a simple web project with HTML, CSS and JS')">
|
||||
🌐 Create web project
|
||||
</div>
|
||||
<div class="quick-action" onclick="quickAction('Create a README.md file for this project')">
|
||||
📝 Create README.md
|
||||
</div>
|
||||
<div class="quick-action" onclick="quickAction('Show me the structure of the current directory recursively')">
|
||||
🌳 Show directory tree
|
||||
</div>
|
||||
<div class="quick-action" onclick="quickAction('Create a simple Python script that prints hello world')">
|
||||
🐍 Create Python script
|
||||
</div>
|
||||
<h3>🔄 Continuous Task Tests</h3>
|
||||
<div class="quick-actions">
|
||||
<div class="quick-action"
|
||||
onclick="quickAction('Create a complete React project with components, styles, and package.json')">
|
||||
⚛️ Create React project
|
||||
</div>
|
||||
|
||||
<h3>🔄 Continuous Task Tests</h3>
|
||||
<div class="quick-actions">
|
||||
<div class="quick-action" onclick="quickAction('Create a complete React project with components, styles, and package.json')">
|
||||
⚛️ Create React project
|
||||
</div>
|
||||
<div class="quick-action" onclick="quickAction('Create a full-stack todo app with HTML, CSS, JavaScript frontend and Node.js backend')">
|
||||
📋 Create Todo App
|
||||
</div>
|
||||
<div class="quick-action" onclick="quickAction('Create a Spring Boot REST API project with controller, service, and model classes')">
|
||||
🍃 Create Spring Boot API
|
||||
</div>
|
||||
<div class="quick-action" onclick="quickAction('Create a complete blog website with multiple HTML pages, CSS styles, and JavaScript functionality')">
|
||||
📰 Create Blog Website
|
||||
</div>
|
||||
<div class="quick-action"
|
||||
onclick="quickAction('Create a full-stack todo app with HTML, CSS, JavaScript frontend and Node.js backend')">
|
||||
📋 Create Todo App
|
||||
</div>
|
||||
<div class="quick-action"
|
||||
onclick="quickAction('Create a Spring Boot REST API project with controller, service, and model classes')">
|
||||
🍃 Create Spring Boot API
|
||||
</div>
|
||||
<div class="quick-action"
|
||||
onclick="quickAction('Create a complete blog website with multiple HTML pages, CSS styles, and JavaScript functionality')">
|
||||
📰 Create Blog Website
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="status" class="status" style="display: none;"></div>
|
||||
<div class="status" id="status" style="display: none;"></div>
|
||||
|
||||
<div style="margin-top: 30px;">
|
||||
<h3>💡 Tips</h3>
|
||||
<div style="font-size: 12px; color: #666; line-height: 1.4;">
|
||||
• Ask for step-by-step project creation<br>
|
||||
• Request file content before editing<br>
|
||||
• Use specific file paths<br>
|
||||
• Ask for directory structure first<br>
|
||||
• Try continuous operations
|
||||
</div>
|
||||
<div style="margin-top: 30px;">
|
||||
<h3>💡 Tips</h3>
|
||||
<div style="font-size: 12px; color: #666; line-height: 1.4;">
|
||||
• Ask for step-by-step project creation<br>
|
||||
• Request file content before editing<br>
|
||||
• Use specific file paths<br>
|
||||
• Ask for directory structure first<br>
|
||||
• Try continuous operations
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JavaScript文件引用 -->
|
||||
<script src="/js/tool-log-display.js"></script>
|
||||
<script src="/js/sse-manager.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
<!-- JavaScript文件引用 -->
|
||||
<script src="/js/tool-log-display.js"></script>
|
||||
<script src="/js/sse-manager.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user