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.
- package/index.js +1 -0
- package/package.json +9 -0
- package//344/273/243/347/240/201/assets/common.css +10 -0
- package//344/273/243/347/240/201/components/FilterSortPanel.vue +183 -0
- package//344/273/243/347/240/201/components/card.vue +17 -0
- package//344/273/243/347/240/201/views/HomePage.vue +199 -0
- package//344/273/243/347/240/201/views/listPage.vue +95 -0
- package//344/273/243/347/240/201/views/officialPage.vue +326 -0
- package//344/273/243/347/240/201/views/searchPage.vue +257 -0
- package//345/212/237/350/203/275/344/273/243/347/240/201//345/211/215/347/253/257/347/233/221/346/216/247/errorLogPage.vue +410 -0
- package//345/212/237/350/203/275/344/273/243/347/240/201//345/211/215/347/253/257/347/233/221/346/216/247/errorMonitor.js +324 -0
- package//345/212/237/350/203/275/344/273/243/347/240/201//345/211/215/347/253/257/347/233/221/346/216/247/main.js +103 -0
- package//345/212/237/350/203/275/344/273/243/347/240/201//345/211/215/347/253/257/347/233/221/346/216/247/request.js +89 -0
- package//345/212/237/350/203/275/344/273/243/347/240/201//345/211/215/347/253/257/347/233/221/346/216/247/testError.vue +501 -0
- package//346/226/207/344/273/266/fitler.vue +455 -0
- package//346/226/207/344/273/266/useFilter.vue +110 -0
- package//346/226/207/344/273/266//345/217/257/351/205/215/347/275/256/347/247/273/345/212/250/345/210/227/350/241/250/346/236/266/345/255/220.vue +243 -0
|
@@ -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
|
+
|