init:框架
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | .idea/* | ||||||
|  | /config.yaml | ||||||
|  | node_modules/* | ||||||
|  | /pnpm-lock.yaml | ||||||
							
								
								
									
										36
									
								
								config.yaml.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								config.yaml.example
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | # 教务cookie | ||||||
|  | cookie: "JSESSIONID=asd;" | ||||||
|  | # 在 https://qmsg.zendee.cn 申请 | ||||||
|  | qmsgKey: "v9631222364dd7ae99909cb63b7445c5" | ||||||
|  | # 轮询间隔毫秒 | ||||||
|  | interval: 100 | ||||||
|  | # 监控列表 | ||||||
|  | # channel: bx(必修),xx(限选),rx(任选) | ||||||
|  | # kch:课程号;kxh:课序号 | ||||||
|  | monit: | ||||||
|  |   list: | ||||||
|  |     - kch: sd01332200 | ||||||
|  |       kxh: 100 | ||||||
|  |       channel: rx | ||||||
|  | # 抢课列表,列表中全抢 | ||||||
|  | acquire: | ||||||
|  |   list: | ||||||
|  |     - kch: sd01332200 | ||||||
|  |       kxh: 100 | ||||||
|  |       channel: rx | ||||||
|  |     - kch: sd00812930 | ||||||
|  |       kxh: 900 | ||||||
|  |       channel: xx | ||||||
|  | # 换课列表(先退掉冲突的课再抢课),列表中任抢其一 | ||||||
|  | replace: | ||||||
|  |   list: | ||||||
|  |     - kch: sd01332200 | ||||||
|  |       kxh: 100 | ||||||
|  |       channel: bx | ||||||
|  |     - kch: sd01332200 | ||||||
|  |       kxh: 100 | ||||||
|  |       channel: bx | ||||||
|  |   exit: | ||||||
|  |     kch: sd01332299 | ||||||
|  |     kxh: 100 | ||||||
|  |     channel: bx | ||||||
							
								
								
									
										23
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | { | ||||||
|  |   "name": "sdu-course-bot", | ||||||
|  |   "version": "1.0.0", | ||||||
|  |   "description": "", | ||||||
|  |   "main": "index.js", | ||||||
|  |   "scripts": { | ||||||
|  |     "test": "ts-node src/test.ts", | ||||||
|  |     "start": "ts-node src/index.ts" | ||||||
|  |   }, | ||||||
|  |   "author": "", | ||||||
|  |   "license": "ISC", | ||||||
|  |   "dependencies": { | ||||||
|  |     "@types/node": "^16.9.1", | ||||||
|  |     "@types/qs": "^6.9.7", | ||||||
|  |     "axios": "^0.21.4", | ||||||
|  |     "axios-retry": "^3.1.9", | ||||||
|  |     "dayjs": "^1.10.7", | ||||||
|  |     "qs": "^6.10.1", | ||||||
|  |     "ts-node": "^10.2.1", | ||||||
|  |     "typescript": "^4.4.3", | ||||||
|  |     "yaml": "^1.10.2" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										79
									
								
								src/actions.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/actions.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | |||||||
|  | import {ICourse} from "./types" | ||||||
|  | import {acquireCourse, exitCourse, findJsonCourse, getTimeNow, logAndNotifyUser, sleep} from "./includes" | ||||||
|  | import {JsonCourseList} from "./poll" | ||||||
|  |  | ||||||
|  | export async function monitProcess(course: ICourse) { | ||||||
|  |     let lastSyrs = -1 | ||||||
|  |     while (true) { | ||||||
|  |         let single = findJsonCourse(course) | ||||||
|  |         if (single == undefined) { | ||||||
|  |             console.log('[monit]无法找到课程 ' + course.kch + ' on channel ' + course.channel) | ||||||
|  |         } else { | ||||||
|  |             if (lastSyrs == -1) { | ||||||
|  |                 console.log('[monit]开始监控 ' + single.kcmc + ' ,当前剩余人数:' + single.syrs) | ||||||
|  |                 lastSyrs = parseInt(single.syrs) | ||||||
|  |             } else { | ||||||
|  |                 if (lastSyrs != parseInt(single.syrs)) { | ||||||
|  |                     logAndNotifyUser('[monit]' + single.kcmc + ' 新剩余人数:' + single.syrs + ' at ' + getTimeNow()) | ||||||
|  |                     lastSyrs = parseInt(single.syrs) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         await sleep(50) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export async function acquireProcess(course: ICourse) { | ||||||
|  |     while (true) { | ||||||
|  |         let single = findJsonCourse(course) | ||||||
|  |         if (single == undefined) { | ||||||
|  |             console.log('[acquire]无法找到课程 ' + course.kch + ' on channel ' + course.channel) | ||||||
|  |         } else { | ||||||
|  |             if (parseInt(single.syrs) > 0) { | ||||||
|  |                 logAndNotifyUser('[acquire]发现 ' + single.kcmc + ' 剩余人数为' + single.syrs + ',进行抢课 at ' + getTimeNow()) | ||||||
|  |                 if (await acquireCourse(single, course.channel)) { | ||||||
|  |                     logAndNotifyUser('[acquire]抢课成功 ' + single.kcmc + ' at ' + getTimeNow()) | ||||||
|  |                     return | ||||||
|  |                 } else { | ||||||
|  |                     logAndNotifyUser('[acquire]抢课失败 ' + single.kcmc + ' at ' + getTimeNow()) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         await sleep(50) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export async function replaceProcess(courseList: ICourse[], exit: ICourse) { | ||||||
|  |     while (true) { | ||||||
|  |         let exitJsonCourse = findJsonCourse(exit) | ||||||
|  |         if (exitJsonCourse == undefined) { | ||||||
|  |             console.log('[replace]找不到需要需要退课的课程 ' + exit.kch + ' on channel ' + exit.channel) | ||||||
|  |         } else { | ||||||
|  |             for (let course of courseList) { | ||||||
|  |                 let single = findJsonCourse(course) | ||||||
|  |                 if (single == undefined) { | ||||||
|  |                     console.log('[replace]无法找到课程 ' + course.kch + ' on channel ' + course.channel) | ||||||
|  |                     continue | ||||||
|  |                 } | ||||||
|  |                 if (parseInt(single.syrs) > 0) { | ||||||
|  |                     logAndNotifyUser('[replace]发现 ' + single.kcmc + ' 剩余人数为' + single.syrs + ',进行换课 at ' + getTimeNow()) | ||||||
|  |                     if (!(await exitCourse(exitJsonCourse, exit.channel))) { | ||||||
|  |                         logAndNotifyUser('[replace]退课 ' + exitJsonCourse.kcmc + ' 失败 at ' + getTimeNow()) | ||||||
|  |                     } | ||||||
|  |                     if (await acquireCourse(single, course.channel)) { | ||||||
|  |                         logAndNotifyUser('[replace]换课 ' + single.kcmc + ' 成功 at ' + getTimeNow()) | ||||||
|  |                         return | ||||||
|  |                     } else { | ||||||
|  |                         logAndNotifyUser('[replace]选课 ' + single.kcmc + ' 失败,进行回滚 at ' + getTimeNow()) | ||||||
|  |                         if (await acquireCourse(exitJsonCourse, exit.channel)) { | ||||||
|  |                             logAndNotifyUser('[replace]回滚 ' + single.kcmc + ' 成功 at ' + getTimeNow()) | ||||||
|  |                         } else { | ||||||
|  |                             logAndNotifyUser('[replace]回滚 ' + single.kcmc + ' 失败 at ' + getTimeNow()) | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         await sleep(50) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								src/config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/config.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | import yaml from "yaml" | ||||||
|  | import * as fs from "fs" | ||||||
|  | import {IAppConfig, TChannel} from "./types" | ||||||
|  |  | ||||||
|  | let appConfig: IAppConfig = yaml.parse(fs.readFileSync('config.yaml', 'utf-8')) | ||||||
|  | let channels: TChannel[] = [] | ||||||
|  | for (let course of appConfig.monit?.list || []) { | ||||||
|  |     if (!channels.includes(course.channel)) { | ||||||
|  |         channels.push(course.channel) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | for (let course of appConfig.acquire?.list || []) { | ||||||
|  |     if (!channels.includes(course.channel)) { | ||||||
|  |         channels.push(course.channel) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | if (appConfig.replace) { | ||||||
|  |     for (let course of appConfig.replace.list) { | ||||||
|  |         if (!channels.includes(course.channel)) { | ||||||
|  |             channels.push(course.channel) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | appConfig.channels = channels | ||||||
|  | export {appConfig} | ||||||
							
								
								
									
										66
									
								
								src/includes.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/includes.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | import axios from 'axios' | ||||||
|  | import {appConfig} from "./config" | ||||||
|  | import * as qs from "qs" | ||||||
|  | import dayjs from "dayjs" | ||||||
|  | import {ICourse, IJsonCourse, TChannel} from "./types" | ||||||
|  | import {JsonCourseList} from "./poll" | ||||||
|  | import axiosRetry from "axios-retry" | ||||||
|  |  | ||||||
|  | let sduAxios = axios.create({ | ||||||
|  |     headers: { | ||||||
|  |         'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||||||
|  |         'Cookie': appConfig.cookie | ||||||
|  |     }, | ||||||
|  |     baseURL: 'https://bkzhjx.wh.sdu.edu.cn/', | ||||||
|  |     timeout: 5, | ||||||
|  |     // maxRedirects: 0 | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | axiosRetry(sduAxios, { | ||||||
|  |     retries: 2, | ||||||
|  |     shouldResetTimeout: true, | ||||||
|  |     retryCondition: (_error) => true, | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | export async function logAndNotifyUser(text: string) { | ||||||
|  |     console.log(text) | ||||||
|  |     await axios.post('https://qmsg.zendee.cn/send/' + appConfig.qmsgKey, qs.stringify({ | ||||||
|  |         msg: text | ||||||
|  |     }), { | ||||||
|  |         headers: { | ||||||
|  |             'Content-Type': 'application/x-www-form-urlencoded' | ||||||
|  |         } | ||||||
|  |     }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function sleep(ms: number) { | ||||||
|  |     return new Promise(resolve => setTimeout(resolve, ms)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function getTimeNow() { | ||||||
|  |     return dayjs().format('hh:mm:ss A') | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function findJsonCourse(course: ICourse): IJsonCourse | undefined { | ||||||
|  |     return JsonCourseList[course.channel].find(single => single.kch == course.kch && parseInt(single.kxh) == course.kxh) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export async function acquireCourse(course: IJsonCourse, channel: TChannel): Promise<boolean> { | ||||||
|  |     if (channel == 'bx' || channel == 'xx') { | ||||||
|  |  | ||||||
|  |     } else { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |     return true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export async function exitCourse(course: IJsonCourse, channel: TChannel): Promise<boolean> { | ||||||
|  |     if (channel == 'bx' || channel == 'xx') { | ||||||
|  |  | ||||||
|  |     } else { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |     return true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export {sduAxios} | ||||||
							
								
								
									
										35
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | import {JsonCourseList, poll} from "./poll" | ||||||
|  | import {appConfig} from "./config" | ||||||
|  | import {acquireProcess, monitProcess, replaceProcess} from "./actions" | ||||||
|  | import {sleep} from "./includes" | ||||||
|  |  | ||||||
|  | async function start() { | ||||||
|  |     console.log('开始启动轮询进程') | ||||||
|  |     poll() | ||||||
|  |     while (true) { | ||||||
|  |         let pollInitComplete = true | ||||||
|  |         for (let channel of appConfig.channels) { | ||||||
|  |             if (JsonCourseList[channel].length == 0) { | ||||||
|  |                 pollInitComplete = false | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if (pollInitComplete) { | ||||||
|  |             break | ||||||
|  |         } | ||||||
|  |         await sleep(50) | ||||||
|  |     } | ||||||
|  |     console.log('轮询进程启动完毕') | ||||||
|  |     console.log('开始启动用户进程') | ||||||
|  |     for (let course of appConfig.monit?.list || []) { | ||||||
|  |         monitProcess(course) | ||||||
|  |     } | ||||||
|  |     for (let course of appConfig.acquire?.list || []) { | ||||||
|  |         acquireProcess(course) | ||||||
|  |     } | ||||||
|  |     if (appConfig.replace) { | ||||||
|  |         replaceProcess(appConfig.replace.list, appConfig.replace.exit) | ||||||
|  |     } | ||||||
|  |     console.log('用户进程启动完毕') | ||||||
|  | } | ||||||
|  |  | ||||||
|  | start() | ||||||
							
								
								
									
										79
									
								
								src/poll.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/poll.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | |||||||
|  | import {IJsonCourse} from "./types" | ||||||
|  | import {getTimeNow, sduAxios, sleep} from "./includes" | ||||||
|  | import {appConfig} from "./config" | ||||||
|  | import * as qs from "qs" | ||||||
|  |  | ||||||
|  | let reqData = [ | ||||||
|  |     {"name": "sEcho", "value": "1"}, | ||||||
|  |     {"name": "iColumns", "value": "2000"},// 1 | ||||||
|  |     {"name": "sColumns", "value": ""}, | ||||||
|  |     {"name": "iDisplayStart", "value": "0"}, | ||||||
|  |     {"name": "iDisplayLength", "value": "2000"},// 1 | ||||||
|  |     {"name": "mDataProp_0", "value": "kch"}, | ||||||
|  |     {"name": "mDataProp_1", "value": "kcmc"}, | ||||||
|  |     {"name": "mDataProp_2", "value": "kxhnew"}, | ||||||
|  |     {"name": "mDataProp_3", "value": "jkfs"}, | ||||||
|  |     {"name": "mDataProp_4", "value": "xmmc"}, | ||||||
|  |     {"name": "mDataProp_5", "value": "xf"}, | ||||||
|  |     {"name": "mDataProp_6", "value": "skls"}, | ||||||
|  |     {"name": "mDataProp_7", "value": "sksj"}, | ||||||
|  |     {"name": "mDataProp_8", "value": "skdd"}, | ||||||
|  |     {"name": "mDataProp_9", "value": "xqmc"}, | ||||||
|  |     {"name": "mDataProp_10", "value": "xkrs"}, | ||||||
|  |     {"name": "mDataProp_11", "value": "syrs"}, | ||||||
|  |     {"name": "mDataProp_12", "value": "ctsm"}, | ||||||
|  |     {"name": "mDataProp_13", "value": "szkcflmc"}, | ||||||
|  |     {"name": "mDataProp_14", "value": "czOper"} | ||||||
|  | ] | ||||||
|  | export const JsonCourseList = <{ bx: IJsonCourse[], xx: IJsonCourse[], rx: IJsonCourse[] }>{ | ||||||
|  |     bx: [], | ||||||
|  |     xx: [], | ||||||
|  |     rx: [] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function updateBx() { | ||||||
|  |     try { | ||||||
|  |         let resp = await sduAxios.post('/jsxsd/xsxkkc/xsxkBxxk?1=1&kcxx=&skls=&skfs=', qs.stringify(reqData)) | ||||||
|  |         JsonCourseList.bx.length = 0 | ||||||
|  |         JsonCourseList.bx.push(...resp.data.aaData) | ||||||
|  |         console.log('更新必修JsonList成功') | ||||||
|  |     } catch (e) { | ||||||
|  |         console.log('获取必修JsonList失败 at ' + getTimeNow()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function updateXx() { | ||||||
|  |     try { | ||||||
|  |         let resp = await sduAxios.post('/jsxsd/xsxkkc/xsxkXxxk?1=1&kcxx=&skls=&skfs=', qs.stringify(reqData)) | ||||||
|  |         JsonCourseList.xx.length = 0 | ||||||
|  |         JsonCourseList.xx.push(...resp.data.aaData) | ||||||
|  |     } catch (e) { | ||||||
|  |         console.log('获取限选JsonList失败 at ' + getTimeNow()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function updateRx() { | ||||||
|  |     try { | ||||||
|  |         let resp = await sduAxios.post('/jsxsd/xsxkkc/xsxkGgxxkxk?kcxx=&skls=&skxq=&skjc=&sfym=false&sfct=false&szjylb=&sfxx=false&skfs=', qs.stringify(reqData)) | ||||||
|  |         JsonCourseList.rx.length = 0 | ||||||
|  |         JsonCourseList.rx.push(...resp.data.aaData) | ||||||
|  |     } catch (e) { | ||||||
|  |         console.log('获取任选JsonList失败 at ' + getTimeNow()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export async function poll() { | ||||||
|  |     if (appConfig.channels.includes('bx')) { | ||||||
|  |         await updateBx() | ||||||
|  |         await sleep(appConfig.interval) | ||||||
|  |     } | ||||||
|  |     if (appConfig.channels.includes('xx')) { | ||||||
|  |         await updateXx() | ||||||
|  |         await sleep(appConfig.interval) | ||||||
|  |     } | ||||||
|  |     if (appConfig.channels.includes('rx')) { | ||||||
|  |         await updateRx() | ||||||
|  |         await sleep(appConfig.interval) | ||||||
|  |     } | ||||||
|  |     setImmediate(poll) | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								src/test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | import {appConfig} from "./config" | ||||||
|  |  | ||||||
|  | console.log('channels: ' + appConfig.channels) | ||||||
|  | for (let course of appConfig.monit?.list || []) { | ||||||
|  |     console.log('添加监控课程 ' + course.kch + ' on channel ' + course.channel) | ||||||
|  | } | ||||||
|  | for (let course of appConfig.acquire?.list || []) { | ||||||
|  |     console.log('添加抢课课程 ' + course.kch + ' on channel ' + course.channel) | ||||||
|  | } | ||||||
|  | if (appConfig.replace) { | ||||||
|  |     console.log('添加退课课程 ' + appConfig.replace.exit.kch + ' on channel ' + appConfig.replace.exit.channel) | ||||||
|  |     for (let course of appConfig.replace.list) { | ||||||
|  |         console.log('添加换课课程 ' + course.kch + ' on channel ' + course.channel) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										91
									
								
								src/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/types.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | |||||||
|  | export type TChannel = 'bx' | 'xx' | 'rx' | ||||||
|  |  | ||||||
|  | export interface ICourse { | ||||||
|  |     kch: string, | ||||||
|  |     kxh: number, | ||||||
|  |     channel: TChannel | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface IAppConfig { | ||||||
|  |     cookie: string, | ||||||
|  |     qmsgKey: string, | ||||||
|  |     interval: number, | ||||||
|  |     channels: TChannel[], | ||||||
|  |     monit?: { | ||||||
|  |         list: ICourse[] | ||||||
|  |     }, | ||||||
|  |     acquire?: { | ||||||
|  |         list: ICourse[] | ||||||
|  |     }, | ||||||
|  |     replace?: { | ||||||
|  |         list: ICourse[], | ||||||
|  |         exit: ICourse | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface IJsonCourse { | ||||||
|  |     parentjx0404id: null; | ||||||
|  |     mfkc: string; | ||||||
|  |     ksfs: string; | ||||||
|  |     jx02kcmkid: null; | ||||||
|  |     ktmc: string; | ||||||
|  |     tzdlb: string; | ||||||
|  |     kcsx: string; | ||||||
|  |     skfs: string; | ||||||
|  |     kch: string; | ||||||
|  |     syrs: string; | ||||||
|  |     kxh: string; | ||||||
|  |     sksj: string; | ||||||
|  |     szkcfl: string; | ||||||
|  |     kcjj: null; | ||||||
|  |     skfsmc: string; | ||||||
|  |     wlpt: null; | ||||||
|  |     kcxzmc: string; | ||||||
|  |     kexuhao: null; | ||||||
|  |     xbyq: null; | ||||||
|  |     sftk: null; | ||||||
|  |     kkdw: string; | ||||||
|  |     kcxzm: string; | ||||||
|  |     szkcflmc: string; | ||||||
|  |     xnxq01id: string; | ||||||
|  |     dwmc: string; | ||||||
|  |     kxhnew: string; | ||||||
|  |     pkrs: number; | ||||||
|  |     xkrs: number; | ||||||
|  |     fzmc: null; | ||||||
|  |     cfbs: null; | ||||||
|  |     kcmc: string; | ||||||
|  |     xyxsnj: null; | ||||||
|  |     kkapList: KkapList[]; | ||||||
|  |     dyrsbl: null; | ||||||
|  |     isnetworkcourse: string; | ||||||
|  |     sklsid: string; | ||||||
|  |     skls: string; | ||||||
|  |     xqid: string; | ||||||
|  |     sfkfxk: string; | ||||||
|  |     skdd: string; | ||||||
|  |     xf: number; | ||||||
|  |     skdws: null; | ||||||
|  |     txsfkxq: string; | ||||||
|  |     xmmc: null; | ||||||
|  |     zxs: number; | ||||||
|  |     jx0404id: string; | ||||||
|  |     xqmc: string; | ||||||
|  |     jx02id: string; | ||||||
|  |     xbyqmc: null; | ||||||
|  |     jkfs: null; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface KkapList { | ||||||
|  |     jssj: string; | ||||||
|  |     jzwmc: string; | ||||||
|  |     jgxm: string; | ||||||
|  |     skjcmc: string; | ||||||
|  |     skzcList: string[]; | ||||||
|  |     xq: string; | ||||||
|  |     kbjcmsid: string; | ||||||
|  |     kkzc: string; | ||||||
|  |     kssj: string; | ||||||
|  |     jsmc: string; | ||||||
|  |     kkdlb: string; | ||||||
|  | } | ||||||
							
								
								
									
										86
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | { | ||||||
|  |   "compilerOptions": { | ||||||
|  |     /* Visit https://aka.ms/tsconfig.json to read more about this file */ | ||||||
|  |  | ||||||
|  |     /* Basic Options */ | ||||||
|  |     // "incremental": true,                         /* Enable incremental compilation */ | ||||||
|  |     "target": "ES2016", | ||||||
|  |     /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ | ||||||
|  |     "module": "commonjs", | ||||||
|  |     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ | ||||||
|  |     // "lib": [],                                   /* Specify library files to be included in the compilation. */ | ||||||
|  |     "allowJs": true, | ||||||
|  |     /* Allow javascript files to be compiled. */ | ||||||
|  |     // "checkJs": true,                             /* Report errors in .js files. */ | ||||||
|  |     // "jsx": "preserve",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ | ||||||
|  |     // "declaration": true,                         /* Generates corresponding '.d.ts' file. */ | ||||||
|  |     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */ | ||||||
|  |     // "sourceMap": true,                           /* Generates corresponding '.map' file. */ | ||||||
|  |     // "outFile": "./",                             /* Concatenate and emit output to single file. */ | ||||||
|  |     "outDir": "./build", | ||||||
|  |     /* Redirect output structure to the directory. */ | ||||||
|  |     "rootDir": "./src", | ||||||
|  |     /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ | ||||||
|  |     // "composite": true,                           /* Enable project compilation */ | ||||||
|  |     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */ | ||||||
|  |     // "removeComments": true,                      /* Do not emit comments to output. */ | ||||||
|  |     // "noEmit": true,                              /* Do not emit outputs. */ | ||||||
|  |     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */ | ||||||
|  |     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ | ||||||
|  |     // "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ | ||||||
|  |  | ||||||
|  |     /* Strict Type-Checking Options */ | ||||||
|  |     "strict": true, | ||||||
|  |     /* Enable all strict type-checking options. */ | ||||||
|  |     // "noImplicitAny": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */ | ||||||
|  |     // "strictNullChecks": true,                    /* Enable strict null checks. */ | ||||||
|  |     // "strictFunctionTypes": true,                 /* Enable strict checking of function types. */ | ||||||
|  |     // "strictBindCallApply": true,                 /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ | ||||||
|  |     // "strictPropertyInitialization": true,        /* Enable strict checking of property initialization in classes. */ | ||||||
|  |     // "noImplicitThis": true,                      /* Raise error on 'this' expressions with an implied 'any' type. */ | ||||||
|  |     // "alwaysStrict": true,                        /* Parse in strict mode and emit "use strict" for each source file. */ | ||||||
|  |  | ||||||
|  |     /* Additional Checks */ | ||||||
|  |     // "noUnusedLocals": true,                      /* Report errors on unused locals. */ | ||||||
|  |     // "noUnusedParameters": true,                  /* Report errors on unused parameters. */ | ||||||
|  |     // "noImplicitReturns": true,                   /* Report error when not all code paths in function return a value. */ | ||||||
|  |     // "noFallthroughCasesInSwitch": true,          /* Report errors for fallthrough cases in switch statement. */ | ||||||
|  |     // "noUncheckedIndexedAccess": true,            /* Include 'undefined' in index signature results */ | ||||||
|  |     // "noPropertyAccessFromIndexSignature": true,  /* Require undeclared properties from index signatures to use element accesses. */ | ||||||
|  |  | ||||||
|  |     /* Module Resolution Options */ | ||||||
|  |     // "moduleResolution": "node",                  /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ | ||||||
|  |     // "baseUrl": "./",                             /* Base directory to resolve non-absolute module names. */ | ||||||
|  |     // "paths": {},                                 /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ | ||||||
|  |     // "rootDirs": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */ | ||||||
|  |     "typeRoots": [ | ||||||
|  |       //      "./node_modules/**/*", | ||||||
|  |       "./node_modules/@types" | ||||||
|  |     ], | ||||||
|  |     /* List of folders to include type definitions from. */ | ||||||
|  |     // "types": [],                                 /* Type declaration files to be included in compilation. */ | ||||||
|  |     // "allowSyntheticDefaultImports": true,        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ | ||||||
|  |     "esModuleInterop": true, | ||||||
|  |     /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ | ||||||
|  |     // "preserveSymlinks": true,                    /* Do not resolve the real path of symlinks. */ | ||||||
|  |     // "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */ | ||||||
|  |  | ||||||
|  |     /* Source Map Options */ | ||||||
|  |     // "sourceRoot": "",                            /* Specify the location where debugger should locate TypeScript files instead of source locations. */ | ||||||
|  |     // "mapRoot": "",                               /* Specify the location where debugger should locate map files instead of generated locations. */ | ||||||
|  |     // "inlineSourceMap": true,                     /* Emit a single file with source maps instead of having a separate file. */ | ||||||
|  |     // "inlineSources": true,                       /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ | ||||||
|  |  | ||||||
|  |     /* Experimental Options */ | ||||||
|  |     "experimentalDecorators": true, | ||||||
|  |     /* Enables experimental support for ES7 decorators. */ | ||||||
|  |     "emitDecoratorMetadata": true, | ||||||
|  |     /* Enables experimental support for emitting type metadata for decorators. */ | ||||||
|  |  | ||||||
|  |     /* Advanced Options */ | ||||||
|  |     "skipLibCheck": true, | ||||||
|  |     /* Skip type checking of declaration files. */ | ||||||
|  |     "forceConsistentCasingInFileNames": true | ||||||
|  |     /* Disallow inconsistently-cased references to the same file. */ | ||||||
|  |   } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user