掘金可视化智能抽奖升级版

536 阅读3分钟

前言

前端时间看到大佬云的世界出了一个掘金抽奖可视化插件(本人使用的油猴),觉得很有意思,copy一下代码,接入进来,使用了几天,感觉非常棒,研究了一下,改了点样式,增加了一些功能

已发布到油猴地址

话不多说,直接看效果 image.png

增加功能如下:

  • 签到,成功后提示连续签到天数和累计签到天数
  • 显示矿石数量和可抽奖次数
  • 优化样式

有兴趣的朋友可以再次优化,附上代码

// ==UserScript==
// @name         掘金签到+可视化智能抽奖
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       凡繁烦
// @icon         https://www.google.com/s2/favicons?domain=juejin.cn
// @grant        none
// @include      https://juejin.cn/*
// ==/UserScript==

(function() {
    'use strict';

    console.log("游猴脚本:掘金自动签到+可视化智能抽奖");

    const styleContent = `
    ._jj_draw_container {
        position:fixed;
        top: 80px;
        right: 0;
        z-index: 9999;
        background-color: rgba(0,0,0,0.6);
        padding: 20px;
    }
        ._jj_button {
            padding: 6px;
            background-color: #1e80ff;
            color: #fff;
            border-radius: 4px;
            text-align: center;
            vertical-align: middle;
            border: 1px solid transparent;
            font-weight: 700;
            letter-spacing: 1em;
            text-indent: 1em;
            cursor: pointer;
        }
        ._jj_btn_sign_in{
            background-color:#e8f3ff !important;
            color:#1e80ff !important;
        }
        ._jj_button:hover {
            opacity: 0.8;
        }
        table._jj_hovertable thead {
            text-align: center;
            font-size: 16px;
            font-weight: 700;
            color:#333;
        }
        table._jj_hovertable {
            font-family: verdana, arial, sans-serif;
            font-size: 11px;
            color: #d25f00;
            border-width: 1px;
            border-color: #999999;
            border-collapse: collapse;
        }
        table._jj_hovertable th {
            background-color: #c3dde0;
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #a9c6c9;
        }
        table._jj_hovertable tr {
            background-color: #fff;
        }
        table._jj_hovertable td {
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #a9c6c9;
        }
        ._jj_button_close{
            font-size: 20px;
            font-weight: 700;
            color: #FFF;
        }
        .__jj_dialog_title{
            display: flex;
        }
        .__jj_dialog_title_left{
            flex:1;
            font-size: 14px;
            color: #fff;
        }
        .__jj_dialog_title_left span{
            color: #1e80ff;
            font-size:20px;
            font-weight: 700;
        }
        .__jj_dialog_title_right{
            width: 30px;
        }

    `;


    const htmlContent = `
    <div class="">
        <div class="__jj_dialog_title">
            <div class="__jj_dialog_title_left" id="__jj_dialog_title_left" style="visibility:hidden;">矿石<span id="ore_num">0</span>个 | 可抽奖<span id="draws_num">0</span>次</div>
            <div class="__jj_dialog_title_right">
            <a href="javascript:void(0)" id="_jj_btn_close" class="_jj_button_close">X</a>
            </div>
        </div>
        <div style="text-align:center;margin: 10px;">
            <button id="_jj_btn_sign_in" type="button" class="_jj_button _jj_btn_sign_in">签到</button>
            <button id="_jj_btn_draw" type="button" class="_jj_button _jj_btn_draw">抽奖</button>
            <button id="_jj_btn_stop" type="button" class="_jj_button">停止</button>
            
        </div>
        <table class="_jj_hovertable">
            <thead>
                <tr>
                    <td>奖品图标</td>
                    <td>奖品名称</td>
                    <td>中奖次数</td>
                    <td>累计奖励</td>
                </tr>
            <tbody id="_jj_tbodyList">
            </tbody>
            </thead>
        </table>
    </div>
    `

    function appendStyle(text) {
        const styleEl = document.createElement('style');
        styleEl.textContent = text;
        document.head.appendChild(styleEl);
    }

    function appendHTML(htmlContent) {
        const htmlEl = document.createElement('div');
        htmlEl.id = "_jj_draw_container";
        htmlEl.className = "_jj_draw_container";
        htmlEl.innerHTML = htmlContent;
        document.body.appendChild(htmlEl);
        getCurPoint();
    }

    appendStyle(styleContent);
    appendHTML(htmlContent);

    let lotteryConfig = [];
    let isDrawing = false;
    let prizes = [];
    const tbodyListEl = document.getElementById("_jj_tbodyList")

    function delay(fn = () => { }, delay = 5000, context = null) {
        let ticket = null;
        let runned = false;
        return {
            run(...args) {
                return new Promise((resolve, reject) => {
                    if (runned === true) {
                        return;
                    }
                    runned = true;
                    ticket = setTimeout(async () => {
                        try {
                            const res = await fn.apply(context, args);
                            resolve(res);
                        } catch (err) {
                            reject(err)
                        }
                    }, delay)
                })
            },
            cancel: () => {
                clearTimeout(ticket);
            }
        }
    }

    function getLotteryConfig() {
        return fetch("https://api.juejin.cn/growth_api/v1/lottery_config/get")
            .then(res => res.json())
    }

    function getSignCount(){
        return fetch('https://api.juejin.cn/growth_api/v1/get_counts?aid=2608&uuid=6986922219256989198',{
            method: 'GET',
            credentials: "include"
        }).then(res => res.json())
    }

    function getCurPoint(){
        return fetch('https://api.juejin.cn/growth_api/v1/get_cur_point?aid=2608&uuid=6986922219256989198',{
            method: 'GET',
            credentials: "include"
        }).then(res => res.json()).then(data=>{
            document.getElementById("ore_num").innerText = data.data;
            document.getElementById("draws_num").innerText = Math.floor(data.data/200);
            document.getElementById("__jj_dialog_title_left").style.visibility='visible';
        })
    }

    function onSignIn() {
        return fetch('https://api.juejin.cn/growth_api/v1/check_in',{
            method: 'POST',
            credentials: "include",
            headers: {
                'Content-Type': 'application/json;charset=utf-8;'
            },
            body: JSON.stringify({aid: '2608',uuid:'6986922219256989198'})
        }).then(res => res.json()).then(data=>{
            if(data.err_no!==0){
                alert(data.err_msg);
            }else{
                onSuccess();
            }
        })
    }

    async function onSuccess(){
        const count = await getSignCount();
        getCurPoint();
        console.log(count)
        alert(`签到成功,连续签到${count.data.cont_count}天,累计签到${count.data.sum_count}`);
    }

    // {"err_no":7003,"err_msg":"积分不足,无法进行抽奖lack of point","data":null}
    function doDraw() {
        return fetch('https://api.juejin.cn/growth_api/v1/lottery/draw', {
            method: 'POST',
            credentials: "include"
        }).then(res => res.json())
    }


    async function onDraw(ev) {
        if (isDrawing) {
            return;
        }
        isDrawing = true;

        try {
            let errNo = 0;
            do {
                if(!isDrawing){
                    break;
                }

                const res = await doDraw();
                getCurPoint();
                errNo = res.err_no;

                if (errNo !== 0) {
                    alert(res.err_msg);
                    isDrawing = false;
                    break;
                }

                // 增加奖励
                addPrize(res.data)
                // 渲染
                renderPrizes();
                // 暂停16ms
                await delay(undefined, 16).run();

                //isDrawing = false;
                //break;

            } while (errNo == 0)

        } catch (err) {
            isDrawing = false
            alert(err.message);
        }
    }

    function addPrize(data) {

        let prize = prizes.find(p => p.lottery_id == data.lottery_id);
        if(!prize) {
            return;
        }
        prize.counts += 1;

    }

    function onStop() {
        isDrawing = false;
    }

    function getTotal(data){
        if(data.lottery_id == "6981716980386496552" || data.lottery_name == "66矿石"){
            return data.counts * 66;
        }
        return data.counts;
    }

    function renderPrizes() {
        tbodyListEl.innerHTML = prizes.map(prize => `
        <tr id="_jj_${prize.lottery_id}">
            <td class="_jj_price_icon"><img style="height:30px" src="${prize.lottery_image}" /></td>
            <td>${prize.lottery_name}</td>
            <td class="_jj_count">${prize.counts}</td>
            <td class="_jj_total">${getTotal(prize)}</td>
        </tr>
    `).join("");

    }


    async function init() {
        lotteryConfig = (await getLotteryConfig()).data.lottery;

        prizes = lotteryConfig.map(c => ({
            lottery_id: c.lottery_id,
            lottery_name: c.lottery_name,
            lottery_image: c.lottery_image,
            counts: 0
        }));

        renderPrizes();
        document.getElementById("_jj_btn_sign_in").addEventListener("click",onSignIn)
        document.getElementById("_jj_btn_draw").addEventListener("click", onDraw);
        document.getElementById("_jj_btn_stop").addEventListener("click", onStop);
        document.getElementById("_jj_btn_close").addEventListener("click", function () {
            document.querySelector("#_jj_draw_container").style.display = "none"
        });
    }
    init();
})();

写在最后

如果说我看得比别人更远些,那是因为我站在巨人的肩膀上
感谢大佬云的世界提供灵感,附上原文

最后再给自己打个广告:凡繁烦个人博客网站