vue_zhongyou 1.0.1

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,501 @@
1
+ <template>
2
+ <div class="test-error-page">
3
+ <div class="header">
4
+ <h2>错误捕获测试页面</h2>
5
+ <van-button
6
+ type="primary"
7
+ size="small"
8
+ @click="goToLogPage"
9
+ >
10
+ 查看错误日志
11
+ </van-button>
12
+ </div>
13
+
14
+ <!-- 统计信息 -->
15
+ <div class="stats-card">
16
+ <div class="stat-item">
17
+ <div class="stat-label">总计</div>
18
+ <div class="stat-value">{{ statistics.total }}</div>
19
+ </div>
20
+ <div class="stat-item">
21
+ <div class="stat-label">接口错误</div>
22
+ <div class="stat-value">{{ statistics.api }}</div>
23
+ </div>
24
+ <div class="stat-item">
25
+ <div class="stat-label">页面错误</div>
26
+ <div class="stat-value">{{ statistics.page }}</div>
27
+ </div>
28
+ <div class="stat-item">
29
+ <div class="stat-label">Promise错误</div>
30
+ <div class="stat-value">{{ statistics.promise }}</div>
31
+ </div>
32
+ </div>
33
+
34
+ <!-- 接口错误测试 -->
35
+ <div class="test-section">
36
+ <div class="section-title">接口错误测试</div>
37
+ <div class="button-group">
38
+ <van-button
39
+ type="primary"
40
+ :loading="loading"
41
+ @click="fetchNoticeList"
42
+ >
43
+ 正常请求(返回noticeList)
44
+ </van-button>
45
+ <van-button
46
+ type="danger"
47
+ @click="test404Error"
48
+ >
49
+ 测试404错误
50
+ </van-button>
51
+ <van-button
52
+ type="danger"
53
+ @click="test500Error"
54
+ >
55
+ 测试500错误
56
+ </van-button>
57
+ <van-button
58
+ type="warning"
59
+ @click="testNetworkError"
60
+ >
61
+ 测试网络错误
62
+ </van-button>
63
+ <van-button
64
+ type="warning"
65
+ @click="testTimeoutError"
66
+ >
67
+ 测试超时错误
68
+ </van-button>
69
+ </div>
70
+
71
+ <!-- 请求结果显示 -->
72
+ <div v-if="requestResult" class="result-box">
73
+ <div class="result-title">请求结果:</div>
74
+ <pre class="result-content">{{ requestResult }}</pre>
75
+ </div>
76
+ </div>
77
+
78
+ <!-- 页面错误测试 -->
79
+ <div class="test-section">
80
+ <div class="section-title">页面错误测试</div>
81
+ <div class="button-group">
82
+ <van-button
83
+ type="danger"
84
+ @click="testPageError"
85
+ >
86
+ 测试JavaScript错误
87
+ </van-button>
88
+ <van-button
89
+ type="danger"
90
+ @click="testReferenceError"
91
+ >
92
+ 测试引用错误
93
+ </van-button>
94
+ <van-button
95
+ type="danger"
96
+ @click="testTypeError"
97
+ >
98
+ 测试类型错误
99
+ </van-button>
100
+ </div>
101
+ </div>
102
+
103
+ <!-- Promise错误测试 -->
104
+ <div class="test-section">
105
+ <div class="section-title">Promise错误测试</div>
106
+ <div class="button-group">
107
+ <van-button
108
+ type="warning"
109
+ @click="testPromiseError"
110
+ >
111
+ 测试Promise未捕获错误
112
+ </van-button>
113
+ <van-button
114
+ type="warning"
115
+ @click="testAsyncError"
116
+ >
117
+ 测试Async函数错误
118
+ </van-button>
119
+ </div>
120
+ </div>
121
+
122
+ <!-- Vue组件错误测试 -->
123
+ <div class="test-section">
124
+ <div class="section-title">Vue组件错误测试</div>
125
+ <div class="button-group">
126
+ <van-button
127
+ type="danger"
128
+ @click="testVueError"
129
+ >
130
+ 测试Vue组件渲染错误
131
+ </van-button>
132
+ </div>
133
+ <!-- 用于触发Vue错误的组件 -->
134
+ <div v-if="shouldRenderError">
135
+ {{ undefinedVariable.property }}
136
+ </div>
137
+ </div>
138
+
139
+ <!-- 刷新统计按钮 -->
140
+ <div class="refresh-section">
141
+ <van-button
142
+ type="default"
143
+ block
144
+ @click="refreshStatistics"
145
+ >
146
+ 刷新统计信息
147
+ </van-button>
148
+ </div>
149
+ </div>
150
+ </template>
151
+
152
+ <script setup>
153
+ import { ref, onMounted } from 'vue'
154
+ import { useRouter } from 'vue-router'
155
+ import { showToast, showFailToast, showSuccessToast } from 'vant'
156
+ import request from '@/api/request'
157
+ import errorMonitor from '@/utils/errorMonitor'
158
+
159
+ const router = useRouter()
160
+ const loading = ref(false)
161
+ const requestResult = ref('')
162
+ const shouldRenderError = ref(false)
163
+ const statistics = ref({
164
+ total: 0,
165
+ api: 0,
166
+ page: 0,
167
+ promise: 0
168
+ })
169
+
170
+ // 刷新统计信息
171
+ const refreshStatistics = () => {
172
+ statistics.value = errorMonitor.getStatistics()
173
+ showToast('统计信息已刷新')
174
+ }
175
+
176
+ // 跳转到日志页面
177
+ const goToLogPage = () => {
178
+ router.push('/error-log')
179
+ }
180
+
181
+ // ============ 接口错误测试 ============
182
+
183
+ // 正常请求 - 获取noticeList
184
+ const fetchNoticeList = async () => {
185
+ loading.value = true
186
+ requestResult.value = ''
187
+
188
+ try {
189
+ // 模拟一个正常的接口请求
190
+ const response = await request.get('/api/notice/list', {
191
+ params: {
192
+ page: 1,
193
+ pageSize: 10
194
+ }
195
+ })
196
+
197
+ // 如果请求成功,显示结果
198
+ if (response && response.data) {
199
+ requestResult.value = JSON.stringify(response.data, null, 2)
200
+ showSuccessToast('请求成功,数据已更新')
201
+ } else {
202
+ // 模拟返回的数据
203
+ const mockData = [
204
+ { id: 1, title: '通知公告1', content: '这是通知公告1的内容' },
205
+ { id: 2, title: '通知公告2', content: '这是通知公告2的内容' },
206
+ { id: 3, title: '通知公告3', content: '这是通知公告3的内容' },
207
+ { id: 4, title: '通知公告4', content: '这是通知公告4的内容' },
208
+ { id: 5, title: '通知公告5', content: '这是通知公告5的内容' }
209
+ ]
210
+ requestResult.value = JSON.stringify(mockData, null, 2)
211
+ showSuccessToast('使用模拟数据(接口不存在)')
212
+ }
213
+
214
+ refreshStatistics()
215
+ } catch (error) {
216
+ // 错误会被错误监控自动捕获
217
+ requestResult.value = `错误: ${error.message || '未知错误'}`
218
+ showFailToast('请求失败:' + (error.message || '未知错误'))
219
+ refreshStatistics()
220
+ } finally {
221
+ loading.value = false
222
+ }
223
+ }
224
+
225
+ // 测试404错误
226
+ const test404Error = async () => {
227
+ loading.value = true
228
+ requestResult.value = ''
229
+
230
+ try {
231
+ await request.get('/api/not-found-endpoint-404')
232
+ } catch (error) {
233
+ requestResult.value = `404错误已捕获: ${error.message}`
234
+ showFailToast('404错误已捕获')
235
+ refreshStatistics()
236
+ } finally {
237
+ loading.value = false
238
+ }
239
+ }
240
+
241
+ // 测试500错误
242
+ const test500Error = async () => {
243
+ loading.value = true
244
+ requestResult.value = ''
245
+
246
+ try {
247
+ await request.get('/api/server-error-500')
248
+ } catch (error) {
249
+ requestResult.value = `500错误已捕获: ${error.message}`
250
+ showFailToast('500错误已捕获')
251
+ refreshStatistics()
252
+ } finally {
253
+ loading.value = false
254
+ }
255
+ }
256
+
257
+ // 测试网络错误
258
+ const testNetworkError = async () => {
259
+ loading.value = true
260
+ requestResult.value = ''
261
+
262
+ try {
263
+ // 临时修改baseURL来模拟网络错误
264
+ const originalBaseURL = request.defaults.baseURL
265
+ request.defaults.baseURL = 'https://non-existent-domain-12345-xyz.com'
266
+
267
+ await request.get('/api/test-network-error')
268
+
269
+ // 恢复baseURL
270
+ request.defaults.baseURL = originalBaseURL
271
+ } catch (error) {
272
+ requestResult.value = `网络错误已捕获: ${error.message}`
273
+ showFailToast('网络错误已捕获')
274
+ // 恢复baseURL
275
+ request.defaults.baseURL = import.meta.env.VITE_API_BASE_URL || ''
276
+ refreshStatistics()
277
+ } finally {
278
+ loading.value = false
279
+ }
280
+ }
281
+
282
+ // 测试超时错误
283
+ const testTimeoutError = async () => {
284
+ loading.value = true
285
+ requestResult.value = ''
286
+
287
+ try {
288
+ // 创建一个超时时间很短的请求
289
+ await request.get('/api/slow-endpoint', {
290
+ timeout: 100 // 100ms超时
291
+ })
292
+ } catch (error) {
293
+ requestResult.value = `超时错误已捕获: ${error.message}`
294
+ showFailToast('超时错误已捕获')
295
+ refreshStatistics()
296
+ } finally {
297
+ loading.value = false
298
+ }
299
+ }
300
+
301
+ // ============ 页面错误测试 ============
302
+
303
+ // 测试JavaScript错误
304
+ const testPageError = () => {
305
+ // 使用 setTimeout 确保错误不会被 try-catch 捕获
306
+ setTimeout(() => {
307
+ throw new Error('测试页面错误:这是一个模拟的前端JavaScript错误')
308
+ }, 0)
309
+ showToast('页面错误已触发,请查看控制台和日志')
310
+ setTimeout(() => {
311
+ refreshStatistics()
312
+ }, 100)
313
+ }
314
+
315
+ // 测试引用错误
316
+ const testReferenceError = () => {
317
+ setTimeout(() => {
318
+ // @ts-ignore
319
+ undefinedVariable.someProperty // 这会触发 ReferenceError
320
+ }, 0)
321
+ showToast('引用错误已触发,请查看控制台和日志')
322
+ setTimeout(() => {
323
+ refreshStatistics()
324
+ }, 100)
325
+ }
326
+
327
+ // 测试类型错误
328
+ const testTypeError = () => {
329
+ setTimeout(() => {
330
+ const obj = null
331
+ // @ts-ignore
332
+ obj.property // 这会触发 TypeError
333
+ }, 0)
334
+ showToast('类型错误已触发,请查看控制台和日志')
335
+ setTimeout(() => {
336
+ refreshStatistics()
337
+ }, 100)
338
+ }
339
+
340
+ // ============ Promise错误测试 ============
341
+
342
+ // 测试Promise未捕获错误
343
+ const testPromiseError = () => {
344
+ // 创建一个未处理的Promise错误
345
+ Promise.reject(new Error('测试Promise错误:这是一个未捕获的Promise错误'))
346
+ showToast('Promise错误已触发,请查看控制台和日志')
347
+ setTimeout(() => {
348
+ refreshStatistics()
349
+ }, 100)
350
+ }
351
+
352
+ // 测试Async函数错误
353
+ const testAsyncError = async () => {
354
+ // 创建一个异步函数,但不捕获错误
355
+ const asyncFunc = async () => {
356
+ throw new Error('测试Async函数错误:这是一个异步函数中的未捕获错误')
357
+ }
358
+
359
+ // 不等待,让它自己失败
360
+ asyncFunc().catch(() => {
361
+ // 即使这里捕获了,但如果在其他地方没有捕获,错误监控还是会捕获
362
+ })
363
+
364
+ // 触发一个真正未捕获的Promise错误
365
+ setTimeout(() => {
366
+ Promise.reject(new Error('Async函数中的未捕获Promise错误'))
367
+ }, 0)
368
+
369
+ showToast('Async错误已触发,请查看控制台和日志')
370
+ setTimeout(() => {
371
+ refreshStatistics()
372
+ }, 100)
373
+ }
374
+
375
+ // ============ Vue组件错误测试 ============
376
+
377
+ // 测试Vue组件渲染错误
378
+ const testVueError = () => {
379
+ shouldRenderError.value = true
380
+ showToast('Vue渲染错误已触发,请查看控制台和日志')
381
+ setTimeout(() => {
382
+ shouldRenderError.value = false
383
+ refreshStatistics()
384
+ }, 100)
385
+ }
386
+
387
+ const getData = ()=>{
388
+ return request({
389
+ url : '/test',
390
+ })
391
+ }
392
+
393
+ // 初始化
394
+ onMounted(() => {
395
+ getData()
396
+ refreshStatistics()
397
+ })
398
+ </script>
399
+
400
+ <style lang="scss" scoped>
401
+ .test-error-page {
402
+ padding: 16px;
403
+ background-color: #f5f5f5;
404
+ min-height: 100vh;
405
+ }
406
+
407
+ .header {
408
+ display: flex;
409
+ justify-content: space-between;
410
+ align-items: center;
411
+ margin-bottom: 16px;
412
+
413
+ h2 {
414
+ margin: 0;
415
+ font-size: 20px;
416
+ font-weight: bold;
417
+ color: #333;
418
+ }
419
+ }
420
+
421
+ .stats-card {
422
+ display: grid;
423
+ grid-template-columns: repeat(4, 1fr);
424
+ gap: 12px;
425
+ margin-bottom: 20px;
426
+
427
+ .stat-item {
428
+ background: #fff;
429
+ border-radius: 8px;
430
+ padding: 16px;
431
+ text-align: center;
432
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
433
+
434
+ .stat-label {
435
+ font-size: 12px;
436
+ color: #666;
437
+ margin-bottom: 8px;
438
+ }
439
+
440
+ .stat-value {
441
+ font-size: 24px;
442
+ font-weight: bold;
443
+ color: #1989fa;
444
+ }
445
+ }
446
+ }
447
+
448
+ .test-section {
449
+ background: #fff;
450
+ border-radius: 8px;
451
+ padding: 16px;
452
+ margin-bottom: 16px;
453
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
454
+
455
+ .section-title {
456
+ font-size: 16px;
457
+ font-weight: bold;
458
+ color: #333;
459
+ margin-bottom: 12px;
460
+ padding-bottom: 8px;
461
+ border-bottom: 1px solid #f0f0f0;
462
+ }
463
+
464
+ .button-group {
465
+ display: flex;
466
+ flex-direction: column;
467
+ gap: 8px;
468
+ }
469
+
470
+ .result-box {
471
+ margin-top: 16px;
472
+ padding: 12px;
473
+ background-color: #f8f9fa;
474
+ border-radius: 4px;
475
+ border: 1px solid #e9ecef;
476
+
477
+ .result-title {
478
+ font-size: 14px;
479
+ font-weight: 500;
480
+ color: #333;
481
+ margin-bottom: 8px;
482
+ }
483
+
484
+ .result-content {
485
+ margin: 0;
486
+ font-size: 12px;
487
+ color: #666;
488
+ white-space: pre-wrap;
489
+ word-break: break-all;
490
+ max-height: 200px;
491
+ overflow-y: auto;
492
+ }
493
+ }
494
+ }
495
+
496
+ .refresh-section {
497
+ margin-top: 20px;
498
+ margin-bottom: 20px;
499
+ }
500
+ </style>
501
+