DESKTOP-8FESTBI\Administrator 7ヶ月前
コミット
d01ab2998c
3個のファイルの変更144行の追加176行の削除
  1. 68
    27
      RuoYi-App/App.vue
  2. 7
    13
      RuoYi-App/pages/novel/list.vue
  3. 69
    136
      RuoYi-App/pages/novel/reader.vue

+ 68
- 27
RuoYi-App/App.vue ファイルの表示

@@ -1,18 +1,28 @@
1 1
 <template>
2 2
   <div id="app">
3
-    <!-- 顶部菜单栏 -->
4
-    <div v-if="showHeader" class="app-header">
5
-      <router-link to="/">首页</router-link>
6
-      <router-link to="/pages/novel/list">小说列表</router-link>
7
-      <router-link to="/pages/author/apply">作者申请</router-link>
8
-      <router-link to="/pages/search/index">搜索</router-link>
3
+    <!-- 错误边界 -->
4
+    <div v-if="hasError" class="error-boundary">
5
+      <h2>应用遇到问题</h2>
6
+      <p>{{ errorMessage }}</p>
7
+      <button @click="reloadApp">重新加载</button>
9 8
     </div>
10 9
     
11
-    <!-- 主内容区 -->
12
-    <router-view v-if="isRouterAlive" />
13
-    
14
-    <!-- 使用自定义TabBar组件 -->
15
-    <CustomTabbar v-if="showTabBar" />
10
+    <!-- 正常内容 -->
11
+    <div v-else>
12
+      <!-- 顶部菜单栏 -->
13
+      <div v-if="showHeader" class="app-header">
14
+        <router-link to="/">首页</router-link>
15
+        <router-link to="/pages/novel/list">小说列表</router-link>
16
+        <router-link to="/pages/author/apply">作者申请</router-link>
17
+        <router-link to="/pages/search/index">搜索</router-link>
18
+      </div>
19
+      
20
+      <!-- 主内容区 -->
21
+      <router-view v-if="isRouterAlive" />
22
+      
23
+      <!-- 使用自定义TabBar组件 -->
24
+      <CustomTabbar v-if="showTabBar" />
25
+    </div>
16 26
   </div>
17 27
 </template>
18 28
 
@@ -29,11 +39,12 @@ export default {
29 39
   components: { CustomTabbar },
30 40
   data() {
31 41
     return {
32
-      // 确保所有属性都在这里定义
42
+      hasError: false,
43
+      errorMessage: '',
33 44
       isRouterAlive: true,
34 45
       showTabBar: false,
35 46
       showHeader: false,
36
-      isMounted: false, // 添加组件挂载状态标志
47
+      isMounted: false,
37 48
       tabBarPages: [
38 49
         '/pages/index/index',
39 50
         '/pages/novel/list',
@@ -49,19 +60,11 @@ export default {
49 60
     }
50 61
   },
51 62
   mounted() {
52
-	    console.log('UniApp SDK版本:', uni.getSystemInfoSync().SDKVersion);
53
-	    console.log('平台:', uni.getSystemInfoSync().platform);
54
-	    console.log('UniApp API可用性检查:');
55
-	    console.log('navigateTo:', typeof uni.navigateTo);
56
-	    console.log('redirectTo:', typeof uni.redirectTo);
57
-	    console.log('switchTab:', typeof uni.switchTab);
58
-		  // 检查页面路径是否正确
59
-		  this.checkPagePaths();
60
-    this.isMounted = true;
63
+    console.log('UniApp SDK版本:', uni.getSystemInfoSync().SDKVersion);
64
+    console.log('平台:', uni.getSystemInfoSync().platform);
61 65
     
62
-    // 详细的环境检查
66
+    this.isMounted = true;
63 67
     this.checkEnvironment();
64
-    
65 68
     this.checkRouteAuth();
66 69
     this.initTheme();
67 70
     this.initStoreState();
@@ -78,11 +81,19 @@ export default {
78 81
       this.logError(event.reason);
79 82
     });
80 83
   },
84
+  errorCaptured(err, vm, info) {
85
+    // 捕获子组件错误
86
+    console.error('Error captured:', err, info);
87
+    this.hasError = true;
88
+    this.errorMessage = err.message;
89
+    
90
+    // 阻止错误继续向上传播
91
+    return false;
92
+  },
81 93
   beforeDestroy() {
82 94
     this.isMounted = false;
83 95
   },
84 96
   watch: {
85
-    // 安全监听路由变化
86 97
     '$route': {
87 98
       immediate: true,
88 99
       handler(newRoute) {
@@ -312,7 +323,13 @@ export default {
312 323
         this.safeUpdateMenuVisibility();
313 324
       });
314 325
     },
315
-    
326
+        reloadApp() {
327
+      this.hasError = false;
328
+      this.isRouterAlive = false;
329
+      this.$nextTick(() => {
330
+        this.isRouterAlive = true;
331
+      });
332
+    },
316 333
     safeUpdateMenuVisibility() {
317 334
       // 确保组件已挂载且路由对象存在
318 335
       if (!this.isMounted || !this.$route || !this.$route.path) return;
@@ -387,6 +404,30 @@ export default {
387 404
 @import '@/styles/index.scss';
388 405
 
389 406
 /* 全局样式修复 */
407
+.error-boundary {
408
+  display: flex;
409
+  flex-direction: column;
410
+  justify-content: center;
411
+  align-items: center;
412
+  height: 100vh;
413
+  text-align: center;
414
+  padding: 20px;
415
+  
416
+  h2 {
417
+    color: #f56c6c;
418
+    margin-bottom: 20px;
419
+  }
420
+  
421
+  button {
422
+    margin-top: 20px;
423
+    padding: 10px 20px;
424
+    background-color: #409eff;
425
+    color: white;
426
+    border: none;
427
+    border-radius: 4px;
428
+    cursor: pointer;
429
+  }
430
+}
390 431
 #app {
391 432
   min-height: 100vh;
392 433
   background-color: var(--bg-color);
@@ -449,4 +490,4 @@ uni-tabbar .uni-tabbar {
449 490
     }
450 491
   }
451 492
 }
452
-</style>
493
+</style>

+ 7
- 13
RuoYi-App/pages/novel/list.vue ファイルの表示

@@ -238,6 +238,7 @@ useVueRouterFallback(url) {
238 238
   }
239 239
 },
240 240
 // 在 list.vue 中修改 openNovel 方法
241
+// 在 list.vue 中修改 openNovel 方法
241 242
 openNovel(novel) {
242 243
   try {
243 244
     console.log('准备打开小说:', novel);
@@ -254,19 +255,12 @@ openNovel(novel) {
254 255
     
255 256
     console.log('跳转到阅读页面,小说ID:', novelId);
256 257
     
257
-    // 使用uni-app的标准导航方式
258
-    uni.navigateTo({
259
-      url: `/pages/novel/reader?novelId=${novelId}&chapterId=1`,
260
-      success: (res) => {
261
-        console.log('导航成功', res);
262
-      },
263
-      fail: (err) => {
264
-        console.error('导航失败', err);
265
-        // 备用导航方案
266
-        this.$router.push({
267
-          path: '/pages/novel/reader',
268
-          query: { novelId: novelId, chapterId: 1 }
269
-        });
258
+    // 使用若依框架的标准导航方式
259
+    this.$router.push({
260
+      path: '/pages/novel/reader',
261
+      query: { 
262
+        novelId: novelId,
263
+        chapterId: 1
270 264
       }
271 265
     });
272 266
   } catch (error) {

+ 69
- 136
RuoYi-App/pages/novel/reader.vue ファイルの表示

@@ -93,7 +93,6 @@
93 93
   </view>
94 94
 </template>
95 95
 
96
-
97 96
 <script>
98 97
 export default {
99 98
   data() {
@@ -102,7 +101,7 @@ export default {
102 101
       chapterId: '',
103 102
       novelTitle: '加载中...',
104 103
       chapterTitle: '加载中...',
105
-      content: '正在加载内容...', // 直接存储解码后的内容
104
+      content: '正在加载内容...',
106 105
       currentChapter: 1,
107 106
       totalChapters: 0,
108 107
       progress: 0,
@@ -130,28 +129,6 @@ export default {
130 129
       chapterList: []
131 130
     }
132 131
   },
133
-    // 添加所有生命周期钩子进行调试
134
-  beforeCreate() {
135
-    console.log('reader beforeCreate');
136
-  },
137
-    created() {
138
-    console.log('reader created');
139
-  },
140
-    beforeMount() {
141
-    console.log('reader beforeMount');
142
-  },
143
-    mounted() {
144
-    console.log('reader mounted');
145
-  },
146
-    onReady() {
147
-    console.log('reader onReady');
148
-  },
149
-    onHide() {
150
-    console.log('reader onHide');
151
-  },
152
-  onUnload() {
153
-    console.log('reader onUnload');
154
-  },
155 132
   onLoad(options) {
156 133
     console.log('阅读器页面加载,参数:', options);
157 134
     
@@ -159,6 +136,8 @@ export default {
159 136
     this.novelId = options.novelId || '';
160 137
     this.chapterId = options.chapterId || '1';
161 138
     
139
+    console.log('novelId:', this.novelId, 'chapterId:', this.chapterId);
140
+    
162 141
     if (!this.novelId) {
163 142
       console.error('小说ID参数缺失');
164 143
       this.error = '小说ID参数缺失';
@@ -178,144 +157,98 @@ export default {
178 157
     this.loadChapterContent();
179 158
   },
180 159
   onShow() {
160
+    console.log('reader onShow');
161
+    
181 162
     // 确保页面显示时也能处理参数
182 163
     const pages = getCurrentPages();
183 164
     const currentPage = pages[pages.length - 1];
184 165
     if (currentPage && currentPage.options) {
185 166
       const options = currentPage.options;
186
-      if (options.novelId && !this.novelId) {
167
+      console.log('当前页面参数:', options);
168
+      
169
+      if (options.novelId && (!this.novelId || this.novelId !== options.novelId)) {
187 170
         this.novelId = options.novelId;
188 171
         this.chapterId = options.chapterId || '1';
189 172
         this.loadChapterContent();
190 173
       }
191 174
     }
192 175
   },
176
+  // 添加所有生命周期钩子进行调试
177
+  beforeCreate() {
178
+    console.log('reader beforeCreate');
179
+  },
180
+  created() {
181
+    console.log('reader created');
182
+  },
183
+  beforeMount() {
184
+    console.log('reader beforeMount');
185
+  },
186
+  mounted() {
187
+    console.log('reader mounted');
188
+  },
189
+  onReady() {
190
+    console.log('reader onReady');
191
+  },
192
+  onHide() {
193
+    console.log('reader onHide');
194
+  },
195
+  onUnload() {
196
+    console.log('reader onUnload');
197
+  },
193 198
   methods: {
194 199
     async loadChapterContent() {
200
+      console.log('开始加载章节内容');
201
+      
195 202
       this.loading = true;
196 203
       this.error = null;
197 204
       
198 205
       try {
199 206
         console.log('开始请求章节内容,章节ID:', this.chapterId);
200 207
         
201
-        // 使用若依框架的API调用方式
202
-        const res = await this.$http.get(`/novel/chapter/${this.chapterId}`);
203
-        console.log('章节内容响应:', res);
204
-        
205
-        if (res.code === 200) {
206
-          this.novelTitle = res.data.novelTitle || '未知小说';
207
-          this.chapterTitle = res.data.chapterTitle || '未知章节';
208
-          
209
-          // 后台已经解码Base64,直接使用内容
210
-          this.content = res.data.content || '';
211
-          
212
-          // 设置章节信息
213
-          this.currentChapter = res.data.chapterIndex || 1;
214
-          this.totalChapters = res.data.totalChapters || 0;
215
-          
216
-          uni.showToast({
217
-            title: '加载成功',
218
-            icon: 'success',
219
-            duration: 1500
220
-          });
221
-        } else {
222
-          console.error('API返回错误状态码:', res.code);
223
-          this.error = '加载失败: ' + (res.msg || '未知错误');
224
-          uni.showToast({
225
-            title: res.msg || '加载失败',
226
-            icon: 'none'
227
-          });
228
-        }
229
-      } catch (error) {
230
-        console.error('加载章节内容失败:', error);
231
-        this.error = '加载失败,请检查网络连接';
232
-        uni.showToast({
233
-          title: '加载失败,请检查网络连接',
234
-          icon: 'none'
235
-        });
236
-      } finally {
237
-        this.loading = false;
238
-        uni.hideLoading();
239
-      }
240
-    },
241
-    
242
-    calculateProgress() {
243
-      // 简化进度计算
244
-      this.progress = Math.min(100, Math.round((this.lastScrollPosition / 1000) * 100));
245
-    },
246
-    
247
-    goBack() {
248
-      uni.navigateBack();
249
-    },
250
-    
251
-    prevChapter() {
252
-      if (this.currentChapter > 1) {
253
-        this.chapterId = parseInt(this.chapterId) - 1;
254
-        this.loadChapterContent();
255
-      } else {
256
-        uni.showToast({ title: '已经是第一章了', icon: 'none' });
257
-      }
258
-    },
259
-    
260
-    nextChapter() {
261
-      if (this.currentChapter < this.totalChapters) {
262
-        this.chapterId = parseInt(this.chapterId) + 1;
263
-        this.loadChapterContent();
264
-      } else {
265
-        uni.showToast({ title: '已经是最后一章了', icon: 'none' });
266
-      }
267
-    },
268
-    
269
-    selectChapter(chapterId) {
270
-      this.chapterId = chapterId;
271
-      this.showCatalogPanel = false;
272
-      this.loadChapterContent();
273
-    },
274
-    
275
-    showMenu() {
276
-      this.showHeader = !this.showHeader;
277
-      this.showFooter = !this.showFooter;
278
-    },
279
-    
280
-    showCatalog() {
281
-      this.showCatalogPanel = true;
282
-    },
283
-    
284
-    showFontSettings() {
285
-      this.showSettings = !this.showSettings;
286
-    },
287
-    
288
-    toggleNightMode() {
289
-      this.nightMode = !this.nightMode;
290
-      this.backgroundColor = this.nightMode ? '#1a1a1a' : '#f5f0e1';
291
-    },
292
-    
293
-    increaseFontSize() {
294
-      this.fontSize = Math.min(24, this.fontSize + 2);
295
-    },
296
-    
297
-    decreaseFontSize() {
298
-      this.fontSize = Math.max(14, this.fontSize - 2);
299
-    },
300
-    
301
-    changeBackground(color) {
302
-      this.backgroundColor = color;
303
-      this.nightMode = color === '#1a1a1a';
304
-    },
208
+    // 确保$http对象可用
209
+    if (!this.$http || typeof this.$http.get !== 'function') {
210
+      throw new Error('网络请求不可用');
211
+    }
305 212
     
306
-    setAdStrategy() {
307
-      const readChapters = uni.getStorageSync('readChapters') || 0;
308
-      this.showAd = readChapters > 0 && readChapters % 3 === 0;
309
-    },
213
+    // 使用若依框架的API调用方式
214
+    const res = await this.$http.get(`/novel/chapter/${this.chapterId}`);
215
+    console.log('章节内容响应:', res);
310 216
     
311
-    downloadChapter() {
312
-      // 下载本章内容供离线阅读
217
+    if (res.code === 200) {
218
+      this.novelTitle = res.data.novelTitle || '未知小说';
219
+      this.chapterTitle = res.data.chapterTitle || '未知章节';
220
+      this.content = res.data.content || '';
221
+      this.currentChapter = res.data.chapterIndex || 1;
222
+      this.totalChapters = res.data.totalChapters || 0;
223
+      
224
+      uni.showToast({
225
+        title: '加载成功',
226
+        icon: 'success',
227
+        duration: 1500
228
+      });
229
+    } else {
230
+      console.error('API返回错误状态码:', res.code);
231
+      this.error = '加载失败: ' + (res.msg || '未知错误');
232
+      uni.showToast({
233
+        title: res.msg || '加载失败',
234
+        icon: 'none'
235
+      });
313 236
     }
237
+  } catch (error) {
238
+    console.error('加载章节内容失败:', error);
239
+    this.error = '加载失败,请检查网络连接';
240
+    uni.showToast({
241
+      title: '加载失败,请检查网络连接',
242
+      icon: 'none'
243
+    });
244
+  } finally {
245
+    this.loading = false;
246
+    uni.hideLoading();
314 247
   }
315 248
 }
249
+}}
316 250
 </script>
317 251
 
318
-
319 252
 <style>
320 253
 .reader-container {
321 254
   position: relative;

読み込み中…
キャンセル
保存