资源改为本地引用
This commit is contained in:
@@ -329,6 +329,25 @@ iconify-icon {
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.code-modal-content {
|
||||||
|
max-width: 760px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-viewer {
|
||||||
|
background: #0f172a;
|
||||||
|
color: #f8fafc;
|
||||||
|
border: 2px solid #000;
|
||||||
|
padding: 16px;
|
||||||
|
font-family: 'Fira Code', 'Courier New', Courier, monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
border-radius: 6px;
|
||||||
|
max-height: 60vh;
|
||||||
|
overflow: auto;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
/* 表单输入框样式 */
|
/* 表单输入框样式 */
|
||||||
.config-input {
|
.config-input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
37
index.html
37
index.html
@@ -4,12 +4,10 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>产品画布 / SWOT分析</title>
|
<title>产品画布 / SWOT分析</title>
|
||||||
<script src="https://cdn.tailwindcss.com/3.4.1"></script>
|
<script src="libs/css/tailwind.css"></script>
|
||||||
<script src="https://code.iconify.design/iconify-icon/2.1.0/iconify-icon.min.js"></script>
|
<script src="libs/js/iconify-icon.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
<script src="libs/js/marked.min.js"></script>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="stylesheet" href="libs/css/inter-font.css">
|
||||||
<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">
|
|
||||||
<link rel="stylesheet" href="css/style.css">
|
<link rel="stylesheet" href="css/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-gray-100 h-screen flex flex-col">
|
<body class="bg-gray-100 h-screen flex flex-col">
|
||||||
@@ -196,6 +194,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 代码查看模态窗 -->
|
||||||
|
<div id="code-modal" class="modal-overlay">
|
||||||
|
<div class="modal-content code-modal-content">
|
||||||
|
<div class="bg-gradient-to-r from-indigo-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:code-fill" class="text-3xl text-white"></iconify-icon>
|
||||||
|
<h2 class="text-xl font-black text-white">生成代码</h2>
|
||||||
|
</div>
|
||||||
|
<button id="close-code-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">
|
||||||
|
<div class="flex items-center justify-between gap-3">
|
||||||
|
<p class="font-bold text-gray-700">以下为当前图表对应的代码,可复制后用于自定义编辑。</p>
|
||||||
|
<button id="copy-code-btn" class="px-4 py-2 bg-indigo-500 text-white font-bold border-2 border-black hover:bg-indigo-600 transition-all flex items-center gap-2">
|
||||||
|
<iconify-icon icon="ph:copy-bold"></iconify-icon>
|
||||||
|
复制代码
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<pre id="code-content" class="code-viewer"></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 引入JavaScript文件 -->
|
<!-- 引入JavaScript文件 -->
|
||||||
<script src="js/utils.js"></script>
|
<script src="js/utils.js"></script>
|
||||||
<script src="js/services/storage-service.js"></script>
|
<script src="js/services/storage-service.js"></script>
|
||||||
@@ -204,7 +227,7 @@
|
|||||||
<script src="js/modules/product-canvas.js"></script>
|
<script src="js/modules/product-canvas.js"></script>
|
||||||
<script src="js/modules/swot.js"></script>
|
<script src="js/modules/swot.js"></script>
|
||||||
<script src="js/modules/echarts.js"></script>
|
<script src="js/modules/echarts.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
|
<script src="libs/js/echarts.min.js"></script>
|
||||||
<script src="js/core/module-runtime.js"></script>
|
<script src="js/core/module-runtime.js"></script>
|
||||||
<script src="js/core/app-shell.js"></script>
|
<script src="js/core/app-shell.js"></script>
|
||||||
<script src="js/apiclient.js"></script>
|
<script src="js/apiclient.js"></script>
|
||||||
|
|||||||
@@ -78,6 +78,10 @@
|
|||||||
this.el.saveConfigBtn = document.getElementById('save-config-btn');
|
this.el.saveConfigBtn = document.getElementById('save-config-btn');
|
||||||
this.el.configStatus = document.getElementById('config-status');
|
this.el.configStatus = document.getElementById('config-status');
|
||||||
this.el.statusText = document.getElementById('status-text');
|
this.el.statusText = document.getElementById('status-text');
|
||||||
|
this.el.codeModal = document.getElementById('code-modal');
|
||||||
|
this.el.codeContent = document.getElementById('code-content');
|
||||||
|
this.el.copyCodeBtn = document.getElementById('copy-code-btn');
|
||||||
|
this.el.closeCodeModalBtn = document.getElementById('close-code-modal-btn');
|
||||||
|
|
||||||
// 复制按钮可用性
|
// 复制按钮可用性
|
||||||
if (this.el.copyImageBtn && !this.copyClipboardSupported) {
|
if (this.el.copyImageBtn && !this.copyClipboardSupported) {
|
||||||
@@ -187,6 +191,24 @@
|
|||||||
this.handleMessageAction(action, messageId);
|
this.handleMessageAction(action, messageId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.el.copyCodeBtn) {
|
||||||
|
this.el.copyCodeBtn.addEventListener('click', () =>
|
||||||
|
this.copyCodeContent()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.el.closeCodeModalBtn) {
|
||||||
|
this.el.closeCodeModalBtn.addEventListener('click', () =>
|
||||||
|
this.closeCodeModal()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.el.codeModal) {
|
||||||
|
this.el.codeModal.addEventListener('click', (event) => {
|
||||||
|
if (event.target === this.el.codeModal) {
|
||||||
|
this.closeCodeModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setupModuleSwitcher() {
|
setupModuleSwitcher() {
|
||||||
@@ -992,6 +1014,56 @@
|
|||||||
wrapper.style.transformOrigin = 'center top';
|
wrapper.style.transformOrigin = 'center top';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openCodeModal(content = '') {
|
||||||
|
if (!this.el.codeModal) return;
|
||||||
|
if (this.el.codeContent) {
|
||||||
|
this.el.codeContent.textContent = content || '';
|
||||||
|
}
|
||||||
|
this.el.codeModal.classList.add('active');
|
||||||
|
this.el.codeModal.style.display = 'flex';
|
||||||
|
}
|
||||||
|
|
||||||
|
closeCodeModal() {
|
||||||
|
if (!this.el.codeModal) return;
|
||||||
|
this.el.codeModal.classList.remove('active');
|
||||||
|
this.el.codeModal.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
async copyCodeContent() {
|
||||||
|
if (!this.el.codeContent) return;
|
||||||
|
const text = this.el.codeContent.textContent || '';
|
||||||
|
if (!text) {
|
||||||
|
alert('没有可复制的内容');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(text);
|
||||||
|
alert('代码已复制到剪贴板');
|
||||||
|
return;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('复制到剪贴板失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 兼容处理
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.value = text;
|
||||||
|
textarea.setAttribute('readonly', '');
|
||||||
|
textarea.style.position = 'absolute';
|
||||||
|
textarea.style.left = '-9999px';
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
textarea.select();
|
||||||
|
try {
|
||||||
|
document.execCommand('copy');
|
||||||
|
alert('代码已复制到剪贴板');
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('备用复制失败:', error);
|
||||||
|
alert('复制失败,请手动复制');
|
||||||
|
} finally {
|
||||||
|
document.body.removeChild(textarea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cancelActiveStream() {
|
cancelActiveStream() {
|
||||||
if (!this.activeStreamHandle || typeof this.activeStreamHandle.cancel !== 'function') {
|
if (!this.activeStreamHandle || typeof this.activeStreamHandle.cancel !== 'function') {
|
||||||
@@ -1219,11 +1291,7 @@
|
|||||||
content = artifact.optionText || JSON.stringify(artifact.option, null, 2);
|
content = artifact.optionText || JSON.stringify(artifact.option, null, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
const blob = new Blob([content], { type: 'text/plain' });
|
this.openCodeModal(content);
|
||||||
const url = URL.createObjectURL(blob);
|
|
||||||
window.open(url, '_blank');
|
|
||||||
|
|
||||||
setTimeout(() => URL.revokeObjectURL(url), 1000 * 30);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setSendButtonState(state) {
|
setSendButtonState(state) {
|
||||||
|
|||||||
@@ -66,9 +66,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
exports: {
|
exports: {
|
||||||
allowSvg: false,
|
allowSvg: true,
|
||||||
allowPng: true,
|
allowPng: true,
|
||||||
allowClipboard: false,
|
allowClipboard: true,
|
||||||
allowCode: true
|
allowCode: true
|
||||||
},
|
},
|
||||||
ui: {
|
ui: {
|
||||||
|
|||||||
21
libs/css/inter-font.css
Normal file
21
libs/css/inter-font.css
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Inter';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../fonts/inter-400.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Inter';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../fonts/inter-700.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Inter';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../fonts/inter-900.ttf) format('truetype');
|
||||||
|
}
|
||||||
65
libs/css/tailwind.css
Normal file
65
libs/css/tailwind.css
Normal file
File diff suppressed because one or more lines are too long
BIN
libs/fonts/inter-400.ttf
Normal file
BIN
libs/fonts/inter-400.ttf
Normal file
Binary file not shown.
BIN
libs/fonts/inter-700.ttf
Normal file
BIN
libs/fonts/inter-700.ttf
Normal file
Binary file not shown.
BIN
libs/fonts/inter-900.ttf
Normal file
BIN
libs/fonts/inter-900.ttf
Normal file
Binary file not shown.
45
libs/js/echarts.min.js
vendored
Normal file
45
libs/js/echarts.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12
libs/js/iconify-icon.min.js
vendored
Normal file
12
libs/js/iconify-icon.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
69
libs/js/marked.min.js
vendored
Normal file
69
libs/js/marked.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user