sysu-gym

中山大学体育场馆管理与预定系统助手

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         sysu-gym
// @namespace    sysu-gym
// @version      1.0
// @description  中山大学体育场馆管理与预定系统助手
// @author       Oahiakgnol
// @match        *://gym.sysu.edu.cn/*
// @run-at       document-end
// ==/UserScript==


(function () {
    'use strict';
    var pageurl = window.location.href;
    var $ = unsafeWindow.$;
    // 引用原页面JS函数 START
    var cleanChose = unsafeWindow.cleanChose;
    var initDay = unsafeWindow.initDay;
    var info = unsafeWindow.info;
    var cu = unsafeWindow.cu;
    var warning1 = unsafeWindow.warning1;
    var error = unsafeWindow.error;
    var setTimeout = unsafeWindow.setTimeout;
    var closeedwin = unsafeWindow.closeedwin;
    // 引用原页面JS函数 END
    // 提供数字宽度补齐,日期格式不对会无法加载
    function pad(num, n) {
        var len = num.toString().length;
        while (len < n) {
            num = "0" + num;
            len++;
        }
        return num;
    }
    // 网址正则
    var reg_product = /[http|https]*?:\/\/gym.sysu.edu.cn\/product\/show.html\?id=(\d+)/;
    var reg_order = /[http|https]*?:\/\/gym.sysu.edu.cn\/order\/show.html\?id=(\d+)/;
    // 特定类型的场地预定才可用
    var button = $('#reserve');
    if (reg_product.test(pageurl) && ($('div#seatshow').length==1)) {
        // 6:00-22:00之外时段订场会被限制, 但只是前端js做了按钮隐藏, 如果存在该情况则恢复按钮
        if (button.hasClass('button-disable')){
            closeedwin();
            button.attr('onclick', 'applySeat();');
            button.removeClass('button-disable');
            button.removeAttr('style');
        }
        $('script:contains("再来预订")').remove()
        // 添加加载任意日期按钮
        $($(".boxes")[2]).append(
            "<style>#loadanydate > button {width: 200px;height: 30px;color:white;background-color:cornflowerblue;border-radius: 3px;border-width: 0;margin: 0;outline: none;font-size: 16px;text-align:center;cursor: pointer;}#loadanydate > button :hover{background-color: antiquewhite;}</style><a style='display:block;float:right' id='loadanydate'><button style='width:150px;height=200px'>加载库存日历</button></a>"
        );
        // 为按钮绑定函数
        $('#loadanydate').click(
            function () {
                // 获取选中日期
                var date = new Date($(".calendar-selected").attr("abbr").split(",").join("-"));
                // 看看是否已经加载过该日期
                var datelist = $('.date');
                for (var i = 0; i < datelist.length; i++) {
                    var itemDate = new Date(datelist[i].innerText);
                    if ((!($(datelist[i]).parent().attr('id') == 'anyDateLoader') & itemDate.getTime() > date.getTime()) || (itemDate.getTime() == date.getTime())) {
                        console.log(`日期 ${date} 已存在`);
                        info('请在库存日历中正确选择还未加载的未来日期');
                        return;
                    }
                }
                // 删除可能存在的自创建的li元素
                $('#anyDateLoader').remove();
                // 构建日期的li元素
                var li = document.createElement("li");
                var weekdayList = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
                var yearString = pad(date.getFullYear(), 4);
                var monthString = pad(date.getMonth() + 1, 2);
                var dayString = pad(date.getDate(), 2);
                var dateString = yearString + "-" + monthString + "-" + dayString;
                var indexString = $(".date-week").find("li").length + 1 + "";
                var weekdayString = weekdayList[date.getDay()];
                li.setAttribute("data-year", yearString);
                li.setAttribute("data-month", monthString);
                li.setAttribute("data-day", dayString);
                li.setAttribute("data-week", weekdayString);
                li.setAttribute("data", dateString);
                li.setAttribute("class", "");
                li.setAttribute("id", "anyDateLoader");
                // 自己创建的标签靠右突出显示
                li.setAttribute("style", "float:right");

                var divWeek = document.createElement("div");
                divWeek.setAttribute("class", "week");
                divWeek.innerText = weekdayString;

                var divStock = document.createElement("div");
                divStock.setAttribute("class", "stock");
                divStock.setAttribute("style", "background: linear-gradient(to right, red, blue);-webkit-background-clip: text;color: transparent;font-size:15px");
                divStock.innerText = "自选日期";

                var divDate = document.createElement("div");
                divDate.setAttribute("class", "date");
                divDate.innerText = dateString;

                li.appendChild(divWeek);
                li.appendChild(divStock);
                li.appendChild(divDate);
                // 调宽ul标签不然被遮挡
                $('ul.dates-list').attr('style', 'width:965px');
                // 把创建的标签附上原网页
                $('ul.dates-list').append(li);

                // 为新建的标签绑定响应函数
                $('#anyDateLoader').click(
                    function () {
                        var myli = $('#anyDateLoader')
                        if (myli.hasClass('active')) {
                            return false;
                        }
                        // 移除其他并添加自身选中高亮
                        myli.parent().children().removeClass("active");
                        myli.addClass("active");
                        // 设置订场信息展示处
                        var datestr = myli.attr('data');
                        var date = new Date(datestr);
                        var weekdayList = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
                        $("#orderdate").html(`${datestr.slice(0, 4)}年${datestr.slice(5, 7)}月${datestr.slice(8, 10)}日  ${weekdayList[date.getDay()]}`);
                        // 初始化场地
                        cleanChose();
                        initDay(datestr);
                        // 无用效果
                        $("li#anyDateLoader").animate({ marginRight: "+=20px" }, 250);
                        $("li#anyDateLoader").animate({ marginRight: "-=20px" }, 250);
                    }
                )
                $('#anyDateLoader').click();
            }
        )
        // 绑定之后预加载
        var latestdate = new Date($('.date')[$('.date').length - 1].innerText);
        var nextdate = new Date(latestdate.getTime() + 24 * 60 * 60 * 1000);
        var nextdatestr = nextdate.getFullYear() + ',' + (nextdate.getMonth() + 1) + ',' + nextdate.getDate();
        $('td.calendar-day').each(
            function (index, ele) {
                if (ele.abbr == nextdatestr) {
                    $('td.calendar-selected').removeClass('calendar-selected');
                    $(ele).addClass('calendar-selected');
                }
            }
        )
        $('#loadanydate').click()
        // 突破每日最多预定场数限制
        $(document).keydown(
            function (e) {
                if (e.ctrlKey && e.keyCode == 13) {
                    var val = prompt("【隐藏项】突破最大预定场数限制,输入最大值:", 2);
                    val = parseInt(val, 10);
                    if (val > 0) {
                        $('#advancenum').attr('value', val);
                        console.log(`日最大订场数限制被用户修改为:${val}`);
                    }
                }
            }
        )
        // 同步更新applySeat函数
        unsafeWindow.applySeat = function applySeat() {
            var num = Number($("#sum").text());
            if (num > 0) {

                if ($("#cr").length > 0) {
                    if (!$("#cr").is(":checked")) {
                        info('请阅读说明后预订!');
                        return false;
                    }
                }

                var model = {};
                if ($("#shoptype").find(".active").data('type') == 'day') {
                    var stock = {};
                    var seatid = [];
  -                 $('#seatshow').find('.ticket-auto').each(function (i, k) {
                        seatid.push($(k).attr('data-did'));
                        stock[$(k).attr('data-stockid')] = (stock[$(k).attr('data-stockid')] == null ? 1 : Number(stock[$(k).attr('data-stockid')]) + 1) + '';
                    })
                    model.stock = stock;
                    model.istimes = '1';
                    model.stockdetailids = seatid.join(',');
                } else {
                    model.dates = $('#yd_date').val();
                    var time_detailname = [];
                    $('#seatshow').find('.ticket-auto').each(function (i, k) {
                        time_detailname.push($(k).data('timer') + '_' + $(k).data('dname'));
                    })
                    model.time_detailnames = time_detailname.join(',');
                    if ($("#shoptype").find(".active").data('type') == 'month') {
                        model.flag = '1';
                    } else {
                        model.flag = '2';
                    }
                    model.serviceid = $('#serviceid').val();
                }

                if ($("#shoptype").find(".active").data('type') == 'day') {

                    var param = {};
                    param.serviceid = $('#serviceid').val();
                    param.num = seatid.length;
                    param.date = $('.date-week').find('li.active').attr('data');
                    unsafeWindow.AjaxGet('/order/booklimt', param, function (o) {
                        $('#param').val(JSON.stringify(model));
                        $('#form1').submit();
                    }, 'json');
                } else {
                    $('#param').val(JSON.stringify(model));
                    $('#form1').submit();
                }
            } else {
                info("请选择需要预订的" + unsafeWindow.typename + "信息!");
            }
        }

        setTimeout('$("a[rel=shopping]").click();', 10);
    }

    if (reg_order.test(pageurl)) {
        if (button.hasClass('button-disable')){
            closeedwin();
            button.attr('onclick', 'goonreserve();event.returnValue=false;');
            button.removeClass('button-disable');
            button.removeClass('normal-button-mid');
            button.removeAttr('style');
        }
        // 添加付款方式选项
        $($("div.action-btn")[0]).prepend("<p align='center' id='tryinfo' retry='true' ncalls='0' interval='1000' style='font-family:verdana;font-size:150%'></p><label><input name='payment' type='radio' value='0' checked='true' />&nbsp;&nbsp;自动支付(运动金)&nbsp;&nbsp;</label><label><input name='payment' type='radio' value='1' />&nbsp;&nbsp;手动支付&nbsp;&nbsp;</label>");
        // 绑定延迟设置按键
        $(document).keydown(
            function (e) {
                if (e.ctrlKey && e.keyCode == 13) {
                    var val = prompt("【隐藏项】设置刷新间隔,单位毫秒 (别太过分,最低500):", 1000);
                    val = parseInt(val, 10);
                    if (val >= 500) {
                        $('#tryinfo').attr('interval', val);
                    }
                }
            }
        )
        // 每次刷新该页面重置 ncalls 记录goonreserve调用次数
        $('#tryinfo').attr('ncalls', 0);
        $('#tryinfo').attr('retry', false);

        // 重写goonreserve方法
        unsafeWindow.goonreserve = function () {
            // 记录调用次数
            var ncalls = parseInt($('#tryinfo').attr('ncalls') == undefined ? 0 : $('#tryinfo').attr('ncalls'));
            ncalls = ncalls + 1;
            $('#tryinfo').attr('ncalls', ncalls);
            // 如果是第一次调用,处理以下事项
            if (ncalls == 1) {
                // 默认遇到未开放的场地继续刷新
                $('#tryinfo').attr('retry', true);
                // 自动刷新的时候限制订场按钮的点击功能,改为取消
                $("#reserve").attr('onclick', "");
                $("#reserve").text('取消刷新');
                $("#reserve").click(
                    function () {
                        $('#tryinfo').attr('retry', false);
                        $("#reserve").text('确认预定');
                        $("#reserve").unbind('click');
                        $("#reserve").attr('onclick', "goonreserve();event.returnValue=false;");
                        // 重置颜色
                        $("table").find("td,th").each(function (index, element) { element.removeAttribute("style") });
                        // 清除信息
                        $('#tryinfo').text("")
                    }
                )
            }

            // post数据
            if (unsafeWindow._param != 'undefined') {
                if (unsafeWindow.set_iphone == 1) {
                    if ($('#remark').val() == null || $('#remark').val() == '') {
                        info('请填写手机号码');
                        return false;
                    }
                    if (!unsafeWindow.phone.test($("#remark").val())) {
                        info("请输入有效的手机号码");
                        return false;
                    }
                    unsafeWindow._param.remark = $('#remark').val();
                }

                var param1 = {};
                param1.param = JSON.stringify(unsafeWindow._param);
                unsafeWindow.AjaxPost('/order/book', param1, function (o) {
                    var val = $('input:radio:checked').val();
                    if (o.result == '1') {
                        window.location.href = cu('/order/myorder_view') + '?id=' + o.object.orderid;
                    } else if (o.result == '2') {
                        if (val == "0") {
                            // 学生付款
                            // 体育金支付
                            var dataPay = {
                                param: "{'payid':2,'orderid':'" + o.object.orderid + "','ctypeindex':0}",
                                json: true
                            }
                            $.ajax({
                                type: 'POST',
                                url: "http://gym.sysu.edu.cn/pay/account/topay.html",
                                data: dataPay,
                                success: function () {
                                    window.location.href = cu('/order/myorder_view') + '?id=' + o.object.orderid
                                },
                                dataType: 'json'
                            });
                        } else if (val == "1") {
                            warning1("现在去支付?", "topaypage", "no", o.object.orderid, o.object.orderid);
                        }
                    } else if (/未到该日期的预订时间/.test(o.message)) {
                        if ($('#tryinfo').attr('retry') == 'true') {
                            setTimeout(unsafeWindow.goonreserve, parseInt($('#tryinfo').attr('interval') == undefined ? 1000 : $('#tryinfo').attr('interval')));
                            $('#tryinfo').text(`已刷新 ${$('#tryinfo').attr('ncalls')} 次,间隔 ${$('#tryinfo').attr('interval')} 毫秒`)
                            console.log(`已刷新${$('#tryinfo').attr('ncalls')}次,继续刷新!间隔${$('#tryinfo').attr('interval')}毫秒。`);
                            // 每次进入前改变字体颜色,退出重置
                            if (typeof ($($("table").find("td,th")[0]).attr('style')) == "undefined") {
                                $("table").find("td,th").each(
                                    function (index, element) {
                                        element.setAttribute("style", "color:#069af3");

                                    }
                                );
                            } else {
                                $("table").find("td,th").each(function (index, element) { element.removeAttribute("style") });
                            }
                        } else {
                            // 重置颜色
                            $("table").find("td,th").each(function (index, element) { element.removeAttribute("style") });
                            console.log(`已刷新${$('#tryinfo').attr('ncalls')}次,用户取消了刷新!`);
                            $('#tryinfo').attr('ncalls', 0);
                        }
                    }
                    else {
                        info(o.message);
                    }
                });
            } else {
                error('数据有误,请返回重试');
            }

        }
        // 重写AjaxPost方法,去掉loadding
        unsafeWindow.AjaxPost = function AjaxPost(url, postData, successFunc, errorFunc) {
            if (postData == null) {
                postData = {
                    json: true
                };
            } else {
                postData.json = true;
                $.ajax({
                    url: cu(url),
                    data: postData,
                    type: 'post',
                    dataType: 'json',
                    success: function (data) {
                        if (data.message) {
                            if (data.message.indexOf('REQUESTERROR') != -1) {
                                // 出错页面
                                $('body').html(data.message);
                            } else if (data.message.indexOf('USERNOTLOGINYET') != -1) {
                                window.location.href = cu('/login/pre') + '?continueurl=' + data.object.continueurl;
                            } else if (data.message.indexOf('NOTPRODUCT') != -1) {
                                window.location.href = cu('/error/403');
                            } else {
                                if (typeof (successFunc) == "function") {
                                    successFunc(data);
                                }
                            }
                        } else {
                            if (typeof (successFunc) == "function") {
                                successFunc(data);
                            }
                        }
                    },
                    error: function (xhr) {
                        if (xhr) {
                            if (errorFunc) {
                                errorFunc(xhr);
                            } else {
                                error(xhr.status + ":" + xhr.statusText);
                            }
                        }
                    }
                });
            }
        }
    }
})();