年會抽獎程序,開箱即用

年末降至,各種年會都需用到抽獎,最近恰好寫了一個抽獎程序,總結一下,也爲了方便往後溫故,也可給諸位一個開箱即用的抽獎demo參考前端

demo演示連接

先睹爲快,傳送門git

完整代碼地址

傳送門github

流程圖

image

說明

  1. 公平抽獎,沒有暗箱操做,代碼經過功能測試、壓測,通過多人review,可放心開箱即用。
  2. 這個抽獎程序是上週公司抽獎實際使用的,可是代碼我隱去了跟公司相關的信息,因此UI上效果基本沒有,但只要稍做修改,如設計一張背景圖便可。
  3. 分辨率1920*1080效果最佳,但需考慮實際使用地方的屏幕設備
  4. 有抽獎中、中獎兩個音樂,須要鏈接音頻效果更佳
  5. 獎品信息能夠配置,一次抽獎能夠分若干小次進行,這裏抽獎暫時只按1桌/1次來,緣由:刪除/放回這裏須要優化一下
  6. 中獎後會將中獎人名單以及獎品信息寫入中獎記錄表,有頁面可查看,方便後面兌獎
  7. 暫時只放出抽桌號的代碼,其實將桌號的圖片換成員工頭像效果會更好,原還有一個簽到頁面,可簽到的人提早錄入了user表,只有簽到的人才在獎池中,這裏還有一個nestjs寫的後臺,代碼暫時沒有放出來,能夠私聊溝通。流程能夠參考
    image

核心代碼

關鍵節點有相應註釋,請仔細閱讀,歡迎指正不足json

//生成從minNum到maxNum的隨機數
randomNum(minNum, maxNum){
    return parseInt(Math.random()* (maxNum - minNum + 1) + minNum); 
},

//獎頭像動起來
doMove(start, end) {
    console.log('start, end', start, end );

    this.setIntervalFun = setInterval(() => {
        for(let i = start; i < end; i ++ ) {
            this.$set(this.currentPrizeUsers, i, this.keepNoRepeat(this.currentPrizeUsers, this.moveUsers));
        }
    }, 80) 
},

//保證數字不重複
keepNoRepeat(currentPrizeUsers, userNoPrize) {
  let user = userNoPrize[this.randomNum(0, userNoPrize.length)];

  //因爲分多小次抽獎,抽獎完成後獎池人數才變化,因此可能存在取值越界
  if(!user) {
    return this.keepNoRepeat(currentPrizeUsers, userNoPrize);
  }
  if(currentPrizeUsers.filter(item => item.userid == user.userid).length > 0) {
    return this.keepNoRepeat(currentPrizeUsers, userNoPrize);
  }else {
    return user;
  }
},

//停/繼續/完成點擊
handlePrizeClick: throttle(function() {
    //單次抽獎的最後一小次暫停
    if(this.movePrizeNum == this.currentPrizeInfo.count) {
        this.choujiangId.pause();
        this.zhongjiangId.play();
        clearInterval(this.setIntervalFun);
        this.movePrizeStatus = 2;
        this.movePrizeNum += 1;
        this.doPrize(this.currentPrizeUsers.filter(item => item.userid).map(item => item.userid).join(','));
        return;
    }

    if(this.movePrizeStatus == 2) {//顯示狀態-完成抽獎
        this.choujiangId.pause();
        this.zhongjiangId.pause();
        this.dialogTableVisible = false;
        this.movePrizeStatus = 0;
    }else if(this.movePrizeStatus == 3) {//再次啓動
        this.choujiangId.play();
        this.zhongjiangId.pause();
        this.movePrizeStatus = 1;
        this.doMove(this.movePrizeNum * this.currentPrizeInfo.everytime, this.currentPrizeInfo.everytime * (this.movePrizeNum + 1) );
        this.movePrizeNum += 1;
    }else if(this.movePrizeStatus == 1) {//暫停
        this.choujiangId.pause();
        this.zhongjiangId.play();
        clearInterval(this.setIntervalFun);
        this.movePrizeStatus = 3;
        this.doPrize(this.currentPrizeUsers.filter(item => item.userid).map(item => item.userid).join(','));
    }
}, 1000),

//洗牌
randomUser() {
    let randomUser = setInterval(() => {
        this.moveUsers = this.moveUsers.sort((a, b) => Math.random() > .5 ? -1 : 1);
    }, 100)
    setTimeout(() => {
        clearInterval(randomUser);
    }, 2000);
}

迭代思路(不足之處)

  1. 配置獎品信息應更豐富,單獨作一個後臺配置頁面,支持配置獎品圖片、抽獎個數、次數、音樂等等
  2. 將獎品配置信息用數據表管理,而不是json
  3. 抽獎歷史記錄應能夠回看,能夠刪除(做廢),同時刪除中獎記錄表
  4. 若是獎池人數足夠多(1w人以上),可能有性能問題,前端循環能夠持續優化
  5. 添加登陸/接口權限控制

後續考慮

  1. 空格鍵按暫停可能會更好操做,可是聲控呢?
  2. 洗牌效果作得更炫酷一些
相關文章
相關標籤/搜索