import { countdown, getAssessmentForm, getAssessmentList, getClassroomList, getClassroomState, getUserInfo, getPhysicalExamResult, getReport, postAssessmentForm, getBankPayment, getCalendar, getInvoiceList, getInvoicePDF, switchLang, naiveSendMail, getCalendarImageUrl, } from "./lib/basics"; import {login, logout} from "./lib/core"; import {getDormScore, getElePayRecord, getEleRechargePayCode, getEleRemainder, resetDormPassword} from "./lib/dorm"; import {getUserInformation, getUserInformationAndStore, postWaterSubmission} from "./lib/water"; import { LibBookRecord, LibFuzzySearchResult, Library, LibraryFloor, LibrarySeat, LibrarySection, LibRoomBookRecord, LibRoomRes, SocketStatus, } from "./models/home/library"; import { bookLibraryRoom, bookLibrarySeat, cancelBooking, cancelLibraryRoomBooking, fuzzySearchLibraryId, getBookingRecords, getLibraryFloorList, getLibraryList, getLibraryRoomBookingInfoList, getLibraryRoomBookingRecord, getLibraryRoomBookingResourceList, getLibrarySeatList, getLibrarySectionList, getAccNo, cabLogin, toggleSocketState, } from "./lib/library"; import { addNewsSubscription, addNewsToFavor, getFavorNewsList, getNewsChannelList, getNewsDetail, getNewsList, getNewsListBySubscription, getNewsSourceList, getNewsSubscriptionList, removeNewsFromFavor, removeNewsSubscription, searchNewsList, } from "./lib/news"; import {getSchedule} from "./lib/schedule"; import {Course} from "./models/home/report"; import {Form} from "./models/home/assessment"; import {NewsSlice, NewsSubscription, ChannelTag} from "./models/news/news"; import { getSportsCaptchaUrlMethod, getSportsReservationRecords, getSportsResources, makeSportsReservation, paySportsReservation, unsubscribeSportsReservation, updateSportsPhoneNumber, ValidReceiptTypes, } from "./lib/sports"; import { getCrTimetable, getCrCaptchaUrl, getCoursePlan, loginCr, searchCrRemaining, searchCrPrimaryOpen, searchCrCourses, getCrAvailableSemesters, selectCourse, Priority, deleteCourse, getSelectedCourses, changeCourseWill, searchCoursePriorityInformation, searchCoursePriorityMeta, getCrCurrentStage, getQueueInfo, cancelCoursePF, setCoursePF, } from "./lib/cr"; import {CrTimetable, SearchCoursePriorityQuery, SearchParams} from "./models/cr/cr"; import {BankPaymentByMonth} from "./models/home/bank"; import { getNamespaces, getPersonalProjects, getProjectBranches, getProjectDetail, getProjectFileBlob, getProjectTree, getRecentProjects, getStarredProjects, renderMarkdown, searchProjects, } from "./lib/gitlab"; import {CalendarData} from "./models/schedule/calendar"; import {bookDetail, downloadChapters, searchReservesLib} from "./lib/reserves-lib"; import {BookChapter} from "./models/home/reserves-lib"; import {Invoice} from "./models/home/invoice"; import {LoginError} from "./utils/error"; import {getDegreeProgramCompletion, getFullDegreeProgram} from "./lib/program"; import {Classroom, ClassroomStateResult} from "./models/home/classroom"; import { getFeedbackReplies, getLatestAnnounces, getLatestVersion, getPrivacyUrl, getWeChatGroupQRCodeContent, submitFeedback, } from "./lib/app"; import {MOCK_LATEST_VERSION} from "./mocks/app"; import {APP_STARTUP_STAT_URL, APP_USAGE_STAT_URL} from "./constants/strings"; import {uFetch} from "./utils/network"; import {getNetworkBalance, getNetworkDetail, getOnlineDevices} from "./lib/network"; import {getScoreByCourseId} from "./lib/thos"; import { canRechargeCampusCard, cardCancelLoss, cardChangeTransactionPassword, cardGetInfo, cardGetPhotoUrl, cardGetTransactions, cardLogin, cardModifyMaxTransactionAmount, cardRechargeFromBank, cardRechargeFromWechatAlipay, cardReportLoss, } from "./lib/card"; import {CardTransactionType} from "./models/card/transaction"; import {CardRechargeType} from "./models/card/recharge"; export class InfoHelper { public userId = ""; public password = ""; /** * Mock account and password. * * Due to various reasons, consumers of this library might hope to get * some fake data, without literally making a request to the school * website. * * We make this possible by creating an internal mocking account. The * default userId and password of this account are both "8888", while you * can change this behavior by modifying `helper.MOCK`. * * After you have logged in with the mocking account, almost every * operation will respond with a fake value. * * You can easily get whether the user is using a mocking account by * invoking `helper.mocked()`. */ public MOCK = "8888"; /** * We consider an account to be mocked if its userId and password are both "8888". */ public mocked = () => this.userId === this.MOCK && this.password === this.MOCK; /** * Returns whether the user is graduate. * * We detect a user's graduation status through the fifth digit (index 4) of his/her student ID. * * That is, we think a user is graduate iff the fifth digit of his/her student ID is 2 or 3. */ public graduate = () => this.userId.length > 4 ? (this.userId[4] === "2" || this.userId[4] === "3") : false; /** * Invoked before logging in. * * Override this value to customize. */ public clearCookieHandler = async () => { }; /** * Invoked when a login error occurs. * * Override this value to customize. */ public loginErrorHook: ((e: LoginError) => any) | undefined = undefined; /** * Login with userId and password. */ public login = async ( auth: { userId?: string; password?: string; }, ): Promise => login(this, auth.userId ?? this.userId, auth.password ?? this.password); /** * Log out and clear fields `userId` and `password` of this `InfoHelper` instance */ public logout = async (): Promise => logout(this); /** * THIS METHOD IS INTENDED FOR APP USE ONLY. * * ANY BREAKING CHANGES SHALL NOT BE DOCUMENTED. */ public appStartUp = async (platform: "ios" | "android") => { if (this.userId === "") { return { bookingRecords: [], sportsReservationRecords: [], crTimetable: [], balance: 0, latestAnnounces: [], latestVersion: MOCK_LATEST_VERSION, }; } const latestAnnounces = await getLatestAnnounces(this); const latestVersion = await getLatestVersion(this, platform); const bookingRecords = await getBookingRecords(this); const sportsReservationRecords = await getSportsReservationRecords(this); let balance: number = 0; try { balance = (await cardGetInfo(this)).balance; } catch { // no-op } uFetch(APP_STARTUP_STAT_URL).catch(() => { }); let crTimetable: CrTimetable[] = []; try { crTimetable = await getCrTimetable(this); } catch { // no-op } return {bookingRecords, sportsReservationRecords, crTimetable, balance, latestAnnounces, latestVersion}; }; public appUsageStat = async (usage: number) => { await uFetch(`${APP_USAGE_STAT_URL}/${usage}`); }; public getLatestAnnounces = async () => getLatestAnnounces(this); public getLatestVersion = async (platform: "ios" | "android") => getLatestVersion(this, platform); public submitFeedback = async ( content: string, appversion: string, os: string, nickname: string, contact: string, phonemodel: string, ) => submitFeedback(this, content, appversion, os, nickname, contact, phonemodel); public getFeedbackReplies = async () => getFeedbackReplies(this); public getWeChatGroupQRCodeContent = async () => getWeChatGroupQRCodeContent(this); public getPrivacyUrl = () => getPrivacyUrl(this); /** * Switch the language. * * This will affect the language of data returned from some APIs. * * @param lang either "zh" or "en" */ public switchLang = async (lang: "zh" | "en"): Promise => switchLang(this, lang); /** * Get the user's full name and email name (i.e. username for email * account) */ public getUserInfo = async () => getUserInfo(this); /** * A naive API that sends an email from the user's Tsinghua mail. * @param subject Subject of email * @param content Content of email * @param recipient Recipient of email. Sending an email to multiple * recipients is not supported yet. */ public naiveSendMail = async (subject: string, content: string, recipient: string) => naiveSendMail(this, subject, content, recipient); /** * Get the school report of the user. * * @param bx a boolean indicating whether to contain only required and * restricted courses (and omit elective courses) * @param newGPA a boolean indicating whether to adopt the new GPA policy * @param flag switch between first degree (1), second degree (2) and * minor courses (3), defaults to 1 * * Note that `bx` takes effect only if `flag` equals to `1` */ public getReport = ( bx: boolean, newGPA: boolean, flag = 1, ): Promise => getReport(this, bx, newGPA, flag); /** * Get the assessment list of teaching evaluation. * * @return An array of courses. Each course is represented with a * three-element tuple, referring to name of course, whether * the course has been evaluated and the url of its evaluation * form (which can then be passed into `getAssessmentForm`. */ public getAssessmentList = (): Promise<[string, boolean, string][]> => getAssessmentList(this); /** * Get the evaluation form of a course from its url. * @param url the corresponding form url to the course to evaluate */ public getAssessmentForm = (url: string): Promise
=> getAssessmentForm(this, url); /** * Submit the evaluation form. */ public postAssessmentForm = (form: Form): Promise => postAssessmentForm(this, form); /** * Get the physical exam score of the user. * * @return Returns a [string, string][], where the first string refers to * the exam item, and the second refers to the exam score. */ public getPhysicalExamResult = (): Promise<[string, string][]> => getPhysicalExamResult(this); /** * Get all classroom buildings available for querying for classroom status. * * Note that you should use `searchName` from the returned struct for * future querying. */ public getClassroomList = (): Promise => getClassroomList(this); /** * Get the classroom state of specific classroom building and week number. * @param building a string representing the queried building * @param week a number representing the queried week number */ public getClassroomState = ( building: string, week: number, ): Promise => getClassroomState(this, building, week); /** * Get the list of invoices. * * This API is paginated. * * @param page page number, starting from 1 */ public getInvoiceList = async (page: number): Promise<{ data: Invoice[]; count: number }> => getInvoiceList(this, page); /** * Get the invoice PDF in base64 format. */ public getInvoicePDF = async (busNumber: string): Promise => getInvoicePDF(this, busNumber); /** * Get the bank payment records of the user. * @param foundation whether to get bank payment result by 基金会 or not */ public getBankPayment = async (foundation = false): Promise => getBankPayment(this, foundation); /** * Get the school calendar data. */ public getCalendar = async (): Promise => getCalendar(this); /** * Get the school calendar image url */ public getCalendarImageUrl = async (year: number, semester: "spring" | "autumn", lang: "zh" | "en") => getCalendarImageUrl(this, year, semester, lang); /** * Get the current countdown notifications from INFO. */ public getCountdown = async (): Promise => countdown(this); /** * Get the dorm score image, in base64 format. * @param dormPassword password for myhome.tsinghua.edu.cn */ public getDormScore = async (dormPassword: string): Promise => getDormScore(this, dormPassword); /** * Make an electricity recharge payment order, and get the pay-code of the * order. * * If you want to use the pay-code on mobile devices, the url link to the * Alipay payment page will be * `"alipayqr://platformapi/startapp?saId=10000007&qrcode=https%3A%2F%2Fqr.alipay.com%2F" + payCode` * * You can also call `genAlipayUrl(payCode)` in `dist/utils/alipay` to get * the Alipay url. * * @param money a number representing the amount of money to be paid * (in yuan, must be integer) */ public getEleRechargePayCode = async (money: number): Promise => getEleRechargePayCode(this, money); /** * Get the recent ele-recharge records. * * @return Returns `[string, string, string, string, string, string][]`, * where the six strings represent name, id, time, channel, value * and status respectively. */ public getElePayRecord = async (): Promise<[string, string, string, string, string, string][]> => getElePayRecord(this); /** * Get the current remainder of electricity. * * @return Returns a number. The return value can be NaN when the remainder * info cannot be parsed. */ public getEleRemainder = async (): Promise<{ remainder: number; updateTime: string }> => getEleRemainder(this); /** * Reset dorm password. * * This method works on the basis that myhome.tsinghua.edu.cn can be logged * in with INFO account, and the dorm password can therefore be reset, * without the need of a original password. * * @param newPassword The new dorm password */ public resetDormPassword = async (newPassword: string): Promise => resetDormPassword(this, newPassword); public getLibraryList = async (): Promise => getLibraryList(this); public getLibrarySectionList = async ( libraryFloor: LibraryFloor, dateChoice: 0 | 1, // 0 for today and 1 for tomorrow ): Promise => getLibrarySectionList(this, libraryFloor, dateChoice); public getLibraryFloorList = async ( library: Library, dateChoice: 0 | 1, // 0 for today and 1 for tomorrow ): Promise => getLibraryFloorList(this, library, dateChoice); public getLibrarySeatList = async ( librarySection: LibrarySection, dateChoice: 0 | 1, // 0 for today and 1 for tomorrow ): Promise => getLibrarySeatList(this, librarySection, dateChoice); public toggleSocketState = async ( seatId: number, target: SocketStatus, ): Promise => toggleSocketState(this, seatId, target); /** * Use this API to book library seats. */ public bookLibrarySeat = async ( librarySeat: LibrarySeat, section: LibrarySection, dateChoice: 0 | 1, // 0 for today and 1 for tomorrow ): Promise<{ status: number; msg: string }> => bookLibrarySeat(this, librarySeat, section, dateChoice); /** * Use this API to get booking records. */ public getBookingRecords = async (): Promise => getBookingRecords(this); /** * Use this API to cancel booking. * @param id the `id` from `LibBookRecord` */ public cancelBooking = async (id: string): Promise => cancelBooking(this, id); /** * DEPRECATED. */ public getLibraryRoomBookingCaptchaUrl = () => Promise.resolve(""); /** * Use this API to get the account number of current user. * * The account number is used to book rooms. */ public getLibraryRoomAccNo = () => getAccNo(); /** * Login cab.hs.lib.tsinghua.edu.cn */ public loginLibraryRoomBooking = async () => cabLogin(this); /** * Gets all available room information */ public getLibraryRoomBookingInfoList = async () => getLibraryRoomBookingInfoList(this); /** * Gets all available room resources * @param date yyyyMMdd * @param kindId * @return Returns a list of all available room resources of a specific * date, along with when and for whom each room is reserved. */ public getLibraryRoomBookingResourceList = async ( date: string, // yyyyMMdd kindId: number, ): Promise => getLibraryRoomBookingResourceList(this, date, kindId); /** * Passes a student's name as keyword and returns the student's ID. * * FUZZY SEARCH IS NO LONGER SUPPORTED. Method name remains unchanged only * for compatability reasons. * * @param keyword a string that serves as the search keyword */ public fuzzySearchLibraryId = async ( keyword: string ): Promise => fuzzySearchLibraryId(this, keyword); /** * Performs a booking request of a library room. * * @param roomRes a `LibRoomRes` object referring to the room that is requested for booking * @param start the beginning time of booking, in format `yyyy-MM-dd HH:mm:SS` where `mm` should be a multiple of 5 and `SS` should be `00` * @param end the ending time of booking, in format `yyyy-MM-dd HH:mm:SS` where `mm` should be a multiple of 5 and `SS` should be `00` * @param memberList a list of strings */ public bookLibraryRoom = async ( roomRes: LibRoomRes, start: string, // yyyy-MM-dd HH:mm end: string, // yyyy-MM-dd HH:mm memberList: number[], // student id's, empty for single user ) => bookLibraryRoom(this, roomRes, start, end, memberList); /** * Returns all active booking records. */ public getLibraryRoomBookingRecord = async (): Promise => getLibraryRoomBookingRecord(this); /** * Cancels a specific library booking record. * @param uuid `uuid` of `LibRoomBookRecord` */ public cancelLibraryRoomBooking = async (uuid: string) => cancelLibraryRoomBooking(this, uuid); /** * Get the news list of all channels or a specific channel. * * This API is paginated. */ public getNewsList = async ( page: number, length: number, channel?: ChannelTag ): Promise => getNewsList(this, page, length, channel); /** * Search the news list with a keyword. * * This API is paginated. */ public searchNewsList = async ( page: number, key: string, channel?: ChannelTag ): Promise => searchNewsList(this, page, key, channel, true); /** * Get all news subscription items. */ public getNewsSubscriptionList = async (): Promise => getNewsSubscriptionList(this); /** * Get all available news sources for subscription. */ public getNewsSourceList = async (): Promise<{ sourceId: string, sourceName: string }[]> => getNewsSourceList(this); /** * Get all available news channels for subscription. * @param needEnglish */ public getNewsChannelList = async (needEnglish: boolean): Promise<{ id: ChannelTag, title: string }[]> => getNewsChannelList(this, needEnglish); /** * if channelId and sourceId is null or undefined at the same time, this function will terminate and return false. * @param channelId channel id * @param sourceId source id * @param keyword news keyword * @returns */ public addNewsSubscription = async (channelId?: ChannelTag, sourceId?: string, keyword?: string): Promise => addNewsSubscription(this, channelId, sourceId, keyword); /** * Remove a news subscription. * @param subscriptionId */ public removeNewsSubscription = async (subscriptionId: string): Promise => removeNewsSubscription(this, subscriptionId); /** * Gets the news list by a specific subscription. * * This API is paginated. */ public getNewsListBySubscription = async (page = 1, subscriptionId?: string) => getNewsListBySubscription(this, page, subscriptionId ?? ""); /** * Get the detailed news with the url provided. * @param url the url of the queried news * @return Returns `[string, string, string][]`, where the three `string`s * represent title, content and abstract respectively. */ public getNewsDetail = async ( url: string, ): Promise<[string, string, string]> => getNewsDetail(this, url); /** * Adds a specific piece of news to fav list. * @param news */ public addNewsToFavor = async (news: NewsSlice): Promise => addNewsToFavor(this, news); /** * Remove a specific piece of news from fav list. * @param news */ public removeNewsFromFavor = async (news: NewsSlice): Promise => removeNewsFromFavor(this, news); /** * if the page is out of range, the NewsSlice will be a 0 length array. * @param page page of favor list * @returns [array of NewsSlice,total pages] */ public getFavorNewsList = async (page: number): Promise<[NewsSlice[], number]> => getFavorNewsList(this, page); /** * Get the schedules of the user. * @return Returns `Schedule[]`, containing all the schedules(including * exams) of the user. */ public getSchedule = async () => getSchedule(this); /** * Gets the timetable for course registration. */ public getCrTimetable = async () => getCrTimetable(this); /** * Gets the login captcha url for the course registration system. */ public getCrCaptchaUrl = async () => getCrCaptchaUrl(this); /** * Log in to the course registration system with the captcha. */ public loginCr = async (captcha: string) => loginCr(this, captcha); /** * Get all semesters available for course registration. */ public getCrAvailableSemesters = async () => getCrAvailableSemesters(this); /** * Get the course plan of a given semester. * @param semester */ public getCrCoursePlan = async (semester: string) => getCoursePlan(this, semester); /** * Search courses for registration remaining data * @param params */ public searchCrRemaining = async (params: SearchParams) => searchCrRemaining(this, params); /** * Search primary courses * @param params */ public searchCrPrimaryOpen = async (params: SearchParams) => searchCrPrimaryOpen(this, params); /** * Search courses for registration * @param params */ public searchCrCourses = async (params: SearchParams) => searchCrCourses(this, params); /** * Select a course. * @param semesterId semester id * @param priority "bx" | "xx" | "rx" | "ty" | "cx" * @param courseId course id * @param courseSeq course seq number * @param will 1 | 2 | 3 */ public selectCourse = async ( semesterId: string, priority: Priority, courseId: string, courseSeq: string, will: 1 | 2 | 3, ) => selectCourse(this, semesterId, priority, courseId, courseSeq, will); /** * Delete a course * @param semesterId * @param courseId * @param courseSeq */ public deleteCourse = async ( semesterId: string, courseId: string, courseSeq: string, ) => deleteCourse(this, semesterId, courseId, courseSeq); /** * Get all selected courses * @param semesterId */ public getSelectedCourses = async (semesterId: string) => getSelectedCourses(this, semesterId); /** * Change a will of a course * @param semesterId * @param courseId * @param courseSeq * @param will */ public changeCourseWill = async ( semesterId: string, courseId: string, courseSeq: string, will: 1 | 2 | 3, ) => changeCourseWill(this, semesterId, courseId, courseSeq, will); /** * Get current course registration stage * @param semesterId */ public getCrCurrentStage = async (semesterId: string) => getCrCurrentStage(this, semesterId); /** * Gets when is the latest course registration queue info released, and * when is the next time for release. * @param semesterId */ public searchCoursePriorityMeta = async (semesterId: string) => searchCoursePriorityMeta(this, semesterId); /** * Gets the course registration data for remaining position * @param semesterId * @param query */ public searchCoursePriorityInformation = async ( semesterId: string, query: SearchCoursePriorityQuery, ) => searchCoursePriorityInformation(this, semesterId, query); /** * Gets course registration queue info * @param semesterId */ public getQueueInfo = async (semesterId: string) => getQueueInfo(this, semesterId); /** * Cancel PF registration for a course * @param semesterId * @param courseId */ public cancelCoursePF = async (semesterId: string, courseId: string) => cancelCoursePF(this, semesterId, courseId); /** * Set PF mark for a course * @param semesterId * @param courseId */ public setCoursePF = async (semesterId: string, courseId: string) => setCoursePF(this, semesterId, courseId); /** * Gets all available sports resources. * * `gymId` and `itemId` can be found in `sportsIdInfoList` from `dist/lib/sports`. * * @param gymId * @param itemId * @param date yyyy-MM-dd */ public getSportsResources = async ( gymId: string, itemId: string, date: string, // yyyy-MM-dd ) => getSportsResources(this, gymId, itemId, date); /** * Saves the phone number in the sports reservation system * @param phone */ public updateSportsPhoneNumber = async (phone: string) => updateSportsPhoneNumber(this, phone); /** * Gets the url to the captcha for sports reservation */ public getSportsCaptchaUrl = () => getSportsCaptchaUrlMethod(); /** * Makes a sports reservation and gets the alipay pay-code if payment is * required. * * If you want to use the pay-code on mobile devices, the url link to the * Alipay payment page will be * `"alipayqr://platformapi/startapp?saId=10000007&qrcode=https%3A%2F%2Fqr.alipay.com%2F" + payCode` * * You can also call `genAlipayUrl(payCode)` in `dist/utils/alipay` to get * the Alipay url. * * @param totalCost a number indicating the total cost of the reservation * @param phone a string representing the user's phone number * @param receiptTitle a string representing the title of the receipt, or `undefined` if a receipt is not needed * @param gymId a string representing the ID of the gym * @param itemId a string representing the ID of the item * @param date a string in the format of `yyyy-MM-dd` * @param captcha a string representing the captcha * @param resHashId a string representing the hash of the resource * @param skipPayment whether to skip payment (and pay later) * @return Returns a string representing the alipay payment code if payment is required, or `undefined` if no payment is needed. */ public makeSportsReservation = async ( totalCost: number, phone: string, receiptTitle: ValidReceiptTypes | undefined, gymId: string, itemId: string, date: string, // yyyy-MM-dd captcha: string, resHashId: string, skipPayment = false, ) => makeSportsReservation(this, totalCost, phone, receiptTitle, gymId, itemId, date, captcha, resHashId, skipPayment); /** * Gets all active sports reservation records. */ public getSportsReservationRecords = async () => getSportsReservationRecords(this); /** * Make sports reservation payment with a payId. */ public paySportsReservation = async ( payId: string, receiptTitle: ValidReceiptTypes | undefined, ): Promise => paySportsReservation(this, payId, receiptTitle); /** * Cancel a sports reservation if payment has not been made * @param bookId a string representing the ID of the reservation */ public unsubscribeSportsReservation = async (bookId: string) => unsubscribeSportsReservation(this, bookId); public getGitNamespaces = async (page: number) => getNamespaces(this, page); public getGitRecentProjects = async (page: number) => getRecentProjects(this, page); public getGitOwnedProjects = async (name: string, page: number) => getPersonalProjects(this, name, page); public searchGitProjects = async (search: string, page: number) => searchProjects(this, search, page); public getGitStarredProjects = async (page: number) => getStarredProjects(this, page); public getGitProjectDetail = async (id: number) => getProjectDetail(this, id); public getGitProjectTree = async ( id: number, path: string, ref: string, page: number, ) => getProjectTree(this, id, path, ref, page); public getGitProjectBranches = async (id: number) => getProjectBranches(this, id); public getGitProjectFileBlob = async (id: number, sha: string) => getProjectFileBlob(this, id, sha); public renderGitMarkdown = async (text: string) => renderMarkdown(this, text); public searchReservesLib = async (bookName: string, page?: number) => searchReservesLib(this, bookName, page); public getReservesLibBookDetail = async (bookId: string) => bookDetail(this, bookId); public reservesLibDownloadChapters = async (chapters: BookChapter[], setCompletion?: (total: number, complete: number) => void) => downloadChapters(chapters, setCompletion); public getDegreeProgramCompletion = async () => getDegreeProgramCompletion(this); public getFullDegreeProgram = async (degreeId?: number, skippedSet?: string[]) => getFullDegreeProgram(this, degreeId, skippedSet); public getNetworkDetail = async (year: number, month: number) => getNetworkDetail(this, year, month); public getOnlineDevices = async () => getOnlineDevices(this); public getNetworkBalance = async () => getNetworkBalance(this); public getScoreByCourseId = async (courseId: string) => getScoreByCourseId(this, courseId); public loginCampusCard = async () => cardLogin(this); public getCampusCardInfo = async () => cardGetInfo(this); public getCampusCardPhotoUrl = async () => cardGetPhotoUrl(); /** * Get the campus card transactions. * @param start YYYY-MM-DD * @param end YYYY-MM-DD * @param type -1 for all (1-3), 1 for consumption, 2 for recharge, 3 for subsidy, 0 for ALL (?) */ public getCampusCardTransactions = async (start: string, end: string, type: CardTransactionType) => cardGetTransactions(this, start, end, type); public changeCampusCardPassword = async (oldPassword: string, newPassword: string) => cardChangeTransactionPassword(this, oldPassword, newPassword); public modifyCampusCardMaxTransactionAmount = async (transactionPassword: string, maxDailyAmount: number, maxOneTimeAmount: number) => cardModifyMaxTransactionAmount(this, transactionPassword, maxDailyAmount, maxOneTimeAmount); public reportCampusCardLoss = async (transactionPassword: string) => cardReportLoss(this, transactionPassword); public cancelCampusCardLoss = async (transactionPassword: string) => cardCancelLoss(this, transactionPassword); /** * Recharge the campus card. * @param amount in yuan * @param transactionPassword * @param type 0 for Bank Card, 1 for Alipay, 2 for Wechat Pay * @return Uri to request to complete the payment process, undefined for Bank */ public rechargeCampusCard = async (amount: number, transactionPassword: string, type: CardRechargeType) => { if (!await canRechargeCampusCard(this)) { throw new Error("暂不支持校园卡充值,请升级应用程序。"); } if (type === CardRechargeType.Bank) { return cardRechargeFromBank(this, transactionPassword, amount); } return cardRechargeFromWechatAlipay(this, amount, type === CardRechargeType.Alipay); }; } export class Water { public id = ""; // 档案号 public num = ""; // 订水量 public num1 = ""; // 订水票量 public lid = ""; // 水种类 public address = ""; // 地址 public phone = ""; // 电话 /* "6":清紫源泉矿泉水(高端) "10":燕园泉矿泉水(高端) "12":农夫山泉桶装水(19L) "11":清紫源泉矿泉水 "8":喜士天然矿泉水(大) "9":喜士天然矿泉水(小) "1":娃哈哈矿泉水 "7":娃哈哈纯净水 "5":清紫源泉纯净水 */ public getUserInformation = async (id: string) => getUserInformation(this, id); public getUserInformationAndStore = async (id: string) => getUserInformationAndStore(this, id); public postWaterSubmission = async (num: string, num1: string, lid: string) => postWaterSubmission(this, num, num1, lid); }