您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
【使用前先看介绍/有问题可反馈】便捷深大 (Convenient SZU):适配深圳大学内部网多个网页的辅助脚本。内部网首页左上角增加 `宿舍用电查询/校园网络续费/登录(不可用)Dr.com/体育场馆预订/百度文库/下载专区/师资队伍` 入口以及增加绑定个人信息窗口,免去进入 `Blackboard/学业完成查询/办事大厅卡片` 的繁琐步骤,自动登录(不可用) `Blackboard/办事大厅/Dr.com/校园网络续费` 等页面,自动填写需要登陆的页面的账号密码,【办事大厅】页面增加【修读课程统计下载】,【网上评教】页面增加【一键五星+评价】,【成长记录】页面增加【学期专业排名】,【转专业】页面增加【转专业成绩显示】,【学业完成查询】页面增加【彩虹地毯】,【宿舍用电查询】可自动记忆填写的宿舍信息并可自动显示近 20 天用电记录。
当前为
// ==UserScript== // @name Convenient SZU // @namespace http://tampermonkey.net/ // @version 1.1.4 // @description 【使用前先看介绍/有问题可反馈】便捷深大 (Convenient SZU):适配深圳大学内部网多个网页的辅助脚本。内部网首页左上角增加 `宿舍用电查询/校园网络续费/登录(不可用)Dr.com/体育场馆预订/百度文库/下载专区/师资队伍` 入口以及增加绑定个人信息窗口,免去进入 `Blackboard/学业完成查询/办事大厅卡片` 的繁琐步骤,自动登录(不可用) `Blackboard/办事大厅/Dr.com/校园网络续费` 等页面,自动填写需要登陆的页面的账号密码,【办事大厅】页面增加【修读课程统计下载】,【网上评教】页面增加【一键五星+评价】,【成长记录】页面增加【学期专业排名】,【转专业】页面增加【转专业成绩显示】,【学业完成查询】页面增加【彩虹地毯】,【宿舍用电查询】可自动记忆填写的宿舍信息并可自动显示近 20 天用电记录。 // @author cc // @match https://elearning.szu.edu.cn/* // @match https://authserver.szu.edu.cn/* // @match https://drcom.szu.edu.cn/* // @match https://self.szu.edu.cn/* // @match https://www1.szu.edu.cn/* // @match http://ehall.szu.edu.cn/* // @match http://bkxk.szu.edu.cn/* // @match https://*.webvpn.szu.edu.cn/* // @match 172.30.255.2/* // @match http://192.168.84.3:9090/cgcSims/* // @grant GM_setValue // @grant GM_getValue // @require https://cdn.bootcss.com/jquery/3.4.1/jquery.js // @require https://gf.qytechs.cn/scripts/418193-coder-utils.js // @require https://gf.qytechs.cn/scripts/422854-bubble-message.js // @noframes // ==/UserScript== (function() { 'use strict' var account = GM_getValue('account') var hasUpdatedInfo = false if (!account) { account = { cid: '', uid: '', pwd: '' } GM_setValue('account', account) } else { hasUpdatedInfo = account.cid && account.uid && account.pwd } function inform (msg) { console.log(`%c${msg}`, 'background-color: yellow; font-size: 16px;') } $(document).ready(function () { inform('Convenient SZU version 1.1.4') var bm = new BubbleMessage() if (location.host.match(/www1.*?\.szu\.edu\.cn/)) { if (location.href.endsWith('.szu.edu.cn/')) { let td = document.querySelector('table table table tbody tr td') let a_drcom_dom = document.getElementById('drcom_dom') if (td && !a_drcom_dom) { function setExtension () { td.querySelectorAll('img').forEach(e => e.remove()) td.firstChild.remove() td.firstChild.remove() td.style.padding = '5px 20px' td.innerHTML += '<br>' let a a = HTMLElement.$mkel('a', { href: 'http://192.168.84.3:9090/cgcSims/', id: 'electricity', }, { innerHTML: '宿舍用电查询' }) td.appendChild(a) a = HTMLElement.$mkel('a', { href: 'https://self.szu.edu.cn/self/', id: 'network', }, { innerHTML: '|校园网络续费' }) td.appendChild(a) a = HTMLElement.$mkel('a', { href: 'http://172.30.255.2/0.htm', id: 'drcom_dom', }, { innerHTML: '|登录(不可用) Dr.com' }) td.appendChild(a) td.innerHTML += '<br>' a = HTMLElement.$mkel('a', { href: 'http://ehall.szu.edu.cn/publicapp/sys/tycgyyxt/index.do', id: 'venue_yh', }, { innerHTML: '体育场馆预订(粤海校区)' }) td.appendChild(a) a = HTMLElement.$mkel('a', { href: 'http://ehall.szu.edu.cn/publicappxl/sys/xlxqtycgyy/index.do', id: 'venue_lh', }, { innerHTML: '|体育场馆预订(丽湖校区)' }) td.appendChild(a) td.innerHTML += '<br>' a = HTMLElement.$mkel('a', { href: 'http://www.lib.szu.edu.cn/zh-hans/er/baidu-wenku', id: 'wenku', }, { innerHTML: '百度文库' }) td.appendChild(a) a = HTMLElement.$mkel('a', { href: 'https://www1.szu.edu.cn/nc/view.asp?id=64', id: 'download', }, { innerHTML: '|下载专区' }) td.appendChild(a) a = HTMLElement.$mkel('a', { href: 'http://xzfc.szu.edu.cn/rsfw/sys/szdxxzfc/login/index.do', id: 'teacher', }, { innerHTML: '|师资队伍' }) td.appendChild(a) } function setInput () { let next_tr = document.querySelector('tbody tbody tbody tr:nth-child(2)') let tr = HTMLElement.$mkel('tr', { id: 'inform' }, {}, { 'display': 'flex', 'flex-wrap': 'wrap', 'justify-content': 'flex-start', }) let uid = HTMLElement.$mkel('input', { id: 'uid', type: 'number', minlength: '10', maxlength: '10', placeholder: '请输入 10 位数学号', }) let cid = HTMLElement.$mkel('input', { id: 'cid', type: 'number', minlength: '6', maxlength: '6', placeholder: '请输入 6 位数校园卡号', }) let pwd = HTMLElement.$mkel('input', { id: 'pwd', type: 'password', placeholder: '请输入统一认证登录(不可用)密码', }) let btn = HTMLElement.$mkel('button', {}, { innerHTML: '更新信息' }, { 'cursor': 'pointer', }, { click: function () { let uid_val = document.getElementById('uid').value let cid_val = document.getElementById('cid').value let pwd_val = document.getElementById('pwd').value if (!uid_val.match(/^\d{10}$/)) { bm.message({ type: 'warning', message: '学号必须为 10 位数', duration: 2000, }) return false } if (!cid_val.match(/^\d{6}$/)) { bm.message({ type: 'warning', message: '校园卡号必须为 6 位数', duration: 2000, }) return false } if (!pwd_val) { bm.message({ type: 'warning', message: '密码不能为空', duration: 2000, }) return false } account.uid = uid_val account.cid = cid_val account.pwd = pwd_val GM_setValue('account', account) bm.message({ type: 'success', message: '信息更新成功', duration: 2000, }) } }) if (account.uid) uid.value = account.uid if (account.cid) cid.value = account.cid if (account.pwd) pwd.value = account.pwd tr.appendChild(uid) tr.appendChild(cid) tr.appendChild(pwd) tr.appendChild(btn) next_tr.parentElement.insertBefore(tr, next_tr) let style = HTMLElement.$mkel('style', {}, { innerText: ` #inform > * { width: 160px; margin-left: 20px; margin-top: 5px; padding: 0 5px; } input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none !important; margin: 0; } ` }) document.head.appendChild(style) let win = document.querySelector('tbody tbody tr:last-child') let lst = win.lastElementChild.querySelector('tr:nth-child(2)') lst.style.height = `${lst.offsetHeight + tr.offsetHeight + 55}px` } setExtension() setInput() } } else if (location.href.indexOf('/board/infolist') >= 0) { function meets (_ct, _in) { for (let it of _in) if (_ct.match(it)) return true return false } function generateCheckbox (_id, _ct, _fn) { var checkbox = document.createElement('input') checkbox.id = _id checkbox.type = 'checkbox' checkbox.checked = false checkbox.style = 'margin-right: 5px;' checkbox.onchange = _fn var label = document.createElement('label') label.innerHTML = _ct label.setAttribute('for', _id) var container = document.createElement('span') container.style = 'font-size: 13px; display: inline-flex; align-items: center; margin-right: 10px; position: relative; top: 2px;' container.appendChild(checkbox) container.appendChild((label)) return container } function setCheckbox () { var checkbox_show_only_college = generateCheckbox('show-only-college', '只看学院学部', function (event) { var _in = [/.*?学院.*/, /.*?学部.*/] var title_container = document.querySelectorAll('[valign=top]')[3] var articles = [...title_container.querySelectorAll('table>tbody>tr')].slice(2) var not_meets_articles = articles.filter(el => !meets(el.querySelector('td:nth-child(3)>a').innerText, _in)) var not_meets_depts = [...document.querySelectorAll('select[name=from_username]>option')].filter(el => !meets(el.value, _in)) if (event.target.checked) { not_meets_depts.forEach(el => el.style.display = 'none') not_meets_articles.forEach(el => el.style.display = 'none') } else { not_meets_depts.forEach(el => el.style.display = '') not_meets_articles.forEach(el => el.style.display = '') } }) var next_el = document.querySelector('select[name=dayy]') var td = next_el.parentElement td.style.width = '500px' td.insertBefore(checkbox_show_only_college, next_el) } function updateSelect () { // 只看学院学部 var show_el = document.querySelector('input#show-only-college') show_el.addEventListener('change', (event) => { account.boardShowOnlyChecked = event.target.checked GM_setValue('account', account) }) if (typeof account.boardShowOnlyChecked !== 'boolean') { account.boardShowOnlyChecked = show_el.checked GM_setValue('account', account) } else if (show_el.checked !== account.boardShowOnlyChecked) { show_el.click() } // 发文时间 var dayy_el = document.querySelector('select[name=dayy]') dayy_el.addEventListener('change', (event) => { account.boardDayySelectedIndex = event.target.selectedIndex GM_setValue('account', account) }) if (typeof account.boardDayySelectedIndex !== 'number') { account.boardDayySelectedIndex = dayy_el.selectedIndex GM_setValue('account', account) } else if (dayy_el.selectedIndex !== account.boardDayySelectedIndex) { dayy_el.selectedIndex = account.boardDayySelectedIndex } // 发文单位 var dept_el = document.querySelector('select[name=from_username]') dept_el.addEventListener('change', (event) => { account.boardDeptSelectedIndex = event.target.selectedIndex GM_setValue('account', account) }) if (typeof account.boardDeptSelectedIndex !== 'number') { account.boardDeptSelectedIndex = dept_el.selectedIndex GM_setValue('account', account) } else if (dept_el.selectedIndex !== account.boardDeptSelectedIndex) { dept_el.selectedIndex = account.boardDeptSelectedIndex } // 搜索关键词 var kw_el = document.querySelector('input[name=keyword]') kw_el.addEventListener('input', (event) => { account.boardKeywordValue = event.target.value GM_setValue('account', account) }) if (typeof account.boardKeywordValue !== 'string') { account.boardKeywordValue = kw_el.getAttribute('value') GM_setValue('account', account) } else if (kw_el.getAttribute('value') !== account.boardKeywordValue) { kw_el.setAttribute('value', account.boardKeywordValue) kw_el.value = account.boardKeywordValue } } setCheckbox() updateSelect() } } else if (!hasUpdatedInfo) { return } if (location.host.indexOf('elearning') >= 0) { if (location.href.endsWith('.szu.edu.cn/') || location.href.endsWith('.szu.edu.cn/webapps/login/')) { let span = document.querySelector('table table table tr td a span') if (span) span.click() } else if (location.href.includes('webapps/portal/')) { let observer = document.body.$monitor({ childList: true }, (events) => { for (let event of events) { for (let node of event.addedNodes) { if (node instanceof HTMLElement && node.classList.contains('lb-wrapper')) { (function rec () { let agree_button = node.querySelector('#agree_button') if (agree_button) { agree_button.click() observer.disconnect() } else { setTimeout(rec, 50) } })() } } } }) } } else if (location.host == 'authserver.szu.edu.cn') { let username_el = document.getElementById('username') let password_el = document.getElementById('password') let helper_el = $('.iCheck-helper') let captchaResponse_el = document.querySelector('p#cpatchaDiv #captchaResponse') let button_el = document.querySelector('button') if (username_el && password_el && button_el && helper_el.length && !captchaResponse_el) { username_el.value = account.cid password_el.value = account.pwd helper_el.click() button_el.click() } } else if (location.host == 'ehall.szu.edu.cn') { function setfunc () { function courseClassSorted (courses) { function getCourseClassPriority (course) { let priority = ['基本通识', '专业核心', '专业限选', '专业选修', '扩展通识', '自然科学', '生命科学', '社会科学', '中华文化', '人文艺术', '创新创业', '个性课程', '基本实践'] for (let i = 0; i < priority.length; i++) if (course.indexOf(priority[i]) >= 0) return i return priority.length } let courseInfo = courses.map(c => { return { course: c, priority: getCourseClassPriority(c), } }) return courseInfo.$sorted('priority').$map('course') } function exec () { $.ajax({ method: 'POST', url: 'http://ehall.szu.edu.cn/jwapp/sys/xywccx/modules/xywccx/cxscfakz.do', data: { BYNJDM: '-', }, }).then(res => { let extendedCourseClasses = ['自然科学类', '生命科学类', '社会科学类', '中华文化类', '人文艺术类', '创新创业类'] let numChinese = ['一', '二', '三', '四', '五', '六', '七', '八'] let courseClassesObj = res.datas.cxscfakz.rows courseClassesObj = courseClassesObj.$map(['KZM', 'KZH', 'PYFADM', 'YQXF', 'WCXF', 'YQMS', 'WCMS', 'YQWCKZS', 'WCKZS', 'FKZH']) let allCourseClasses = courseClassesObj.filter(c => c.FKZH !== '-1').$map('KZM') let statCourseClasses = allCourseClasses.filter(c => !extendedCourseClasses.includes(c)) let extendedCourseClass = allCourseClasses.$where(c => c.indexOf('扩展通识') >= 0, true) let cmap = Object.fromEntries([[extendedCourseClass, courseClassesObj.$where(c => c.KZM.indexOf('扩展通识') >= 0, true)]]) allCourseClasses = allCourseClasses.filter(c => c.indexOf('扩展通识') < 0) let recommendClasses = statCourseClasses.filter(c => c.indexOf('个性课程') < 0) courseClassesObj = courseClassesObj.filter(c => allCourseClasses.includes(c.KZM) && c.FKZH !== '-1') cmap = Object.assign(cmap, Object.fromEntries(courseClassesObj.map(c => [c.KZM, c]))) let keys = ['课程类型', '要求学分', '已修学分', '要求门数', '已修门数', '要求类别数', '已修类别数'] let progressContent = '课程类型,要求学分,已修学分,要求门数,已修门数,要求类别数,已修类别数\n' statCourseClasses = courseClassSorted(statCourseClasses) statCourseClasses.map(statCourseClass => { let c = cmap[statCourseClass] return { '课程类型': statCourseClass, '要求学分': c.YQXF, '已修学分': c.WCXF, '要求门数': c.YQMS === null ? '0' : String(c.YQMS), '已修门数': c.WCMS === null ? '0' : String(c.WCMS), '要求类别数': c.YQWCKZS === null ? '0' : String(c.YQWCKZS), '已修类别数': c.WCKZS === null ? '0' : String(c.WCKZS), } }).forEach(p => progressContent += keys.map(k => p[k]).join(',') + '\n') let reqs = [] courseClassesObj.forEach(courseClass => { reqs.push($.ajax({ method: 'POST', url: 'http://ehall.szu.edu.cn/jwapp/sys/xywccx/modules/xywccx/cxscfakzkc.do', data: { BYNJDM: '-', KZH: courseClass.KZH, PYFADM: courseClass.PYFADM, pageSize: 999, pageNumber: 1, }, }).then(res => { let courseList = res.datas.cxscfakzkc.rows courseList = courseList.$map(['KCM', 'CJ', 'XF', 'SFTG_DISPLAY', 'XNXQDM', 'KCXZDM_DISPLAY', 'KCH', 'BZ']) courseList = courseList.$reindex({'KCM': '课程名', 'CJ': '成绩', 'XF': '学分', 'SFTG_DISPLAY': '是否通过', 'XNXQDM': '学年学期', 'KCXZDM_DISPLAY': '课程性质', 'BZ': '备注'}) let clreqs = [] courseList.forEach(course => { course['课程类型'] = courseClass.KZM course['成绩'] = course['成绩'] || '' course['学年学期'] = course['学年学期'] || '' course['备注'] = course['备注'] || '' if (course['备注'].match(/[^\d\s\:a-zA-z\-]/g) === null || course['备注'].match(/见.*?备注.*/) !== null) course['备注'] = '' clreqs.push($.ajax({ method: 'POST', url: 'http://ehall.szu.edu.cn/jwapp/sys/qxfacx/modules/pyfacxepg/kzkccx.do', data: { KZH: courseClass.KZH, PYFADM: courseClass.PYFADM, KCH: course.KCH, pageSize: 1, pageNumber: 1, }, }).then(res => { let recSem = '' if (res.datas.kzkccx.rows.length > 0) { let remark = res.datas.kzkccx.rows[0].BZ recSem = res.datas.kzkccx.rows[0].XDXQ || '' if (typeof remark === 'string' && remark.length > 0 && !course['备注'].length && (remark.match(/[^\d\s\:a-zA-z\-]/g) !== null && remark.match(/见.*?备注.*/) === null)) course['备注'] = remark } course['建议修读学期'] = recSem delete course.KCH return course }).fail(err => { console.error(err) })) }) return Promise.all(clreqs).then(res => { return [courseClass.KZM, res] }) }).fail(err => { console.error(err) })) }) Promise.all(reqs).then(res => { let courses = Object.fromEntries(res) let gradeMap = {'A+': 4.5, 'A': 4.0, 'B+': 3.5, 'B': 3.0, 'C+': 2.5, 'C': 2.0, 'D': 1.0, 'F': 0.0} let semester = Array.from(new Set(Object.values(courses).$merge().$map('学年学期'))).filter(s => Boolean(s)) semester.sort() let earliestYear = new Date().getFullYear() if (semester.length) earliestYear = Number(semester[0].slice(0, 4)) let semesterIndexToDate = (year, semesterIndex) => { semesterIndex = Number(semesterIndex) let reccommendYear = year + ((semesterIndex - 1) >> 1) let reccommendGrade = 2 - (semesterIndex & 1) return `${reccommendYear}-${reccommendYear + 1}-${reccommendGrade}` } let semesterDateToChinese = (year, semesterDate) => { let allNums = semesterDate.match(/\d+/g) let yearIndex = Number(allNums[0]) - year let gradeChinese = `大${numChinese[yearIndex]}${['上', '下'][Number(allNums[2]) - 1]}` return `${semesterDate} (${gradeChinese})` } let semesterGrade = {} semester.forEach(s => semesterGrade[s] = {semester: s, allScore: 0, getScore: 0, avgScore: 0, acaScore: 0, acgScore: 0, acvScore: 0}) Object.values(courses).$merge().forEach(course => { if (course['学年学期']) { semesterGrade[course['学年学期']]['allScore'] += course['学分'] semesterGrade[course['学年学期']]['getScore'] += course['学分'] * gradeMap[course['成绩']] } }) semesterGrade = Object.values(semesterGrade).$sorted('semester') for (let i = 0; i < semesterGrade.length; i++) { semesterGrade[i].avgScore = parseFloat(semesterGrade[i].getScore / semesterGrade[i].allScore).toFixed(2) semesterGrade[i].acaScore = semesterGrade[i].allScore semesterGrade[i].acgScore = semesterGrade[i].getScore for (let j = 0; j < i; j++) { semesterGrade[i].acaScore += semesterGrade[j].allScore semesterGrade[i].acgScore += semesterGrade[j].getScore } semesterGrade[i].acvScore = parseFloat(semesterGrade[i].acgScore / semesterGrade[i].acaScore).toFixed(2) semesterGrade[i].semester = semesterDateToChinese(earliestYear, semesterGrade[i].semester) } recommendClasses.forEach(recommendClass => { let courseClassesIndex = courseClassesObj.$where(x => x.KZM === recommendClass) if (courseClassesIndex >= 0) { courses[recommendClass].forEach(c => { let reccommendSemester = '' if (c['建议修读学期']) reccommendSemester = semesterIndexToDate(earliestYear, c['建议修读学期']) c['建议修读学期'] = reccommendSemester }) } }) let orderedCourses = [] allCourseClasses = courseClassSorted(allCourseClasses) allCourseClasses.forEach(courseClass => { if (ut.type.$isIterable(courses[courseClass]) && courses[courseClass].length > 0) { courses[courseClass] = courses[courseClass].$sorted(['课程名', '建议修读学期', '学年学期', '是否通过'], [false, false, false, true]) orderedCourses = orderedCourses.concat(courses[courseClass]) } }) let suggestCourses = [] let notPassCourses = orderedCourses.filter(c => c['是否通过'] !== '通过') recommendClasses = courseClassSorted(recommendClasses) recommendClasses.forEach(recommendClass => { let tmpCourseList = notPassCourses.filter(c => c['课程类型'] === recommendClass) tmpCourseList = tmpCourseList.$sorted('建议修读学期') if (recommendClass === '专业选修课') { let tmpLimitCourseList = tmpCourseList.filter(c => c['备注'].indexOf('限选') >= 0) let tmpFreeCourseList = tmpCourseList.filter(c => c['备注'].indexOf('限选') < 0) tmpCourseList = tmpLimitCourseList.concat(tmpFreeCourseList) } suggestCourses = suggestCourses.concat(tmpCourseList) }) orderedCourses.forEach(c => { if (c['学年学期']) c['学年学期'] = semesterDateToChinese(earliestYear, c['学年学期']) if (c['建议修读学期']) c['建议修读学期'] = semesterDateToChinese(earliestYear, c['建议修读学期']) }) let gradeContent = '学年学期,学期学分,学期GPA,累计学分,累计GPA\n' for (let grade of semesterGrade) gradeContent += `${grade.semester},${grade.allScore},${grade.avgScore},${grade.acaScore},${grade.acvScore}\n` let courseContent = '课程名,学分,成绩,是否通过,学年学期,建议修读学期,课程类型,课程性质,备注\n' for (let course of orderedCourses) courseContent += `${course['课程名']},${course['学分']},${course['成绩']},${course['是否通过']},${course['学年学期']},${course['建议修读学期']},${course['课程类型']},${course['课程性质']},${course['备注']}\n` let suggestContent = '以下是根据数据自动生成的推荐修读课程,仅供参考\n' suggestContent += '课程名,学分,成绩,是否通过,学年学期,建议修读学期,课程类型,课程性质,备注\n' for (let course of suggestCourses) suggestContent += `${course['课程名']},${course['学分']},${course['成绩']},${course['是否通过']},${course['学年学期']},${course['建议修读学期']},${course['课程类型']},${course['课程性质']},${course['备注']}\n` let csvContent = `${courseContent}\n${gradeContent}\n${progressContent}\n${suggestContent}\n` csvContent.$toCsv('修读课程统计.csv') bm.message({ type: 'success', message: '修读课程统计表格生成成功', duration: 2000, }) }) }).fail(err => { console.error(err) }) } (function () { let ampDesktopNav = $('#ampDesktopNav')[0] if (!ampDesktopNav) return function setTab () { let stuServeCenter = ampDesktopNav.firstElementChild let div = HTMLElement.$mkel('div', { id: 'download-training-program', class: stuServeCenter.className.replace(/\s?amp\-active/, ''), title: '修读课程统计下载', }, {innerHTML: '修读课程统计下载'}, {}, { click: function () { $.ajax({ method: 'POST', url: 'http://ehall.szu.edu.cn/jwapp/sys/xywccx/modules/xywccx/cxscfakz.do', data: { BYNJDM: '-', }, }).then(res => { let rows = res.datas.cxscfakz.rows let i = 0 while (rows[i].KZM.indexOf('基本通识课') < 0 && i < rows.length) i++ let courseClass = rows[i] $.ajax({ method: 'POST', url: 'http://ehall.szu.edu.cn/jwapp/sys/qxfacx/modules/pyfacxepg/kzkccx.do', data: { KZH: courseClass.KZH, PYFADM: courseClass.PYFADM, pageSize: 10, pageNumber: 1, BYNJDM: '-', }, }).then(res => { setTimeout(() => { $('#ampDesktopNav')[0].firstElementChild.click() }, 50) exec() }).fail(err => { console.log('fail (code: -2)') bm.message({ type: 'info', message: `将跳转至"全校培养方案查询",跳转后请手动关闭打开的页面`, duration: 2000, }) setTimeout(() => { let btn = $('[amp-title=全校培养方案查询]')[0] btn.setAttribute('amp-unviewabledescription', 'true') btn.click() setTimeout(() => { div.click() }, 50) }, 3000) }) }).fail(err => { console.log('fail (code: -1)') bm.message({ type: 'info', message: `将跳转至"学业完成查询",跳转后请手动关闭打开的页面`, duration: 2000, }) setTimeout(() => { let btn = $('.card-bus-content [amp-title=学业完成查询]')[0] btn.setAttribute('amp-unviewabledescription', 'true') btn.click() setTimeout(() => { div.click() }, 50) }, 3000) }) }, }) stuServeCenter.$before(div, -1) } (function rec () { let child = ampDesktopNav.firstElementChild if (child) { setTab() } else { setTimeout(rec, 50) } })() })() } let ampHasNoLogin = document.getElementById('ampHasNoLogin') if (ampHasNoLogin && sessionStorage.ampUserId === 'guest') { ampHasNoLogin.click() setfunc() } if (sessionStorage.ampUserId !== 'guest') { if (location.href.indexOf('/jwapp/sys/czjl') >= 0) { (function rec () { let el = document.getElementsByClassName('czjl-sixItem-container')[0] if (el) { el.innerHTML = el.innerHTML.replace(/<!\-\-\s*/g, '').replace(/\s*\-\->+/g, '') } else { setTimeout(rec, 50) } })() } if (location.href.indexOf('/jwapp/sys/jwwspj') >= 0) { if (document.getElementsByClassName('timu-title')[0] && !document.getElementById('quick-set')) { let title = document.getElementsByClassName('timu-title')[0] let btn = HTMLElement.$mkel('button', {id: 'quick-set'}, {innerHTML: '一键五星+评价'}, { 'border': '0', 'width': '300px', 'height': '40px', 'margin-left': '10px', 'fontW-weight': 'bold', 'font-size': '16px', 'color': 'white', 'background-color': '#d22e2e', }, { 'click': function () { let rotate = document.getElementsByClassName('rotate')[0] if (rotate && rotate.innerHTML.indexOf('已') >= 0) { bm.message({ type: 'warning', message: '你已经评教过了', duration: 2000, }) return false } $('[data-x-bl=100]').toArray().forEach(s => s.firstElementChild.click()) $('textarea').val(prompt('请提供一个默认的教师评价')) return false }, }) title.$before(btn) } } if (location.href.indexOf('/new/index.html') >= 0) { if ($('#ampDesktopNav')[0] && !$('#download-training-program')[0]) { setfunc() } } if (location.href.indexOf('/jwapp/sys/xywccx') >= 0) { function setFunc () { let scoreMaps = { 'A+': 4.5, 'A': 4.0, 'B+': 3.5, 'B': 3.0, 'C+': 2.5, 'C': 2.0, 'D': 1.0, 'F': 0.0, } function setList (courses, sem) { function createInfo () { let studentName = sessionStorage.ampUserName let weightedScore = courses.map(c => parseFloat(c['学分']) * scoreMaps[c['成绩']]) let score = courses.map(c => parseFloat(c['学分'])) let avgScore = parseFloat(weightedScore.$sum() / score.$sum()).toFixed(2) let info = HTMLElement.$mkel( 'div', {}, { innerHTML: ` <p style="margin-top: 40px">${studentName} 同学,你本学期的绩点是:</p> <p style="font-size: 120px color: #fff306 height: 120px margin-top: 30px"><i>${avgScore}</i></p> <p style="margin: 70px 0 60px">下学期再接再厉哦!</p> `, }, { 'font-size': '30px', 'background-color': '#fe5f5e', 'margin-bottom': '20px', 'width': '640px', 'display': 'flex', 'flex-direction': 'column', 'align-items': 'center', 'color': 'white', } ) return info } function createTable () { let table = HTMLElement.$mkel( 'div', { id: 'rainbow-grade-table' }, {}, { 'width': 'max-content', 'height': 'max-content', 'display': 'flex', 'flex-direction': 'column', 'margin': '200px', 'align-items': 'center', 'background-color': 'white', 'line-height': 'normal', } ) return table } function createItem (course) { function createText () { let text = HTMLElement.$mkel( 'div', {}, { innerHTML: ` <p style=" overflow: hidden; text-overflow: ellipsis; white-space: nowrap; ">课程名:${course['课程名']}</p> <p>课程号:${course['课程号']}</p> <p>学分:${course['学分']}</p> <p>课程类别:${course['课程类别']}</p> `, }, { 'width': '400px', 'font-size': '28px', 'padding-left': '20px', } ) let container = HTMLElement.$mkel( 'div', {}, {}, { 'display': 'flex', 'flex-direction': 'column', 'align-items': 'center', 'justify-content': 'center', } ) container.appendChild(text) return container } function createScore () { let text = HTMLElement.$mkel( 'div', {}, { innerHTML: course['成绩'] }, { 'font-size': '90px', }, ) let container = HTMLElement.$mkel( 'div', {}, {}, { 'display': 'flex', 'flex-direction': 'column', 'align-items': 'center', 'justify-content': 'center', 'width': '160px', } ) container.appendChild(text) return container } function createCard () { let cmap = { 'A+': '#e7322f', 'A': '#fe5f5e', 'B+': '#7648d9', 'B': '#4d89d7', 'C+': '#ff7905', 'C': '#ffa303', 'D': '#219b3e', 'F': '#4e4e4e', } let bgc = cmap[course['成绩']] let card = HTMLElement.$mkel('div', {}, {}, { 'display': 'flex', 'flex-direction': 'row', 'align-items': 'center', 'justify-content': 'space-between', 'width': '600px', 'height': '200px', 'margin-bottom': '20px', 'border-radius': '12px', 'background-color': bgc, 'color': 'white', }) let text = createText() let score = createScore() card.appendChild(text) card.appendChild(score) return card } let item = createCard() return item } let semList = Array.from(new Set(courses.map(c => c['学年学期']).filter(c => c))) if (sem && !semList.includes(sem)) { bm.message({ type: 'warning', message: '输入不合法,默认生成最新学期的彩虹地毯', duration: 2000, }) sem = semList.$max() } if (!sem) sem = semList.$max() courses = courses.filter(c => c['学年学期'] === sem) courses = courses.$sorted([c => parseFloat(c['学分']), c => scoreMaps[c['成绩']]], [true, true]) let table = createTable() table.appendChild(createInfo()) courses.forEach(course => table.appendChild(createItem(course))) $('.bh-paper-pile-body')[0].$before(table) } function downloadList () { function callbackfn (canvas) { let a = HTMLElement.$mkel( 'a', { href: canvas.toDataURL('image/png', 1.0), download: '彩虹地毯.png', } ) document.body.appendChild(a) a.click() document.body.removeChild(a) } if (typeof html2canvas !== 'undefined') { $.getScript('https://html2canvas.hertzen.com/dist/html2canvas.js', function () { html2canvas($('#rainbow-grade-table')[0], { dpi: window.devicePixelRatio }).then(callbackfn) }) } else { html2canvas($('#rainbow-grade-table')[0], { dpi: window.devicePixelRatio }).then(callbackfn) } } function setBar (courses) { if (!$('#xywcqk_chdt')[0]) { let bar = $('.bh-paper-pile-dialog-container')[0] if (bar) { bar.style.width = `${bar.offsetWidth + 100}px` let a = HTMLElement.$mkel( 'a', { id: 'xywcqk_chdt' }, { innerHTML: '彩虹地毯', }, { 'font-size': '14px', 'margin-left': '20px', 'cursor': 'pointer', } ) let last = $('#xywcqk_bxqxk')[0] last.$before(a) a.$before(last) a.addEventListener('click', function (event) { if (!$('#rainbow-grade-table')[0]) { let semester = prompt(`请输入需要生成彩虹地毯的学年学期,格式为 'yyyy-yyyy-n' ,如 '2020-2021-2' 表示2020学年至2021学年第2学期,若输入不合法或不输入,将默认生成最新学期的彩虹地毯`) while (semester && !/^\d{4}-\d{4}-\d$/.exec(semester)) semester = prompt(`输入格式必须为 'yyyy-yyyy-n'`) if (!semester) { bm.message({ type: 'warning', message: '未输入,默认生成最新学期的彩虹地毯', duration: 2000, }) semester = undefined } else { let [yearStart, yearEnd, num] = semester.match(/\d+/g) if (parseInt(yearEnd) - parseInt(yearStart) !== 1 || !parseInt(num).$in(1, 2, true)) { bm.message({ type: 'warning', message: '输入不合法,默认生成最新学期的彩虹地毯', duration: 2000, }) semester = undefined } } setList(courses, semester) downloadList() } }) } } } if (!window.courseClasses) { $.ajax({ method: 'POST', url: 'http://ehall.szu.edu.cn/jwapp/sys/xywccx/modules/xywccx/cxscfakz.do', data: { BYNJDM: '-', }, }).then(res => { let courseClasses = res.datas.cxscfakz.rows window.courseClasses = courseClasses courseClasses = courseClasses.$map(['KZM', 'KZH', 'PYFADM', 'YQXF', 'WCXF', 'YQMS', 'WCMS', 'YQWCKZS', 'WCKZS', 'FKZH']).filter(c => c.FKZH !== '-1') Promise.all(courseClasses.map(courseClass => { return $.ajax({ method: 'POST', url: 'http://ehall.szu.edu.cn/jwapp/sys/xywccx/modules/xywccx/cxscfakzkc.do', data: { BYNJDM: '-', KZH: courseClass.KZH, PYFADM: courseClass.PYFADM, pageSize: 999, pageNumber: 1, }, }).then(res => { let courseList = res.datas.cxscfakzkc.rows courseList = courseList.$map(['KCM', 'KCH', 'CJ', 'XF', 'KCLBDM_DISPLAY', 'SFTG_DISPLAY', 'XNXQDM']) courseList = courseList.$reindex({'KCM': '课程名', 'KCH': '课程号','CJ': '成绩', 'XF': '学分', 'KCLBDM_DISPLAY': '课程类别', 'SFTG_DISPLAY': '是否通过', 'XNXQDM': '学年学期'}) courseList.forEach(c => { c['成绩'] = c['成绩'] || 'F' c['学分'] = parseFloat(c['学分']).toFixed(2) }) return courseList }) })).then(res => { setBar(res.$merge()) window.courseClasses = undefined }) }) } } let fn = (events) => { for (let event of events) { for (let node of event.addedNodes) { if (node.classList.contains('bh-paper-pile-dialog')) { setFunc() } } } } document.body.$monitor({ childList: true }, fn) } if (location.href.indexOf('/jwapp/sys/zzy') >= 0) { function addCJ () { if (document.getElementById('convenient-szu-zzy-cj')) return $.ajax({ url: 'http://ehall.szu.edu.cn/jwapp/sys/zzy/modules/xszzysq/cxxszzybmsq.do', type: 'POST', data: { XH: localStorage.ampUserId }, }).then(res => { var info = res.datas.cxxszzybmsq.rows[0] if (info) { var bar = document.createElement('span') bar.id = 'convenient-szu-zzy-cj' if (info.GGKCJ) bar.innerHTML += `公共课成绩:${info.GGKCJ} ` if (info.ZYKCJ) bar.innerHTML += `专业课成绩:${info.ZYKCJ} ` if (info.ZCJ) bar.innerHTML += `总成绩:${info.ZCJ} ` if (bar.innerHTML.length) { (function rec () { var text_center = document.querySelector('.bh-text-center.bh-pull-left') if (text_center) text_center.appendChild(bar) else setTimeout(rec, 250) })() } } }) } if (location.href.endsWith('#/xszzysq')) addCJ() window.onhashchange = () => { if (location.href.endsWith('#/xszzysq')) addCJ() } } } (function rec () { if ($('#ampTabContentItem0')[0]) { $('#ampTabContentItem0')[0].$monitor({ childList: true, subtree: true }, (events) => { $('.appFlag.widget-app-item').attr('amp-unviewabledescription', 'true') $('.appFlag.amp-app-card-hover-big').attr('amp-unviewabledescription', 'true') }) } else { setTimeout(rec, 50) } })() var ampServiceCenterSearchApps = $('#ampServiceCenterSearchApps')[0] if (ampServiceCenterSearchApps) { ampServiceCenterSearchApps.$monitor({ childList: true, subtree: true }, (events) => { $('.appFlag.widget-app-item').attr('amp-unviewabledescription', 'true') $('.appFlag.amp-app-card-hover-big').attr('amp-unviewabledescription', 'true') }) } } else if (location.host == '172.30.255.2') { if (location.href.includes('.htm')) { let username = document.getElementById('username') let password = document.getElementById('password') let submit = document.querySelector('#submit[type=submit]') if (username && password && submit) { username.value = account.cid password.value = account.pwd submit.click() } } } else if (location.host == '192.168.84.3:9090') { let client = document.querySelector('[name=client]') let buildingName = document.querySelector('[name=buildingId]') let roomName = document.querySelector('[name=roomName]') let beginTime = document.querySelector('#beginTime') let endTime = document.querySelector('#endTime') if (client && buildingName && roomName) { if (account.clientSelectedIndex !== client.selectedIndex) { account.clientSelectedIndex = client.selectedIndex account.client = client.value delete account.buildingNameSelectedIndex delete account.buildingId delete account.roomName GM_setValue('account', account) } if (account.buildingId) buildingName.selectedIndex = account.buildingNameSelectedIndex buildingName.removeAttribute('onchange') buildingName.onchange = function () { account.buildingNameSelectedIndex = this.selectedIndex account.buildingId = this.options[this.selectedIndex].value GM_setValue('account', account) } if (account.roomName) roomName.value = account.roomName roomName.oninput = function () { account.roomName = this.value GM_setValue('account', account) } } else if (beginTime && endTime && location.href.indexOf('login.do') >= 0) { let toDate = (date) => date.toLocaleDateString().replace(/\//g, '-') let now = new Date() let twentyDaysAgo = new Date(now.getTime() - 1000 * 86400 * 19) beginTime.value = toDate(twentyDaysAgo) endTime.value = toDate(now) document.querySelector('[name=type]').selectedIndex = 1 document.querySelector('[type=submit]').click() } } else if (location.host == 'drcom.szu.edu.cn') { if (location.href.includes('.htm')) { let username_el = document.querySelector('input[name=DDDDD]') let password_el = document.querySelector('input[name=upass]') let submit_el = document.querySelector('input[type=submit]') if (username_el && password_el && submit_el) { username_el.value = account.cid password_el.value = account.pwd submit_el.click() } } } else if (location.host.match(/bkxk.*?\.szu\.edu\.cn/)) { let loginName_el = document.getElementById('loginName') let loginPwd_el = document.getElementById('loginPwd') if (loginName_el && loginPwd_el) { loginName_el.value = account.uid loginPwd_el.value = account.pwd } } else if (location.host == 'self.szu.edu.cn') { let account_el = document.getElementById('account') let pass_el = document.getElementById('pass') let submit_el = document.querySelector('input[type=submit]') if (account_el && pass_el && submit_el) { account_el.value = account.cid pass_el.value = account.pwd submit_el.click() } } else if (location.host.match(/authserver.*?\.webvpn\.szu\.edu\.cn/)) { var username_el = document.getElementById('username') var password_el = document.getElementById('password') var helper_el = document.querySelector('.iCheck-helper') var button_submit = document.querySelector('button[type=submit]') if (username_el && password_el && helper_el && button_submit) { helper_el.click() username_el.setAttribute('value', account.cid) password_el.setAttribute('value', account.pwd) button_submit.click() } } else if (1) {} }) })()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址