Greasy Fork

Greasy Fork is available in English.

东南大学抢课助手

听说你抢不到课

当前为 2021-05-30 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         东南大学抢课助手
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  听说你抢不到课
// @author       realhuhu
// @match        http://newxk.urp.seu.edu.cn/xsxkapp/sys/xsxkapp/*
// @icon         https://huhu-1304907527.cos.ap-nanjing.myqcloud.com/share/qkzs
// @grant        none
// ==/UserScript==

(function () {
  'use strict';
  (_ => {
    _.init = () => {
      window.raw = {}
      window.result = []
      getAllCourses()
    }

    let getAllCourses = () => {
      $.ajax({
        type: "POST",
        url: "http://newxk.urp.seu.edu.cn/xsxkapp/sys/xsxkapp/elective/recommendedCourse.do",
        data: buildQueryTCParam(""),
        dataType: "json",
        ContentType: "application/json",
        beforeSend: XMLHttpRequest => {
          XMLHttpRequest.setRequestHeader("token", sessionStorage["token"])
        },
        success: data => {
          window.allCourses = data.dataList
          window.allCoursesId = getAllCoursesId(data.dataList)
        }
      })
    }

    let getAllCoursesId = allCourses => {
      let allCoursesId = []
      allCourses.forEach(value => {
        value.tcList.forEach(value => {
          allCoursesId.push(value.teachingClassID)
        })
      })
      return allCoursesId
    }


    let getSingleCourse = id => {
      let courseName = ""
      let teacherName = ""
      let info = {}
      allCourses.forEach(value => {
        courseName = value.courseName
        value.tcList.forEach(value => {
          if (value.teachingClassID === id) {
            teacherName = value.teacherName
            info = {course: courseName, teacher: teacherName}
          }
        })
      })
      return info
    }

    _.updateRaw = id => {
      if (window.raw[id] === undefined) {
        let index = Object.keys(window.raw).map(s => s.substr(0, s.length - 2)).indexOf(id.substr(0, id.length - 2))
        if (index === -1) {
          window.raw[id] = getSingleCourse(id)
          $.bhTip({
            content: "已添加",
            state: "success",
            hideWaitTime: 1000
          })
        } else {
          window.raw.length = 0
          Object.keys(window.raw).splice(index, 1, id).forEach(key => {
            raw[key] = getSingleCourse(key)
          })
          $.bhTip({
            content: "已替换",
            state: "success",
            hideWaitTime: 1000
          })
        }
      } else {
        $.bhTip({
          content: "你已经添加过这门课了",
          state: "danger",
          hideWaitTime: 2000
        })
      }
      Components.reloadList()
    }

  })(window.Courses = window.Courses || {});

  (_ => {
    _.mount = () => {
      createTag()
      createPanel()
      createModal()
      createAddButton()
    }

    let createTag = () => {
      let target = $(".cv-icons")[0]
      let wrap = document.createElement("div")
      wrap.setAttribute("class", "cv-user-icon cvMiniIconFlag")
      wrap.setAttribute("title", "抢课列表")
      wrap.setAttribute("onclick", "toggle()")
      wrap.innerHTML = tagTemplate()
      target.appendChild(wrap)
    }

    let createPanel = () => {
      let target = $("body")[0]
      let wrap = document.createElement("div")
      wrap.setAttribute("class", "panel hide")
      wrap.setAttribute("style", "display:none")
      wrap.innerHTML = panelTemplate()
      target.appendChild(wrap)
    }

    let createModal = () => {
      let target = $("body")[0]
      let wrap = document.createElement("div")
      wrap.setAttribute("class", "musk cover")
      wrap.setAttribute("style", "display:none; z-index:10000000;position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,0.8)")
      wrap.innerHTML = _.modalTemplate(result)
      target.appendChild(wrap)
    }

    let createAddButton = () => {
      let row = []
      let cards = []
      new Promise((resolve, reject) => {
        let timer = setInterval(() => {
          row = $("article .cv-row")
          if (row.length !== 0) {
            clearInterval(timer)
            resolve()
          }
        }, 10)
      }).then(successMessage => {
        for (let i = 0; i < row.length; i++) {
          row[i].addEventListener("click", () => {
            new Promise((resolve, reject) => {
              let timer = setInterval(() => {
                let target = row[i]
                cards = target.getElementsByClassName("cv-info")
                if (cards.length !== 0) {
                  clearInterval(timer)
                  resolve()
                }
              }, 10)
            }).then(successMessage => {
              for (let j = 0; j < cards.length; j++) {
                let target = cards[j]
                let id = target.querySelectorAll("button[tcid]")[0].getAttribute("tcid")
                if (target.getElementsByClassName("add").length === 0) {
                  let wrap = document.createElement("div")
                  wrap.setAttribute("class", "cv-caption-text cv-operation add")
                  wrap.innerHTML = '<button class="cv-btn cv-btn-cancel" type="button"  style="margin-left:0" onclick="addCourse(\'' + id + '\')">添加到列表</button>'
                  target.appendChild(wrap)
                }
              }
            })
          })
        }
      })
    }

    let tagTemplate = () =>
      '<svg t="1622102436350" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1611" width="100%" height="100%">' +
      '<path d="M768 952.32h-512c-57.344 0-102.4-45.056-102.4-102.4v-675.84c0-57.344 45.056-102.4 102.4-102.4h512c57.344 0 102.4 45.056 102.4 102.4v677.888c0 55.296-47.104 100.352-102.4 100.352z m-512-839.68c-34.816 0-61.44 26.624-61.44 61.44v675.84c0 34.816 26.624 61.44 61.44 61.44h512c32.768 0 61.44-26.624 61.44-59.392V174.08c0-34.816-26.624-61.44-61.44-61.44h-512z" p-id="1612" fill="#ffffff"/>' +
      '<path d="M714.752 530.432H309.248c-12.288 0-20.48-8.192-20.48-20.48s8.192-20.48 20.48-20.48h405.504c12.288 0 20.48 8.192 20.48 20.48s-8.192 20.48-20.48 20.48zM714.752 348.16H309.248c-12.288 0-20.48-8.192-20.48-20.48s8.192-20.48 20.48-20.48h405.504c12.288 0 20.48 8.192 20.48 20.48s-8.192 20.48-20.48 20.48zM598.016 716.8H309.248c-12.288 0-20.48-8.192-20.48-20.48s8.192-20.48 20.48-20.48h288.768c12.288 0 20.48 8.192 20.48 20.48s-8.192 20.48-20.48 20.48z" p-id="1613" fill="#ffffff"/>' +
      '</svg>'

    let panelTemplate = () => {
      let content = ''
      content += '<div style="width: 350px;height: 100%;float: left;position: fixed;top: 0;left: 0;background-color: rgba(61,72,105,0.9);z-index: 10000">'
      content += '<h1 style="color: #c7e6e6;margin-left: 20px; text-align: center">东大抢课脚本</h1>'
      content += '<hr>'
      content += '<input class="cv-search-input" id="enter" placeholder="输入课程编号+老师编号后,按回车添加" type="text"  style="width: 90%; margin:10px 5% 10px" onkeydown="enterCourse(\'' + event + '\')">'
      content += '<div class="list-wrap" style="overflow: auto;margin: 10px;border:1px solid white;height: 50%">'
      content += listTemplate(raw)
      content += '</div>'
      content += '<hr>'
      content += '<div class="cv-clearfix-child"><button class="cv-btn cv-btn-chose crab" style="width: 120px;height: 40px;font-size: 20px;float: right;margin: 20px 30px 0" onclick="crab()">一键抢课</button></div>'
      content += '<div class="cv-clearfix-child"><button class="cv-btn cv-btn-cancel show-result" style="width: 120px;height: 40px;font-size: 20px;float: right; margin: 20px 30px 0;display: none" onclick="showResult()">显示结果</button></div>'
      content += '</div>'
      return content
    }

    let listTemplate = raw => {
      let content = ''
      content += ' <div class="cv-list">'
      content += '<div class="cv-head">'
      content += '<div class="cv-normal" style="width: 60%">已选课程</div>'
      content += '<div class="cv-normal" style="width: 20%">教师</div>'
      content += '<div class="cv-normal" style="width: 20%">操作</div>'
      content += '</div>'
      if (JSON.stringify(raw) !== '{}') {
        content += '<div class="cv-body">'
        Object.keys(raw).forEach(key => {
          let course = raw[key].course
          let teacher = raw[key].teacher
          content += '<div class="cv-row">'
          content += '<div style="width: 60%;color: lightblue;height: 45px;border-right:1px solid rgba(230, 240, 252, 0.6);font-size: ">' + course + '</div>'
          content += '<div style="width: 20%;color: lightblue;height: 45px;border-right:1px solid rgba(230, 240, 252, 0.6)">' + teacher + '</div>'
          content += '<div style="width: 20%;height: 45px"><button class="cv-btn cv-btn-cancel" type="button" onclick="removeCourse(\'' + key + '\')">移除</button></div>'
          content += '</div>'
        })
        content += '</div>'
      } else {
        content += "<h3 style='color:lightblue;margin-top: 50%'>还未选择课程</h3>"
      }
      content += '</div>'
      return content
    }

    _.modalTemplate = result => {
      let content = ''
      content += '<div style="position: fixed;left: 20%;top:20%;width: 60%;height: 60%;background-color: white">'
      content += '<div style="margin: 60px 50px 0;height: 45vh;overflow: auto; border:1px solid rgba(61,72,105,0.9)">'
      content += '<div class="cv-list">'
      content += '<div class="cv-head">'
      content += '<div class="cv-normal" style="width: 40%">课程</div>'
      content += '<div class="cv-normal" style="width: 60%">结果</div>'
      content += '</div>'
      content += '<div class="cv-body">'
      result.forEach(value => {
        let course = value.course
        let result = value.result
        content += '<div class="cv-row">'
        content += '<div style="width: 40%;color: black;height: 45px;border-right:1px solid rgba(230, 240, 252, 0.6) ">' + course + '</div>'
        content += '<div style="width: 60%;color: black;height: 45px;border-right:1px solid rgba(230, 240, 252, 0.6)">' + result + '</div>'
        content += '</div>'
      })
      content += '</div>'
      content += '</div>'
      content += '</div>'
      content += '<button class="cv-btn cv-btn-chose" style="width: 120px;height: 40px;font-size: 20px;float: right;margin: 20px 50px 0" onclick="closeResult()">确定</button>'
      content += '</div>'
      return content
    }

    _.reloadList = () => {
      $(".list-wrap")[0].innerHTML = listTemplate(raw)
    }

  })(window.Components = window.Components || {});

  (() => {
    window.toggle = () => {
      let target = $(".panel")
      if (target.hasClass("hide")) {
        target.removeClass("hide")
        target.removeAttr("style")
      } else {
        target.addClass("hide")
        target.attr("style", "display:none")
      }
    }

    window.removeCourse = key => {
      delete raw[key]
      Components.reloadList()
      $.bhTip({
        content: "已移除",
        state: "success",
        hideWaitTime: 1000
      })
    }

    window.enterCourse = e => {
      let evt = window.event || e;
      if (evt.keyCode === 13) {
        let target = $("#enter")
        let id = target.val()
        id = "202020214" + id
        if (allCoursesId.indexOf(id) !== -1) {
          if (raw[id] === undefined) {
            target.val("")
            Courses.updateRaw(id)
          } else {
            $.bhTip({
              content: "你已经添加过这门课了",
              state: "danger",
              hideWaitTime: 2000
            })
          }
        } else {
          $.bhTip({
            content: "无效的课程代码,请重新输入",
            state: "danger",
            hideWaitTime: 2000
          })
        }
      }
    }

    window.crab = () => {
      if (JSON.stringify(raw) === '{}') {
        $.bhTip({
          content: "你还没有选择课程!!!",
          state: "danger",
          hideWaitTime: 2000
        })
      } else {
        window.result.length = 0
        let posts = []
        Object.keys(raw).forEach(key => {
          let param = buildAddVolunteerParam(key)
          posts.push($.ajax({
            type: "POST",
            url: "http://newxk.urp.seu.edu.cn/xsxkapp/sys/xsxkapp/elective/volunteer.do",
            data: param,
            dataType: "json",
            ContentType: "application/json",
            beforeSend: XMLHttpRequest => {
              XMLHttpRequest.setRequestHeader("token", sessionStorage["token"])
            },
            success: data => {
              result.push({"course": raw[key].course + "  " + raw[key].teacher, "result": data.msg})
            }
          }))
        })
        $(".crab")[0].innerText = "请等待.."
        $.when(...posts).done(() => {
          $(".crab")[0].innerText = "一键抢课"
          $.bhTip({
            content: "抢课完成",
            state: "success",
            hideWaitTime: 1000
          })
          $(".show-result").css("display", "")
        })
      }
    }

    window.showResult = () => {
      let target = $(".musk")
      if (target.hasClass("cover")) {
        target.removeClass("cover")
        target.css("display", "")
        target[0].innerHTML = Components.modalTemplate(result)
      }
    }

    window.closeResult = () => {
      let target = $(".musk")
      target.addClass("cover")
      target.css("display", "none")
    }

    window.addCourse = id => {
      if (raw[id] === undefined) {
        Courses.updateRaw(id)
      } else {
        $.bhTip({
          content: "你已经添加过这门课了",
          state: "danger"
        })
      }
    }
  })();

  $(() => {
    Courses.init()
    Components.mount()
  })
})
();