最近好像有个奇葩说相关的话题上了热搜。不过,那些话题并不是我们这次的主题,我们更想聊聊辩论赛的“未来”。

说是“未来”,或许现在也同样适用。在疫情还未解除的情况下,很多线下活动都无法进行,辩论就是其中之一。不过已经有人将这个场景从线下搬到了线上。

我们 2019 年 RTC 创新编程挑战赛的三强之一,“辩之竹”团队实现了一套功能完整的辩论系统,能计时、在线辩论、裁判视频点评,还能统计票数等。而且,它已经应用于很多辩论比赛中。于是我们让“辩之竹”撰写分享了一下作品的初衷,还有核心功能的实现:

1.项目介绍

为解决传统辩论赛UI丑、各系统相互割裂、线下举办各类成本等问题,特开发此系统。该套系统完全体包括:

  • 可定制的赛事计时器

  • 赛程、评委和辩手 管理后台

  • 赛程查看和无纸化提交分数的小程序

  • 赛后即时点对点反馈个人表现的辩力提升系统

  • 远程裁决的视频会议部分

2.项目初心

作为一个大学生,我们经常在大学举办各类辩论赛,但是在当前的辩论赛事中,长期存在着五大问题,即如图:
image

  • 日程查看不直观

  • 计时器简陋不美观

  • 统计票数麻烦且不环保

  • 复盘数据获取困难

  • 优质裁判资源稀少

除了以上问题,其实我们也发现现在的辩论赛非常受限于场地的局限,就算同一学校的两支辩论队也要解决申请教室、邀请评委、宣传吸引观众等问题,更别说如果是两所学校,两个城市,甚至两个国家的辩论队之间要举办比赛了。所以也想着能否把辩论赛整体搬迁到线上进行,正好接触到声网Agora 的黑客松大赛,了解到 SDK 每个月有 10000 分钟的免费额度,也看下了他支撑的语言框架和 SDK 集成文档很丰富,于是就想着参赛做个作品,能帮助解决相关问题的同时,提升锻炼自己的技术水平。

3.解决日程观看不直观

日程展示一直是个问题。传统赛事中,日程展示通常都是以发送 PDF 的形式呈现,当参赛人员和观赛人员想要查看日程时,往往需要 [打开QQ->进入赛事群->点开群文件->打开PDF->人工寻找对应日期的日程]

就算完成了上述步骤,日程文件往往也是一个 字号小、信息繁复、不直观 的 PDF 文件。寻找一个日程很麻烦且不适。为了让参赛人员和观赛人员更直观的看到日程,特在小程序内设置此页面。

数据储存使用了微信的云开发,并设计了 Web 端的后台页面,利用微信提供的API进行小程序端和 Web 端的数据统一来在 Web 端添加日程。

Web 端数据发送部分代码:

//./web/admin-battle-add.php
//这里调用了我自己写的微信云开发简易SDK,可以在源码中./web部分/lib/WeChat.php找到。具体信息可以在本文后部分具体介绍中找到。
else if($motion=="addBattle"){
    $title   = $_POST["title"];
    $loc     = $_POST["loc"];
    $time    = $_POST["time"];
    $teamClaimId = $_POST["teamClaimId"];
    $teamCounterClaimId = $_POST["teamCounterClaimId"];
    $res = $wx->databaseAdd("db.collection(\"battle\").add({data:{env:\"{$GLOBALS["env"]}\",title:\"{$title}\",status:\"0\",loc:\"{$loc}\",time:\"{$time}\",data:{teamClaim:{Id:\"{$teamClaimId}\",point:\"\"},teamCounterClaim:{Id:\"{$teamCounterClaimId}\",point:\"\"}}}})");
    redirect("./admin-battle-query.php?id=".$res["id_list"][0]);
}

小程序部分代码:

//./小程序部分/Bam1/client/src/pages/schedule/schedule.js
componentWillMount () {
    let {env} = this.$router.params;
    Taro.setNavigationBarTitle({title:this.$router.params.cName});
    Taro.setStorageSync("env",env);
    let p = this;
    let skpD = 0;
    Taro.cloud.database({env:"factory-1"}).collection("other").where({
        env: Taro.getStorageSync("env"),
        isSkpD : true
    }).get({
        success: res1 => {
        skpD = res1.data[0].skpD;
        Taro.cloud.database({env:"factory-1"}).collection("battle").where({env: Taro.getStorageSync("env")}).skip(skpD).limit(12).get({
            success:function (res) {
            let idL = p.state.idList;
            res.data.map((item,index)=>{
                idL.push(item._id);
            });
            p.setState({
                idList: idL
            })
...
}

备注:

  • 小程序部分,./Wechat Mini Program/Bam1/client/src/pages/schedule/schedule.js这部分代码主要是调用微信云开发的相关函数获取比赛 ID 列表。
  • 在这个文件外,./Wechat Mini Program/Bam1/client/src/components/battle/battle.js 是每一个日程 card 的组件。通过 schedule 文件向内传入 ID 参数,在 battle component 内获取数据。
  • 这里存在一个并不合理的获取数据方式。我后来思考,在主界面一次性获取所有数据后,将数据交由 battle component 渲染应该可以得到更高的性能。但是当时时间有限,就没有修改。

4.解决计时器简陋不美观

其次,计时器的不美观问题,传统计时器如图:


显然,这种计时器与任何现代的设计思维都背道而驰,完全无美感可言。我找朋友为我设计了计时器的页面,并利用 HTML + JavaScript 实现其功能。计时器展示如图:

JS 的主要实现部分在 ./web/admin-battle-add.php

该计时器主要实现了如下功能:

  • 辩手姓名、图片展示

  • 键盘操控

  • 自定义环节

由于使用 HTML 开发,它有相比 exe 的更高跨平台能力。

5.解决统计票数问题

同时,响应无纸化潮流,我还设计了无纸化提交分数的裁判系统。它的另一个好处是避免了人工计算分数,防止人为误差的出现 + 计算分数的等待。
文件在:./Wechat Mini Program/Bam1/client/src/pages/user/judge.js

 


裁判界面的环节是与计时器同步的。


这里为了防止数据丢失,还使用 Taro.setStorageSync(),在每一次写完数据后,将数据存入临时数据。同样,当全部写入完毕,再使用微信云开发提交到服务器。