feat: 全局格式化代码

This commit is contained in:
evo
2025-12-06 14:38:41 +08:00
parent 96c53390aa
commit 7c7d5838cd
538 changed files with 21132 additions and 14160 deletions

View File

@@ -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);
}
}
/* 响应式设计 */

View File

@@ -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();
// 确保函数在全局作用域中可用

View File

@@ -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);

View File

@@ -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>