2929 :style =" { left: loadingPosition.x + 'px', top: loadingPosition.y + 'px' }"
3030 />
3131 <div class =" loading-text" >正在生成关卡中...</div >
32+ <div class =" progress-container" >
33+ <el-progress
34+ :percentage =" generateProgress"
35+ :stroke-width =" 6"
36+ :show-text =" false"
37+ color =" #DAA520"
38+ />
39+ <div class =" progress-text" >{{ generateProgress }}%</div >
40+ </div >
3241 </div >
3342 </div >
3443 </el-card >
135144 :style =" { left: submitLoadingPosition.x + 'px', top: submitLoadingPosition.y + 'px' }"
136145 />
137146 <div class =" loading-text" >正在提交答案...</div >
147+ <div class =" progress-container" >
148+ <el-progress
149+ :percentage =" submitProgress"
150+ :stroke-width =" 6"
151+ :show-text =" false"
152+ color =" #DAA520"
153+ />
154+ <div class =" progress-text" >{{ submitProgress }}%</div >
155+ </div >
138156 </div >
139157 </div >
140158 </div >
@@ -170,17 +188,25 @@ const currentLevel = ref(null)
170188const selectedOptions = ref ([])
171189const draggedOption = ref (null )
172190
191+ // 进度条相关
192+ const generateProgress = ref (0 )
193+ const submitProgress = ref (0 )
194+ let generateProgressInterval = null
195+ let submitProgressInterval = null
196+
173197// 加载图标随机移动相关
174198const loadingPosition = ref ({ x: 0 , y: 0 })
175199const submitLoadingPosition = ref ({ x: 0 , y: 0 })
176200let loadingInterval = null
177201let submitLoadingInterval = null
178202
179203// 随机移动函数
180- const getRandomPosition = (containerWidth = 300 , containerHeight = 80 , iconSize = 40 ) => {
204+ const getRandomPosition = (containerWidth = 300 , containerHeight = 180 , iconSize = 40 ) => {
205+ // 限制图标在容器上半部分活动,避免与文案和进度条重叠
206+ const maxY = Math .min (containerHeight - 120 , 35 ) // 保留底部给文案和进度条
181207 return {
182- x: Math .random () * (containerWidth - iconSize),
183- y: Math .random () * (containerHeight - iconSize)
208+ x: Math .random () * (containerWidth - iconSize - 10 ) + 5 , // 左右留5px边距
209+ y: Math .random () * maxY + 5 // 上方留5px边距
184210 }
185211}
186212
@@ -192,8 +218,8 @@ const startRandomMovement = (positionRef, intervalRef) => {
192218
193219 // 根据屏幕大小调整容器尺寸
194220 const isMobile = window .innerWidth <= 768
195- const containerWidth = isMobile ? 210 : 260
196- const containerHeight = isMobile ? 30 : 40
221+ const containerWidth = isMobile ? 250 : 300
222+ const containerHeight = isMobile ? 160 : 180
197223 const iconSize = isMobile ? 35 : 40
198224
199225 // 初始位置
@@ -212,6 +238,41 @@ const stopRandomMovement = (intervalRef) => {
212238 }
213239}
214240
241+ // 进度条模拟逻辑
242+ const simulateProgress = (progressRef , type = ' generate' ) => {
243+ progressRef .value = 0
244+ let currentProgress = 0
245+
246+ return setInterval (() => {
247+ if (currentProgress < 30 ) {
248+ // 前30%:快速增长(模拟初始化)
249+ currentProgress += Math .random () * 8 + 3
250+ } else if (currentProgress < 60 ) {
251+ // 30%-60%:中等速度(模拟处理中)
252+ currentProgress += Math .random () * 4 + 2
253+ } else if (currentProgress < 85 ) {
254+ // 60%-85%:较慢速度(模拟深度处理)
255+ currentProgress += Math .random () * 2 + 1
256+ } else if (currentProgress < 99 ) {
257+ // 85%-99%:很慢速度(模拟最终处理)
258+ currentProgress += Math .random () * 0.5 + 0.2
259+ }
260+
261+ // 确保不超过99%,最后1%由实际完成时设置
262+ progressRef .value = Math .min (Math .floor (currentProgress), 99 )
263+ }, type === ' generate' ? 300 : 200 ) // 生成关卡稍慢,提交答案稍快
264+ }
265+
266+ const stopProgress = (intervalRef ) => {
267+ if (intervalRef) {
268+ clearInterval (intervalRef)
269+ }
270+ }
271+
272+ const completeProgress = (progressRef ) => {
273+ progressRef .value = 100
274+ }
275+
215276// 计算可用选项(排除已选择的)
216277const availableOptions = computed (() => {
217278 if (! currentLevel .value ? .options ) return []
@@ -259,16 +320,34 @@ const generateLevel = async () => {
259320 console .log (' 使用的薪资:' , userSalary)
260321
261322 generating .value = true
323+ // 启动进度条模拟
324+ generateProgressInterval = simulateProgress (generateProgress, ' generate' )
325+
262326 try {
263327 const levelData = await generateLevelAPI ({ salary: userSalary })
264328 currentLevel .value = levelData
265329 selectedOptions .value = []
266- ElMessage .success (' 关卡生成成功!' )
330+
331+ // 完成进度条
332+ completeProgress (generateProgress)
333+
334+ // 短暂延迟后显示成功消息,让用户看到100%
335+ setTimeout (() => {
336+ ElMessage .success (' 关卡生成成功!' )
337+ }, 200 )
267338 } catch (error) {
268339 console .error (' 生成关卡失败:' , error)
269340 ElMessage .error (' 生成关卡失败,请重试' )
270341 } finally {
271- generating .value = false
342+ // 清理进度条定时器
343+ stopProgress (generateProgressInterval)
344+ generateProgressInterval = null
345+
346+ // 延迟重置状态,让用户看到完成效果
347+ setTimeout (() => {
348+ generating .value = false
349+ generateProgress .value = 0
350+ }, 500 )
272351 }
273352}
274353
@@ -336,6 +415,9 @@ const submitAnswer = async () => {
336415 }
337416
338417 submitting .value = true
418+ // 启动进度条模拟
419+ submitProgressInterval = simulateProgress (submitProgress, ' submit' )
420+
339421 try {
340422 const submitData = {
341423 levelId: currentLevel .value .id ,
@@ -351,15 +433,28 @@ const submitAnswer = async () => {
351433 userStore .updateUserSalary (newSalary)
352434 }
353435
354- // 跳转到结果页面
355- console .log (' 准备跳转到结果页面:' , ` /result/${ result .id } ` )
356- router .push (` /result/${ result .id } ` )
436+ // 完成进度条
437+ completeProgress (submitProgress)
438+
439+ // 短暂延迟后跳转,让用户看到100%
440+ setTimeout (() => {
441+ console .log (' 准备跳转到结果页面:' , ` /result/${ result .id } ` )
442+ router .push (` /result/${ result .id } ` )
443+ }, 300 )
357444
358445 } catch (error) {
359446 console .error (' 提交答案失败:' , error)
360447 ElMessage .error (' 提交答案失败,请重试' )
361- } finally {
362- submitting .value = false
448+
449+ // 清理进度条定时器
450+ stopProgress (submitProgressInterval)
451+ submitProgressInterval = null
452+
453+ // 重置状态
454+ setTimeout (() => {
455+ submitting .value = false
456+ submitProgress .value = 0
457+ }, 300 )
363458 }
364459}
365460
@@ -376,6 +471,11 @@ watch(generating, (newVal) => {
376471 } else {
377472 stopRandomMovement (loadingInterval)
378473 loadingInterval = null
474+ // 确保进度条定时器也被清理
475+ if (generateProgressInterval) {
476+ stopProgress (generateProgressInterval)
477+ generateProgressInterval = null
478+ }
379479 }
380480})
381481
@@ -386,6 +486,11 @@ watch(submitting, (newVal) => {
386486 } else {
387487 stopRandomMovement (submitLoadingInterval)
388488 submitLoadingInterval = null
489+ // 确保进度条定时器也被清理
490+ if (submitProgressInterval) {
491+ stopProgress (submitProgressInterval)
492+ submitProgressInterval = null
493+ }
389494 }
390495})
391496
@@ -397,9 +502,11 @@ onMounted(() => {
397502})
398503
399504onUnmounted (() => {
400- // 组件销毁时清理定时器
505+ // 组件销毁时清理所有定时器
401506 stopRandomMovement (loadingInterval)
402507 stopRandomMovement (submitLoadingInterval)
508+ stopProgress (generateProgressInterval)
509+ stopProgress (submitProgressInterval)
403510})
404511< / script>
405512
@@ -605,7 +712,7 @@ onUnmounted(() => {
605712.custom - loading- area {
606713 position: relative;
607714 width: 300px ;
608- height: 80px ;
715+ height: 180px ;
609716 margin: 20px auto;
610717 border: 2px dashed var (-- border- medium);
611718 border- radius: 12px ;
@@ -619,17 +726,46 @@ onUnmounted(() => {
619726 height: 40px ;
620727 transition: all 0 .3s ease- in - out;
621728 z- index: 2 ;
729+ /* 限制图标活动范围,避免与文案和进度条重叠 */
730+ top: 5px ;
622731}
623732
624733.loading - text {
625734 position: absolute;
626- bottom: 5px ;
735+ bottom: 32px ;
627736 left: 50 % ;
628737 transform: translateX (- 50 % );
629738 color: var (-- text- secondary);
630739 font- size: 14px ;
631740 font- weight: 500 ;
741+ z- index: 3 ;
742+ background: var (-- bg- secondary);
743+ padding: 2px 8px ;
744+ border- radius: 4px ;
745+ }
746+
747+ /* 进度条容器 */
748+ .progress - container {
749+ position: absolute;
750+ bottom: 8px ;
751+ left: 20px ;
752+ right: 20px ;
632753 z- index: 1 ;
754+ display: flex;
755+ align- items: center;
756+ gap: 10px ;
757+ }
758+
759+ .progress - container .el - progress {
760+ flex: 1 ;
761+ }
762+
763+ .progress - text {
764+ color: var (-- text- secondary);
765+ font- size: 12px ;
766+ font- weight: 600 ;
767+ min- width: 30px ;
768+ text- align: right;
633769}
634770
635771.submit - loading {
@@ -656,12 +792,23 @@ onUnmounted(() => {
656792
657793 .custom - loading- area {
658794 width: 250px ;
659- height: 70px ;
795+ height: 80px ;
660796 }
661797
662798 .custom - loading- icon {
663799 width: 35px ;
664800 height: 35px ;
665801 }
802+
803+ .progress - container {
804+ left: 15px ;
805+ right: 15px ;
806+ gap: 8px ;
807+ }
808+
809+ .progress - text {
810+ font- size: 11px ;
811+ min- width: 28px ;
812+ }
666813}
667814< / style>
0 commit comments