工作记录(五)——竞赛模块前端用户部分实现

工作记录(五):竞赛模块前端逻辑实现以及页面实现,包括竞赛主页和竞赛答题页

本次开发聚焦于竞赛模块的主要页面与核心交互逻辑,包括比赛列表、比赛进行、比赛结果等功能。通过细致的状态管理、动画设计和数据可视化,提升了整体用户体验和系统可维护性。


一、ContestsView.vue 比赛列表页面

1. 页面状态管理

比赛列表页面采用Vue 3的响应式系统,通过ref定义dataList和total来存储比赛数据和总数。searchParams对象用于管理搜索条件和分页信息,便于灵活地处理数据加载和展示。页面加载时会根据这些参数自动请求数据并更新视图。

为了让比赛时长更直观,定义了makeHoursMinutes函数,将比赛时长(秒)转换为“小时分钟”格式。该函数会先计算小时数,再判断是否有剩余分钟,最终拼接成友好的字符串,便于用户快速理解比赛持续时间。

  let hours = Math.floor(duration / 3600);
  let minutes = Math.floor((duration % 3600) / 60);
  return hours ? `${hours}小时${minutes ? " " + minutes + "分" : ""}` : `${minutes}`;
}

2. 比赛状态判断

比赛状态判断通过比较当前时间与比赛的开始/结束时间,动态决定比赛的可操作性。isBegin函数会判断当前时间是否晚于比赛开始时间,isEnd函数会判断当前时间是否晚于比赛结束时间。这些状态用于控制用户可执行的操作,比如未开始的比赛不能进入答题,已结束的比赛只能查看结果,保证了操作的准确性和安全性。

function isBegin(record) {
  // 当前时间大于开始时间则比赛已开始
}
function isEnd(record) {
  // 当前时间大于等于结束时间则比赛已结束
}

3. 奖杯与动画效果

奖杯区域采用了多种CSS动画提升视觉体验。文字动画通过关键帧实现上下浮动和缩放,配合渐变色背景和文字裁剪,营造出活泼的氛围。彩带使用SVG路径和旋转动画,左右对称地摆动,增强了节日感。奖杯本身结合了上下浮动、缩放和左右摇摆,配合阴影和变换原点,整体更具立体感和动感。这些动画通过CSS的@keyframes和transform属性实现,提升了页面的趣味性和吸引力。

@keyframes textFloat { /* 文字上下浮动和缩放 */ }
@keyframes waveLeft { /* 左彩带左右摇摆 */ }
@keyframes waveRight { /* 右彩带左右摇摆 */ }
@keyframes trophyAnimation { /* 奖杯上下浮动和旋转 */ }

在这里插入图片描述


二、DoContestView.vue 比赛进行页面

1. 比赛状态管理

比赛进行页需要管理多种状态,包括当前比赛信息、题目列表、剩余时间、比赛结果、通过题目统计以及代码提交表单。所有状态均采用ref响应式管理,确保页面数据和交互的实时同步。这样可以在比赛过程中动态更新题目、剩余时间和用户提交的代码,保证了比赛流程的流畅性。


2. 倒计时系统实现

倒计时系统通过与后端服务协作,支持获取剩余时间和启动新的倒计时。比赛开始时会自动调用后端接口获取剩余时间,如果没有则主动启动倒计时并设置初始值。前端会定时刷新剩余时间,确保用户始终看到准确的倒计时信息。时间结束后,系统会自动提交试卷,保证比赛的公平性和准确性。

async function getRemainingTime(duration) {
  // 先尝试从后端获取剩余时间
  const res = await 后端获取剩余时间();
  if (res成功) {
    剩余时间 = res.data;
  } else {
    // 获取不到则通知后端启动倒计时,并本地设置初始值
    await 启动后端倒计时(duration);
    剩余时间 = duration;
  }
}

async function startCountDown(duration) {
  // 通知后端启动倒计时
  await 后端启动倒计时(duration);
}

3. 代码提交与评判

用户提交代码后,系统会将代码和题目ID发送到后端评判服务。提交成功后,前端会自动刷新比赛结果和题目通过情况,并根据评判结果给予用户即时反馈(如题目变绿色、弹窗提示等)。整个流程保证了评判的及时性和用户体验,用户可以清楚地知道自己的提交是否通过。

    // 反馈信息
      message.success("运行完成,代码正确");
      message.error("运行错误,代码或者算法存在问题,请仔细检查");
      message.error("运行失败,可能是服务器缘故,请联系工作人员" + res.message);

在这里插入图片描述


三、ContestResultView.vue 比赛结果页面

1. 排名与奖励

比赛结果页通过计算每个选手的排名,并根据排名动态分配积分奖励。前三名有特殊的积分和样式,前十名有额外激励,其他参赛者也能获得基础积分。getRank函数根据当前分页和行号计算实际排名,getReword函数根据排名分配不同的积分奖励,getRankClass函数为不同排名提供独特的样式类名,配合CSS实现了醒目的视觉效果,对前三名选手的特殊样式处理。

function getRankClass(rowIndex) {
  // 返回不同排名的样式
  const rank = getRank(rowIndex);
  if (rank === 1) return 'rank-first';
  if (rank === 2) return 'rank-second';
  if (rank === 3) return 'rank-third';
  return '';
}

2. 成绩展示组件

每个选手的每道题成绩以卡片形式展示,包含分数和耗时。getQuestionScore和getQuestionConsume函数分别获取题目的得分和耗时信息。特别设计了perfect-score样式类,当选手获得满分时会触发特殊的视觉效果。时间消耗的显示帮助评估解题效率,为同分情况下的排名提供参考依据。

function getQuestionScore(record, column) {
  // 通过列信息确定题目索引,然后返回该题目的分数
  题目索引 = 由column信息推算得到
  return record.题目分数列表[题目索引]?.score
}

function getQuestionConsume(record, column) {
  // 通过列信息确定题目索引,然后返回该题目的耗时
  题目索引 = 由column信息推算得到
  return record.题目分数列表[题目索引]?.consume
}

在这里插入图片描述


四、总结

本次开发实现了竞赛模块的主要页面和核心交互逻辑。通过响应式状态管理、前后端协同的倒计时与评判流程、丰富的动画效果和数据可视化,极大提升了系统的易用性和美观度。在实践中,我进一步掌握了复杂页面状态的组织方法、动画与交互的性能优化技巧,以及数据驱动的可视化设计思路,为后续功能扩展和用户体验提升打下了坚实基础。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值