first commit

This commit is contained in:
史悦
2025-10-24 17:44:25 +08:00
commit 18f1aba08e
9 changed files with 2972 additions and 0 deletions

806
设计/原型.html Normal file
View File

@@ -0,0 +1,806 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>产品画布 / SWOT分析</title>
<script src="https://cdn.tailwindcss.com/3.4.1"></script>
<script src="https://code.iconify.design/iconify-icon/2.1.0/iconify-icon.min.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
}
/* 狂野线条效果 */
.wild-border {
border: 3px solid;
box-shadow: 4px 4px 0px rgba(0,0,0,0.3);
}
/* 切换按钮激活状态 */
.mode-btn-active {
transform: translateY(-2px);
box-shadow: 0 4px 0 rgba(0,0,0,0.3);
}
.mode-btn-inactive {
opacity: 0.6;
}
/* 对话气泡样式 */
.chat-bubble-user {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 10px 14px;
max-width: 80%;
border: 2px solid #000;
box-shadow: 2px 2px 0 rgba(0,0,0,0.2);
}
.chat-bubble-ai {
background: #fff;
color: #1f2937;
padding: 10px 14px;
max-width: 85%;
border: 2px solid #10b981;
box-shadow: 2px 2px 0 rgba(16, 185, 129, 0.3);
}
/* SVG占位符样式 - 块级换行 + 新配色 */
.svg-placeholder-block {
display: block;
background: linear-gradient(135deg, #f59e0b 0%, #ef4444 100%);
color: white;
padding: 8px 14px;
margin: 8px 0;
border: 2px solid #000;
box-shadow: 3px 3px 0 rgba(0,0,0,0.25);
font-weight: bold;
font-size: 13px;
cursor: pointer;
transition: all 0.2s;
text-align: center;
}
.svg-placeholder-block:hover {
transform: translateX(2px) translateY(-2px);
box-shadow: 4px 4px 0 rgba(0,0,0,0.3);
background: linear-gradient(135deg, #fb923c 0%, #f87171 100%);
}
/* 气泡操作按钮 */
.bubble-action-btn {
opacity: 0;
transition: opacity 0.2s;
}
.chat-bubble-ai:hover .bubble-action-btn {
opacity: 1;
}
/* 小手摇摆动画 */
@keyframes wave {
0%, 100% {transform: translateX(0px) rotate(90deg);}
10%, 30%, 50%, 70%, 90% {transform: translateX(-1px) rotate(90deg);}
20%, 40%, 60%, 80% {transform: translateX(1px) rotate(90deg);}
}
.wave-hand {
animation: wave 3s ease-in-out infinite;
display: inline-block;
transform: rotate(90deg);
}
/* 模态窗样式 */
.modal-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.7);
z-index: 1000;
align-items: center;
justify-content: center;
}
.modal-overlay.active {
display: flex;
}
.modal-content {
background: white;
border: 4px solid #000;
box-shadow: 8px 8px 0 rgba(0,0,0,0.4);
max-width: 500px;
width: 90%;
max-height: 90vh;
overflow-y: auto;
}
/* 表单输入框样式 */
.config-input {
width: 100%;
padding: 10px;
border: 2px solid #000;
font-size: 14px;
transition: all 0.2s;
}
.config-input:focus {
outline: none;
border-color: #667eea;
box-shadow: 3px 3px 0 rgba(102, 126, 234, 0.3);
}
/* 齿轮旋转动画 */
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.settings-btn:hover iconify-icon {
animation: rotate 1s linear infinite;
}
</style>
</head>
<body class="bg-gray-100 h-screen flex flex-col">
<!-- 顶部标题栏 -->
<header class="bg-gradient-to-r from-orange-500 to-pink-500 p-3 flex items-center justify-between border-b-4 border-black">
<div class="flex items-center space-x-2">
<iconify-icon icon="ph:lightning-fill" class="text-3xl text-white"></iconify-icon>
<h1 id="page-title" class="text-2xl font-black text-white tracking-tight">产品画布</h1>
</div>
<!-- 右侧按钮组 -->
<div class="flex items-center gap-3">
<!-- API配置按钮 -->
<button id="settings-btn" class="settings-btn bg-white/20 text-white p-2 border-2 border-white hover:bg-white/30 transition-all" title="API配置">
<iconify-icon icon="ph:gear-six-fill" class="text-2xl"></iconify-icon>
</button>
<span class="text-white font-bold text-sm">点击切换模式</span>
<iconify-icon icon="ph:hand-pointing-fill" class="text-2xl text-yellow-300 wave-hand"></iconify-icon>
<button id="canvas-mode-btn" class="mode-btn-active bg-white text-orange-600 px-4 py-2 font-bold border-2 border-black hover:bg-orange-50 transition-all duration-200">
<iconify-icon icon="ph:pen-nib-duotone" class="align-middle mr-1"></iconify-icon>
产品画布
</button>
<button id="swot-mode-btn" class="mode-btn-inactive bg-white text-purple-600 px-4 py-2 font-bold border-2 border-black hover:bg-purple-50 transition-all duration-200">
<iconify-icon icon="ph:chart-bar-duotone" class="align-middle mr-1"></iconify-icon>
SWOT分析
</button>
</div>
</header>
<!-- 主内容区 -->
<main class="flex-1 grid grid-cols-1 md:grid-cols-3 gap-4 p-4 overflow-hidden">
<!-- 左侧对话面板 -->
<div class="md:col-span-1 bg-white wild-border border-cyan-500 flex flex-col">
<!-- 对话历史区 -->
<div id="chat-history" class="flex-1 p-4 overflow-y-auto space-y-3">
<!-- 用户消息 -->
<div class="flex justify-end">
<div class="chat-bubble-user">
帮我生成一个电商产品的画布
</div>
</div>
<!-- AI回复 - 包含SVG占位符换行 -->
<div class="flex justify-start">
<div class="chat-bubble-ai relative group" data-message-id="msg-1">
<div>
好的!我为您生成了一个电商产品画布,
<div class="svg-placeholder-block" data-svg-id="svg-1" onclick="viewSVG('svg-1')">
📊 点击查看产品画布 SVG
</div>
包含了目标用户、核心价值、关键功能等模块。点击上方标签可在右侧查看详细图表。
</div>
<!-- 悬浮操作按钮 -->
<div class="flex gap-2 mt-2 pt-2 border-t border-gray-200">
<button class="bubble-action-btn flex items-center gap-1 text-xs text-gray-600 hover:text-blue-600 transition-colors" onclick="rollbackToMessage('msg-1')">
<iconify-icon icon="ph:arrow-u-up-left-bold"></iconify-icon>
<span>退回</span>
</button>
<button class="bubble-action-btn flex items-center gap-1 text-xs text-gray-600 hover:text-green-600 transition-colors" onclick="regenerateMessage('msg-1')">
<iconify-icon icon="ph:arrow-clockwise-bold"></iconify-icon>
<span>重新生成</span>
</button>
</div>
</div>
</div>
<!-- 用户消息 -->
<div class="flex justify-end">
<div class="chat-bubble-user">
能不能调整一下配色方案?
</div>
</div>
<!-- AI回复 - 包含SVG占位符换行 -->
<div class="flex justify-start">
<div class="chat-bubble-ai relative group" data-message-id="msg-2">
<div>
当然可以!我已经为您调整了配色,
<div class="svg-placeholder-block" data-svg-id="svg-2" onclick="viewSVG('svg-2')">
📊 点击查看优化后的 SVG
</div>
采用了更加现代和鲜明的色彩组合,同时保持了良好的视觉层次。
</div>
<!-- 悬浮操作按钮 -->
<div class="flex gap-2 mt-2 pt-2 border-t border-gray-200">
<button class="bubble-action-btn flex items-center gap-1 text-xs text-gray-600 hover:text-blue-600 transition-colors" onclick="rollbackToMessage('msg-2')">
<iconify-icon icon="ph:arrow-u-up-left-bold"></iconify-icon>
<span>退回</span>
</button>
<button class="bubble-action-btn flex items-center gap-1 text-xs text-gray-600 hover:text-green-600 transition-colors" onclick="regenerateMessage('msg-2')">
<iconify-icon icon="ph:arrow-clockwise-bold"></iconify-icon>
<span>重新生成</span>
</button>
</div>
</div>
</div>
</div>
<!-- 输入区 -->
<div class="p-3 border-t-3 border-gray-300 bg-yellow-50">
<div class="relative flex items-center gap-2">
<input
id="chat-input"
type="text"
placeholder="输入您的想法按Enter发送..."
class="flex-1 p-2 border-2 border-gray-800 focus:border-cyan-500 focus:outline-none transition-colors font-medium"
/>
<button id="send-button" class="text-cyan-600 hover:text-cyan-700 transition-colors p-2 hover:scale-110 transform duration-200">
<iconify-icon icon="ph:paper-plane-tilt-fill" class="text-3xl"></iconify-icon>
</button>
</div>
</div>
</div>
<!-- 右侧显示面板 -->
<div class="md:col-span-2 bg-white wild-border border-purple-600 flex flex-col">
<div id="svg-viewer" class="flex-1 flex items-center justify-center p-4 bg-gradient-to-br from-purple-50 to-pink-50 overflow-auto">
<div id="svg-placeholder" class="text-center text-gray-400">
<iconify-icon icon="ph:image-square" class="text-6xl mx-auto text-purple-400"></iconify-icon>
<p class="mt-2 font-bold" id="placeholder-text">生成的产品画布将在此处显示</p>
</div>
</div>
<!-- 底部操作栏 -->
<div class="p-3 border-t-3 border-gray-300 flex justify-end items-center gap-2 bg-gray-800">
<button id="download-svg-btn" class="p-2 bg-orange-500 text-white border-2 border-black hover:bg-orange-600 transition-all" title="下载SVG">
<iconify-icon icon="mdi:download-outline" class="text-xl"></iconify-icon>
</button>
<button id="export-image-btn" class="p-2 bg-green-500 text-white border-2 border-black hover:bg-green-600 transition-all" title="导出为图片">
<iconify-icon icon="mdi:image-outline" class="text-xl"></iconify-icon>
</button>
<button id="view-code-btn" class="p-2 bg-blue-500 text-white border-2 border-black hover:bg-blue-600 transition-all" title="查看代码">
<iconify-icon icon="mdi:code-tags" class="text-xl"></iconify-icon>
</button>
</div>
</div>
</main>
<!-- API配置模态窗 -->
<div id="config-modal" class="modal-overlay">
<div class="modal-content">
<!-- 模态窗头部 -->
<div class="bg-gradient-to-r from-blue-600 to-purple-600 p-4 border-b-4 border-black flex items-center justify-between">
<div class="flex items-center gap-2">
<iconify-icon icon="ph:plugs-connected-fill" class="text-3xl text-white"></iconify-icon>
<h2 class="text-xl font-black text-white">API 配置</h2>
</div>
<button id="close-modal-btn" class="text-white hover:bg-white/20 p-2 transition-all">
<iconify-icon icon="ph:x-bold" class="text-2xl"></iconify-icon>
</button>
</div>
<!-- 模态窗内容 -->
<div class="p-6 space-y-4">
<!-- API URL -->
<div>
<label class="block font-bold text-gray-800 mb-2 flex items-center gap-2">
<iconify-icon icon="ph:link-bold" class="text-lg text-blue-600"></iconify-icon>
API URL
</label>
<input
id="api-url"
type="text"
placeholder="https://api.example.com/v1/chat"
class="config-input"
value=""
/>
</div>
<!-- API Key -->
<div>
<label class="block font-bold text-gray-800 mb-2 flex items-center gap-2">
<iconify-icon icon="ph:key-bold" class="text-lg text-green-600"></iconify-icon>
API Key
</label>
<input
id="api-key"
type="password"
placeholder="sk-xxxxxxxxxxxxxxxx"
class="config-input"
value=""
/>
</div>
<!-- Model -->
<div>
<label class="block font-bold text-gray-800 mb-2 flex items-center gap-2">
<iconify-icon icon="ph:robot-bold" class="text-lg text-purple-600"></iconify-icon>
模型 (Model)
</label>
<input
id="api-model"
type="text"
placeholder="gpt-4-turbo"
class="config-input"
value=""
/>
</div>
<!-- 状态显示 -->
<div id="config-status" class="p-3 border-2 border-gray-300 bg-gray-50 text-sm text-gray-600 hidden">
<iconify-icon icon="ph:info" class="align-middle"></iconify-icon>
<span id="status-text">等待操作...</span>
</div>
</div>
<!-- 模态窗底部按钮 -->
<div class="p-4 border-t-3 border-gray-300 bg-gray-100 flex gap-3 justify-end">
<button id="test-api-btn" class="px-4 py-2 bg-yellow-500 text-white font-bold border-2 border-black hover:bg-yellow-600 transition-all flex items-center gap-2">
<iconify-icon icon="ph:flask-bold"></iconify-icon>
测试连接
</button>
<button id="save-config-btn" class="px-4 py-2 bg-green-500 text-white font-bold border-2 border-black hover:bg-green-600 transition-all flex items-center gap-2">
<iconify-icon icon="ph:floppy-disk-bold"></iconify-icon>
保存配置
</button>
</div>
</div>
</div>
<script>
// ===== 全局变量 =====
let currentMode = 'canvas';
let svgStorage = {};
let currentSvgId = null;
let apiConfig = {
url: '',
key: '',
model: ''
};
// ===== DOM元素 =====
const canvasBtn = document.getElementById('canvas-mode-btn');
const swotBtn = document.getElementById('swot-mode-btn');
const pageTitle = document.getElementById('page-title');
const placeholderText = document.getElementById('placeholder-text');
const chatInput = document.getElementById('chat-input');
const sendButton = document.getElementById('send-button');
const chatHistory = document.getElementById('chat-history');
const svgViewer = document.getElementById('svg-viewer');
// 模态窗元素
const settingsBtn = document.getElementById('settings-btn');
const configModal = document.getElementById('config-modal');
const closeModalBtn = document.getElementById('close-modal-btn');
const apiUrlInput = document.getElementById('api-url');
const apiKeyInput = document.getElementById('api-key');
const apiModelInput = document.getElementById('api-model');
const testApiBtn = document.getElementById('test-api-btn');
const saveConfigBtn = document.getElementById('save-config-btn');
const configStatus = document.getElementById('config-status');
const statusText = document.getElementById('status-text');
// ===== 初始化 - 加载已保存的配置 =====
function loadConfig() {
const saved = localStorage.getItem('apiConfig');
if (saved) {
apiConfig = JSON.parse(saved);
apiUrlInput.value = apiConfig.url || '';
apiKeyInput.value = apiConfig.key || '';
apiModelInput.value = apiConfig.model || '';
}
}
// ===== 模态窗控制 =====
settingsBtn.addEventListener('click', () => {
configModal.classList.add('active');
loadConfig();
});
closeModalBtn.addEventListener('click', () => {
configModal.classList.remove('active');
});
configModal.addEventListener('click', (e) => {
if (e.target === configModal) {
configModal.classList.remove('active');
}
});
// ===== 保存配置 =====
saveConfigBtn.addEventListener('click', () => {
apiConfig.url = apiUrlInput.value.trim();
apiConfig.key = apiKeyInput.value.trim();
apiConfig.model = apiModelInput.value.trim();
if (!apiConfig.url || !apiConfig.key || !apiConfig.model) {
showStatus('⚠️ 请填写所有字段', 'error');
return;
}
localStorage.setItem('apiConfig', JSON.stringify(apiConfig));
showStatus('✅ 配置已保存成功!', 'success');
setTimeout(() => {
configModal.classList.remove('active');
}, 1500);
});
// ===== 测试API连接 =====
testApiBtn.addEventListener('click', async () => {
const url = apiUrlInput.value.trim();
const key = apiKeyInput.value.trim();
const model = apiModelInput.value.trim();
if (!url || !key || !model) {
showStatus('⚠️ 请先填写所有字段', 'error');
return;
}
showStatus('🔄 正在测试连接...', 'loading');
// TODO: 实现真实的API测试
setTimeout(() => {
// 模拟测试成功
showStatus('✅ 连接测试成功!', 'success');
// 真实实现示例:
/*
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${key}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: model,
messages: [{role: 'user', content: 'test'}],
max_tokens: 5
})
});
if (response.ok) {
showStatus('✅ 连接测试成功!', 'success');
} else {
showStatus('❌ 连接失败: ' + response.statusText, 'error');
}
} catch (error) {
showStatus('❌ 连接失败: ' + error.message, 'error');
}
*/
}, 1500);
});
// ===== 显示状态信息 =====
function showStatus(message, type) {
configStatus.classList.remove('hidden');
statusText.textContent = message;
configStatus.classList.remove('border-gray-300', 'bg-gray-50', 'text-gray-600');
configStatus.classList.remove('border-green-500', 'bg-green-50', 'text-green-700');
configStatus.classList.remove('border-red-500', 'bg-red-50', 'text-red-700');
configStatus.classList.remove('border-blue-500', 'bg-blue-50', 'text-blue-700');
if (type === 'success') {
configStatus.classList.add('border-green-500', 'bg-green-50', 'text-green-700');
} else if (type === 'error') {
configStatus.classList.add('border-red-500', 'bg-red-50', 'text-red-700');
} else if (type === 'loading') {
configStatus.classList.add('border-blue-500', 'bg-blue-50', 'text-blue-700');
} else {
configStatus.classList.add('border-gray-300', 'bg-gray-50', 'text-gray-600');
}
}
// ===== 模式切换 =====
canvasBtn.addEventListener('click', () => {
if (currentMode !== 'canvas') {
currentMode = 'canvas';
updateModeUI();
}
});
swotBtn.addEventListener('click', () => {
if (currentMode !== 'swot') {
currentMode = 'swot';
updateModeUI();
}
});
function updateModeUI() {
if (currentMode === 'canvas') {
canvasBtn.classList.add('mode-btn-active');
canvasBtn.classList.remove('mode-btn-inactive');
swotBtn.classList.remove('mode-btn-active');
swotBtn.classList.add('mode-btn-inactive');
pageTitle.textContent = '产品画布';
if (!currentSvgId) {
placeholderText.textContent = '生成的产品画布将在此处显示';
}
} else {
swotBtn.classList.add('mode-btn-active');
swotBtn.classList.remove('mode-btn-inactive');
canvasBtn.classList.remove('mode-btn-active');
canvasBtn.classList.add('mode-btn-inactive');
pageTitle.textContent = 'SWOT分析';
if (!currentSvgId) {
placeholderText.textContent = '生成的SWOT分析将在此处显示';
}
}
}
// ===== 发送消息 =====
sendButton.addEventListener('click', sendMessage);
chatInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendMessage();
}
});
function sendMessage() {
const message = chatInput.value.trim();
if (!message) return;
// 检查API配置
if (!apiConfig.url || !apiConfig.key || !apiConfig.model) {
alert('⚠️ 请先配置API设置点击右上角齿轮图标进行配置。');
settingsBtn.click();
return;
}
addUserMessage(message);
chatInput.value = '';
// 模拟API调用TODO: 替换为真实调用)
setTimeout(() => {
simulateAPIResponse(message);
}, 1000);
}
// ===== 添加用户消息 =====
function addUserMessage(text) {
const messageDiv = document.createElement('div');
messageDiv.className = 'flex justify-end';
messageDiv.innerHTML = `
<div class="chat-bubble-user">
${escapeHtml(text)}
</div>
`;
chatHistory.appendChild(messageDiv);
scrollToBottom();
}
// ===== 添加AI消息 =====
function addAIMessage(fullResponse) {
const messageId = 'msg-' + Date.now();
const parsed = parseSVGResponse(fullResponse);
if (parsed.svgContent) {
const svgId = 'svg-' + Date.now();
svgStorage[svgId] = {
content: parsed.svgContent,
messageId: messageId
};
viewSVG(svgId);
const messageDiv = document.createElement('div');
messageDiv.className = 'flex justify-start';
messageDiv.innerHTML = `
<div class="chat-bubble-ai relative group" data-message-id="${messageId}">
<div>
${escapeHtml(parsed.beforeText)}
<div class="svg-placeholder-block" data-svg-id="${svgId}" onclick="viewSVG('${svgId}')">
📊 点击查看 SVG
</div>
${escapeHtml(parsed.afterText)}
</div>
<div class="flex gap-2 mt-2 pt-2 border-t border-gray-200">
<button class="bubble-action-btn flex items-center gap-1 text-xs text-gray-600 hover:text-blue-600 transition-colors" onclick="rollbackToMessage('${messageId}')">
<iconify-icon icon="ph:arrow-u-up-left-bold"></iconify-icon>
<span>退回</span>
</button>
<button class="bubble-action-btn flex items-center gap-1 text-xs text-gray-600 hover:text-green-600 transition-colors" onclick="regenerateMessage('${messageId}')">
<iconify-icon icon="ph:arrow-clockwise-bold"></iconify-icon>
<span>重新生成</span>
</button>
</div>
</div>
`;
chatHistory.appendChild(messageDiv);
} else {
const messageDiv = document.createElement('div');
messageDiv.className = 'flex justify-start';
messageDiv.innerHTML = `
<div class="chat-bubble-ai relative group" data-message-id="${messageId}">
<div class="mb-1">
${escapeHtml(fullResponse)}
</div>
<div class="flex gap-2 mt-2 pt-2 border-t border-gray-200">
<button class="bubble-action-btn flex items-center gap-1 text-xs text-gray-600 hover:text-blue-600 transition-colors" onclick="rollbackToMessage('${messageId}')">
<icon ify-icon icon="ph:arrow-u-up-left-bold"></iconify-icon>
<span>退回</span>
</button>
<button class="bubble-action-btn flex items-center gap-1 text-xs text-gray-600 hover:text-green-600 transition-colors" onclick="regenerateMessage('${messageId}')">
<iconify-icon icon="ph:arrow-clockwise-bold"></iconify-icon>
<span>重新生成</span>
</button>
</div>
</div>
`;
chatHistory.appendChild(messageDiv);
}
scrollToBottom();
}
// ===== 解析SVG响应 =====
function parseSVGResponse(response) {
const svgRegex = /```svg\s*([\s\S]*?)```/i;
const match = response.match(svgRegex);
if (match) {
const svgContent = match[1].trim();
const beforeText = response.substring(0, match.index).trim();
const afterText = response.substring(match.index + match[0].length).trim();
return {
svgContent,
beforeText,
afterText
};
}
return {
svgContent: null,
beforeText: response,
afterText: ''
};
}
// ===== 显示SVG =====
function viewSVG(svgId) {
if (!svgStorage[svgId]) {
console.error('SVG not found:', svgId);
return;
}
currentSvgId = svgId;
const svgContent = svgStorage[svgId].content;
svgViewer.innerHTML = svgContent;
}
// ===== 气泡操作功能 =====
function rollbackToMessage(messageId) {
console.log('退回到消息:', messageId);
// TODO: 实现退回逻辑
}
function regenerateMessage(messageId) {
console.log('重新生成消息:', messageId);
// TODO: 实现重新生成逻辑
}
// ===== 底部操作按钮 =====
document.getElementById('download-svg-btn').addEventListener('click', () => {
if (!currentSvgId) {
alert('请先生成SVG图表');
return;
}
const svgContent = svgStorage[currentSvgId].content;
const blob = new Blob([svgContent], { type: 'image/svg+xml' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${currentMode}-${Date.now()}.svg`;
a.click();
URL.revokeObjectURL(url);
});
document.getElementById('export-image-btn').addEventListener('click', () => {
if (!currentSvgId) {
alert('请先生成SVG图表');
return;
}
console.log('导出为图片:', currentSvgId);
// TODO: 实现SVG转PNG功能
});
document.getElementById('view-code-btn').addEventListener('click', () => {
if (!currentSvgId) {
alert('请先生成SVG图表');
return;
}
const svgContent = svgStorage[currentSvgId].content;
alert('SVG代码\n\n' + svgContent);
// TODO: 使用更好的代码展示弹窗
});
// ===== 工具函数 =====
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function scrollToBottom() {
chatHistory.scrollTop = chatHistory.scrollHeight;
}
// ===== 模拟API响应测试用 =====
function simulateAPIResponse(userMessage) {
const mockResponses = [
`好的!我为您生成了一个${currentMode === 'canvas' ? '产品画布' : 'SWOT分析'}
\`\`\`svg
<svg width="600" height="400" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="#f0f0f0"/>
<text x="300" y="200" text-anchor="middle" font-size="24" fill="#333">
这是${currentMode === 'canvas' ? '产品画布' : 'SWOT分析'}示例SVG
</text>
<circle cx="300" cy="250" r="50" fill="#667eea" opacity="0.5"/>
</svg>
\`\`\`
包含了关键要素和模块。点击上方标签可在右侧查看详细图表。`,
`已经为您调整完成!
\`\`\`svg
<svg width="600" height="400" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea;stop-opacity:1" />
<stop offset="100%" style="stop-color:#764ba2;stop-opacity:1" />
</linearGradient>
</defs>
<rect width="100%" height="100%" fill="url(#grad1)"/>
<text x="300" y="200" text-anchor="middle" font-size="28" fill="white" font-weight="bold">
${currentMode === 'canvas' ? '优化后的产品画布' : '优化后的SWOT分析'}
</text>
</svg>
\`\`\`
采用了更加鲜明的色彩组合,希望您满意!`
];
const response = mockResponses[Math.floor(Math.random() * mockResponses.length)];
addAIMessage(response);
}
// ===== 页面加载时初始化 =====
loadConfig();
</script>
</body>
</html>
```