@lark-apaas/devtool-kits 0.1.0-alpha.0 → 0.1.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,345 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>错误页面</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
16
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
17
+ sans-serif;
18
+ -webkit-font-smoothing: antialiased;
19
+ -moz-osx-font-smoothing: grayscale;
20
+ }
21
+
22
+ .container {
23
+ min-height: 100vh;
24
+ display: flex;
25
+ align-items: center;
26
+ justify-content: center;
27
+ background-color: #F3F4F6; /* bg-gray-100 */
28
+ padding: 20px;
29
+ }
30
+
31
+ .content {
32
+ display: flex;
33
+ flex-direction: column;
34
+ justify-content: center;
35
+ align-items: center;
36
+ text-align: center;
37
+ max-width: 800px;
38
+ width: 100%;
39
+ }
40
+
41
+ .error-image {
42
+ margin-bottom: 16px; /* mb-4 */
43
+ width: 120px; /* w-[120px] */
44
+ height: auto;
45
+ }
46
+
47
+ .title {
48
+ font-size: 18px; /* text-l (推测为 text-lg) */
49
+ line-height: 22px;
50
+ color: #1F2329;
51
+ font-weight: 500; /* font-medium */
52
+ margin-bottom: 8px; /* mb-2 */
53
+ }
54
+
55
+ .description {
56
+ font-size: 14px; /* text-sm */
57
+ line-height: 22px;
58
+ color: #646A73;
59
+ font-weight: 400; /* font-normal */
60
+ margin-bottom: 16px; /* mb-4 */
61
+ }
62
+
63
+ .error-message {
64
+ font-size: 14px;
65
+ line-height: 20px;
66
+ color: #DC2626; /* red-600 */
67
+ margin-bottom: 16px;
68
+ padding: 8px 12px;
69
+ background-color: #FEF2F2; /* red-50 */
70
+ border-radius: 6px;
71
+ word-break: break-word;
72
+ }
73
+
74
+ .logs-container {
75
+ width: 100%;
76
+ max-width: 700px;
77
+ margin-bottom: 16px;
78
+ text-align: left;
79
+ }
80
+
81
+ .logs-box {
82
+ background-color: #1F2937; /* gray-800 */
83
+ color: #F9FAFB; /* gray-50 */
84
+ padding: 12px;
85
+ border-radius: 6px;
86
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
87
+ font-size: 12px;
88
+ line-height: 18px;
89
+ overflow-x: auto;
90
+ max-height: 300px;
91
+ overflow-y: auto;
92
+ white-space: pre-wrap;
93
+ word-break: break-all;
94
+ }
95
+
96
+ .button-group {
97
+ display: flex;
98
+ gap: 16px; /* space-x-4 */
99
+ }
100
+
101
+ .button {
102
+ height: 32px; /* h-[32px] */
103
+ padding: 0 16px;
104
+ border-radius: 6px; /* rounded-[6px] */
105
+ font-size: 14px; /* text-sm */
106
+ font-weight: 400; /* font-[400] */
107
+ cursor: pointer;
108
+ transition: all 0.2s;
109
+ outline: none; /* focus:outline-hidden */
110
+ border: 1px solid;
111
+ }
112
+
113
+ .button-copy {
114
+ background-color: white; /* bg-white */
115
+ color: #4B5563; /* text-gray-600 */
116
+ border-color: #D0D3D6; /* border-[#D0D3D6] */
117
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); /* shadow-xs */
118
+ }
119
+
120
+ .button-copy:hover {
121
+ background-color: #F3F4F6; /* hover:bg-gray-100 */
122
+ }
123
+
124
+ .button-copy:active {
125
+ background-color: #E5E7EB; /* active:bg-gray-200 */
126
+ }
127
+
128
+ .button-repair {
129
+ background-color: #2563EB; /* bg-blue-600 */
130
+ color: white; /* text-white */
131
+ border-color: transparent; /* border-transparent */
132
+ font-weight: 500; /* font-medium */
133
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); /* shadow-xs */
134
+ }
135
+
136
+ .button-repair:hover {
137
+ background-color: #2563EB; /* hover:bg-blue-600 (保持不变) */
138
+ }
139
+
140
+ .button-repair:active {
141
+ background-color: #1E40AF; /* active:bg-blue-700 */
142
+ }
143
+ </style>
144
+ </head>
145
+ <body>
146
+ <div class="container">
147
+ <div class="content">
148
+ <img
149
+ src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ylcylz_fsph_ryhs/ljhwZthlaukjlkulzlp/feisuda/template/render_error.svg"
150
+ alt="render error"
151
+ class="error-image"
152
+ />
153
+ <p class="title">哎呀,写错代码了</p>
154
+ <p class="description">代理服务出现异常,请查看下方错误日志</p>
155
+
156
+ <div class="error-message" id="errorMessage"></div>
157
+
158
+ <div class="logs-container">
159
+ <div class="logs-box" id="logsBox">
160
+ 正在加载日志...
161
+ </div>
162
+ </div>
163
+
164
+ <div class="button-group">
165
+ <button class="button button-copy" id="copyBtn">
166
+ 复制错误信息
167
+ </button>
168
+ <button class="button button-repair" id="repairBtn">
169
+ 告诉妙搭修复
170
+ </button>
171
+ </div>
172
+ </div>
173
+ </div>
174
+
175
+ <script>
176
+ // 全局错误对象
177
+ let errorData = {
178
+ message: "{{.errorData.message}}",
179
+ };
180
+ let locationData = null;
181
+
182
+ // 初始化页面
183
+ function init() {
184
+ // 显示错误信息
185
+ const errorMessageEl = document.getElementById('errorMessage');
186
+ const logsBoxEl = document.getElementById('logsBox');
187
+
188
+ if (errorData.message) {
189
+ errorMessageEl.textContent = errorData.message;
190
+ }
191
+
192
+ if (errorData.logs) {
193
+ logsBoxEl.textContent = errorData.logs;
194
+ } else {
195
+ logsBoxEl.textContent = '未找到相关错误日志';
196
+ }
197
+
198
+ // 绑定事件
199
+ document.getElementById('copyBtn').addEventListener('click', handleCopy);
200
+ document.getElementById('repairBtn').addEventListener('click', handleRepair);
201
+
202
+ // 获取当前位置信息
203
+ locationData = {
204
+ pathname: window.location.pathname,
205
+ search: window.location.search,
206
+ hash: window.location.hash,
207
+ };
208
+
209
+ // 如果有错误对象,发送 postMessage
210
+ if (errorData) {
211
+ sendPostMessage({
212
+ type: 'RenderError',
213
+ data: errorData,
214
+ location: locationData,
215
+ });
216
+ }
217
+ }
218
+
219
+ // 复制错误信息到剪贴板
220
+ async function handleCopy() {
221
+ if (!errorData) {
222
+ console.error('没有错误信息可复制');
223
+ return;
224
+ }
225
+
226
+ const { message, logs } = errorData;
227
+ let result = '';
228
+
229
+ if (message) {
230
+ result += message + '\n\n';
231
+ }
232
+
233
+ if (logs) {
234
+ result += '错误日志:\n' + logs;
235
+ }
236
+
237
+ if (!result) {
238
+ result = '未找到错误信息';
239
+ }
240
+
241
+ const success = await copyToClipboard(result);
242
+ if (success) {
243
+ console.log('错误信息已复制到剪贴板');
244
+ // 可选:显示复制成功提示
245
+ const btn = document.getElementById('copyBtn');
246
+ const originalText = btn.textContent;
247
+ btn.textContent = '已复制!';
248
+ setTimeout(() => {
249
+ btn.textContent = originalText;
250
+ }, 2000);
251
+ } else {
252
+ console.error('复制失败');
253
+ }
254
+ }
255
+
256
+ // 告诉妙搭修复
257
+ function handleRepair() {
258
+ sendPostMessage({
259
+ type: 'RenderErrorRepair',
260
+ data: errorData,
261
+ });
262
+ }
263
+
264
+ // 发送 postMessage
265
+ function sendPostMessage(message, targetOrigin) {
266
+ console.log('发送 postMessage:', message);
267
+ const origin = targetOrigin || getPreviewParentOrigin();
268
+ window.parent.postMessage(message, origin);
269
+ }
270
+
271
+ // 获取父窗口 origin
272
+ function getPreviewParentOrigin() {
273
+ // 优先使用 document.referrer
274
+ if (document.referrer) {
275
+ try {
276
+ const url = new URL(document.referrer);
277
+ return url.origin;
278
+ } catch (e) {
279
+ console.error('解析 referrer 失败:', e);
280
+ }
281
+ }
282
+
283
+ // 降级方案:使用通配符(不安全,仅用于开发环境)
284
+ return '*';
285
+ }
286
+
287
+ // 复制到剪贴板
288
+ async function copyToClipboard(text) {
289
+ try {
290
+ // 优先使用现代的 Clipboard API
291
+ if (navigator.clipboard && window.isSecureContext) {
292
+ await navigator.clipboard.writeText(text);
293
+ return true;
294
+ }
295
+
296
+ // 降级方案:使用传统的 execCommand 方法
297
+ return fallbackCopyToClipboard(text);
298
+ } catch (error) {
299
+ console.error('复制到剪切板失败:', error);
300
+ return false;
301
+ }
302
+ }
303
+
304
+ // 降级复制方案(兼容旧浏览器)
305
+ function fallbackCopyToClipboard(text) {
306
+ try {
307
+ // 创建临时的 textarea 元素
308
+ const textArea = document.createElement('textarea');
309
+ textArea.value = text;
310
+
311
+ // 设置样式,使其不可见
312
+ textArea.style.position = 'fixed';
313
+ textArea.style.left = '-999999px';
314
+ textArea.style.top = '-999999px';
315
+ textArea.setAttribute('readonly', '');
316
+
317
+ // 添加到 DOM
318
+ document.body.appendChild(textArea);
319
+
320
+ // 选中文本
321
+ textArea.focus();
322
+ textArea.select();
323
+
324
+ // 执行复制命令
325
+ const successful = document.execCommand('copy');
326
+
327
+ // 清理:移除临时元素
328
+ document.body.removeChild(textArea);
329
+
330
+ return successful;
331
+ } catch (error) {
332
+ console.error('降级复制方案失败:', error);
333
+ return false;
334
+ }
335
+ }
336
+
337
+ // 页面加载完成后初始化
338
+ if (document.readyState === 'loading') {
339
+ document.addEventListener('DOMContentLoaded', init);
340
+ } else {
341
+ init();
342
+ }
343
+ </script>
344
+ </body>
345
+ </html>