這是一個基於 深圳實驗學校 的網上訂餐系統開發的 API。開發者可以省略原先冗雜而無法避免的傳值代碼、擺脫原本繁瑣而不易理解的操作邏輯,通過封裝好的 szsy-canteen API 更為簡潔的介面實現網上訂餐交互。

szsy-canteen API 使用 Golang 編寫而成,保證其效率和性能。API 適用於對學校網上訂餐系統用戶端的二次開發 💗

English | 简体中文 | 正體中文

為何使用

簡而言之,邏輯簡單、省流高效。

由於最原始的初衷是降低學校網上訂餐系統的移動端開發成本,在 API 的設計上,將 優化邏輯節省流量 作為重要的考量指標。這裡舉個例子。API 提供了直接獲取「可訂餐日期」清單的介面,就避免了用戶端「獲取所有日期包括不必要的」(浪費流量)和「判斷日期是否可以訂餐」(複雜邏輯)等操作的開銷。

當然,因為開發時間比較有限和個人能力實屬不足,API 的部分設計比較粗糙。歡迎新的 contribution,或者你有新的關於訂餐服務的實現,希望你可以讓我知道,我會在 README 中更新你的推廣 link 😄

如何配置

如果你是 64位 Windows 或 Linux 上的開發者,可以直接下載各自系統的預編譯包,按兩下執行後 API 將默認開啟在本地機器 2018 埠上。

如果你試圖自己編譯運行,需要安裝配置 Golang 的開發環境並下載完整的源碼檔進行編譯。可以執行以下命令生成該平臺下的可執行檔。

1
go build main.go

簡單上手

szsy-canteen API 提供了以下介面:

  • login :登錄網上訂餐系統獲取基本資訊並得到進一步操作所需的口令

  • dates :獲取所有當前可以訂餐(即未超過訂餐時間)的日期列表

  • menu :獲取指定日期的功能表詳情以及訂餐情況

  • order :提交指定日期的訂餐請求

  • logout :登出網上訂餐系統

預設配置中 API 的 URL 應是

1
http://localhost:2018/

登錄網上訂餐系統

將 一卡通用戶名 和 使用 MD5 演算法加密後的密碼 寫入 JSON 欄位,以下是一個例子

1
2
3
4
{
    "账号":"2152000",
    "密码":"80d9ba95cce518bf747bda3bc98faef8"
}

考慮到安全的因素,設計上決定把用 MD5 加密密碼的工作交給請求端,即這裡你需要自行 MD5 加密密碼字串並把加密後的密碼字串提供給 密码 一項。

使用 POST 方法提交到 URL

1
http://localhost:2018/login

API 端將返回一個如下 JSON

1
2
3
4
5
{
    "姓名":"XXX",
    "余额":"666.66元",
    "口令":"6E19822908B2FEA56F7BF,bnfh4fsigr5z04ebdeo"
}

真實返回的 口令 一值將會比示例中展現的長得多,這裡為了排版做了精簡。

獲取可訂日期列表

將登錄時獲得的口令寫入 JSON 欄位

1
2
3
{
    "口令":"6E19822908B2FEA56F7BF,bnfh4fsigr5z04ebdeo"
}

使用 POST 方法提交到 URL

1
http://localhost:2018/dates

你將會得到返回 JSON 如下

1
2
3
4
5
{
    "可订日期":["2018-06-26","2018-06-27","2018-06-28","2018-06-29",
    "2018-07-02","2018-07-03","2018-07-04","2018-07-05",
    "2018-07-06","2018-07-09","2018-07-10","2018-07-13"]
} 

返回的日期列表將會包含 當前月與下個月的可訂餐日期,即 API 也會嘗試請求到下個月的菜單,不會遺漏下個月未超出訂餐時間的菜單。學校更新菜單最多一次性更新兩個月的份量。所以你可以放心把這份工作交給 szsy-canteen API 操心。

獲取指定日期菜單

同樣地,將登錄時獲得的口令寫入 JSON 欄位

1
2
3
{
    "口令":"6E19822908B2FEA56F7BF,bnfh4fsigr5z04ebdeo"
}

使用 POST 方法提交到含有「指定日期」參數的 URL

1
http://localhost:2018/menu/?date=2018-07-06

你可以得到返回如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
    "不订餐":null,
    "早餐":
        [
            ["0","套餐","早餐套餐","5.00","0"],
            ["1","牛奶","学生奶","2.04","0"],
            ["2","蛋类","五香鸡蛋","1.40","0"],
            ["3","点心","巧克力面包","1.40","0"],
            ["4","点心","玉米酥","1.40","0"],
            ["5","点心","南瓜米糕","1.40","0"],
            ["6","点心","鲜肉包","1.40","0"],
            ["7","粉面类","水饺","1.60","0"]
        ],
    "午餐":
        [
            ["0","套餐","午餐套餐","12.00","0"],
            ["1","水果","杨桃","1.30","0"],
            ["2","菜肴","蒜茸炒黄芽白","1.80","0"],
            ["3","菜肴","炒小瓜片","1.80","0"],
            ["4","菜肴","剁椒蒸鱼(微辣)","4.40","0"],
            ["5","菜肴","肉末豆角","3.60","0"],
            ["6","菜肴","土豆烧肉","5.60","0"],
            ["7","菜肴","香辣翅根2个","6.70","0"]
        ],
    "晚餐":null
}

每一道菜包含的資訊點順序排列如下

1
["编号","类型","菜名","单价","订餐个数"]

不订餐 的這一項一般都應為 null 值,如示例。當然,如果早餐午餐 選擇了不訂餐,那麼 不订餐 的值應為

1
"不订餐":["早餐","午餐"]

示例中 2018年7月10日 是週五,所以晚餐的菜單缺失,即 晚餐 的值為 null

提交訂餐資訊請求

將登錄時獲得的口令和早午晚三餐的訂餐資訊寫入 JSON 欄位

1
2
3
4
5
6
{
    "口令":"6E19822908B2FEA56F7BF,bnfh4fsigr5z04ebdeo",
    "早餐":"套餐",
    "午餐":"0,0,2,0,0,1,0,1",
    "晚餐":"不订餐"
}

訂餐資訊有三種格式可以填入,示例給出了所有情況

  1. 套餐(即等價於「1,0,0,0,0,0,0,0」)

  2. 不订餐(即等價于勾選上「不訂餐」選項)

  3. 給出以逗號為分隔符號的八道菜的訂餐個數

所以,本例中這位同學的早餐選擇了套餐隨緣,午餐選擇 2份蒜茸炒黃芽白、1份肉末豆角 和 1份香辣翅根2個,晚餐選擇了不訂餐。

遇到週五晚上,即晚餐功能表缺失的情況,應給予 晚餐 這一項 null 值,而非省略 晚餐 此項。此處為了演示 不订餐 欄位,晚餐 暫且填入該欄位,但實際上應該是null 😂

你會發現八道菜中第一道菜是 套餐,實際上後面的菜的訂餐個數若不為 0 時,套餐 的值無論為何值都會被 0 覆蓋。

接著使用 POST 方法提交到含有「指定日期」參數的 URL

1
http://localhost:2018/order/?date=2018-07-10

你可能得到如下幾種返回資訊

  1. 提交成功(即請求提交成功,訂餐資訊已寫入系統)

  2. 账户异常(即此帳戶被凍結或有其它異常情況,往往是欠費)

  3. 超过订餐时间(即該日不在允許訂餐時間範圍內,可通過提交前檢查日期是否存在於「可訂餐日期」清單內而避免此錯誤)

  4. 提交失败(用戶端網路超時或學校伺服器宕機等原因導致)

學校的伺服器處理訂餐信息所需的時間遠超于正常所需時間 😂,所以你往往需要等待幾秒才可以得到回饋(實驗人應有深刻的體會)不要因此過於頻繁地提交訂餐資訊,你可能會提交失敗,更糟的是得到錯誤的返回資訊。

登出網上訂餐系統

將登錄時獲得的口令寫入 JSON 欄位

1
2
3
{
    "口令":"6E19822908B2FEA56F7BF,bnfh4fsigr5z04ebdeo"
}

使用 POST 方法提交到 URL

1
http://localhost:2018/logout

得到 登出成功 後即可完成登出。

有關口令過期的錯誤

szsy-canteen API 的錯誤提示都比較明確易讀,但還是要對這條作單獨的說明。

如果你在使用口令請求日期清單、獲取某日菜單或是提交訂餐請求時,得到了「口令錯誤或過期」的錯誤提示,這意味著你的口令有可能過期了。這時,你需要做的就是重新 login 以獲得新的口令。

關於訂多份餐的提示

原則上,學校的網上訂餐系統限制每道菜最多選擇 3 份,這是網站上的 JavaScript 腳本限制的。然而使用 API 沒有這個限制,理論上你可以訂超過 3 份的數量。

經過實際測試,5 份以內個數成功率較大,基本可以提交成功,份數過於誇張大的成功率基本為零,會有 提交失败 的錯誤返回。之前閑著無聊嘗試過的提交成功的最大份數為 20 份,對,20份鹵雞腿。

當然,這裡不是漏洞。份數達到了 20 份也代表你需要支付 20 份的帳單(要不然我也不會在這裡堂而皇之地陳述這些)

在這里加這段文字是想提出一個建議:作為開發者的你,在開發用戶端的時候,也許可以提供一個可以顯性修改份數的入口。畢竟偶爾在「淨葷菜」上給自己加點餐也是充滿了幸福感的一件事。

致謝

@xlfjn

@GrakePch

感謝以上兩位在開發過程中提供的技術上和精神上的支援 💗