--- tags: NeutecLife App --- # 2-3.分類列表:會議室&英文課 API :::info 目錄: <a href="https://hackmd.io/FStSBTFdRhac3tsDr8OyiA">0.登入功能相關 API 文件</a> <a href="https://hackmd.io/coOyibBDRYqJpluQIQFYmg">1.首頁功能相關 API 文件</a> <a href="https://hackmd.io/-A3kGYJ8SHyjegBROlwJow">2-1.分類列表:分類列表頁、借書&歸還 API 文件</a> <a href="https://hackmd.io/boCGrFpsR0CciLYEXS-kxw">2-2.分類列表:借物 API 文件</a> <a href="https://hackmd.io/jBWDb0OaT_KV-_ducdzqsQ">2-3.分類列表:會議室&英文課 API 文件</a> <a href="https://hackmd.io/FhZ89ZDxSbOK8oYslEXuCA">3.最新消息 API 文件</a> <a href="https://hackmd.io/SSAxobFGQEC8lyHiu485iQ">4.通知 API 文件</a> <a href="https://hackmd.io/Fz8d0LtbS2iwhuI3QmmzYQ">5.我的 API 文件</a> > [time=Jan 4, 2024] * `更新` Document init > [time=Oct 28, 2024] * `更新` 移除meetingRoomPage.schedule中的grid欄位 > [time=Nov 26, 2024] * `更新` reservationId更名為scheduleId以配合schema命名 * `更新` 邀請名單改用id,memberList加入id欄位取代email欄位 > [time=Dec 18, 2024] * `更新` recurringPattern的值修改為「0:單次 1:每週重複」,移除了「2:每月重複」 > [time=Jan 8, 2025] * `更新` meetingRoomRecurringPopupPage-recurringValidate的response新增參數recurringIsNeverEnd > [time=Jan 14, 2025] * `更新` meetingRoomRecurringPopupPage-recurringValidate 新增schedule(optional)欄位 * `更新` meetingRoomSettingPage中的isNeedPush修改其含義 > [time=Feb 5, 2025] * `新增` 增加會議室「新增/調整」預約動線文件連結 > [time=Feb 12, 2025] * `更新` 調整預約情況(type=update)下,request不帶入isRecurringUpdate參數, 因為isRecurringUpdate的值與recurringPattern的值含義相同。 > [time=Mar 4, 2025] * `更新` 更新「歸納recurringValidate API介接時機」邏輯。 > [time=Apr 8, 2025] * `更新` meetingRoomDetailPage.settingContent的Response新增欄位meetingRoomName。雖然已有meetingRoomId,但若是從「通知」透過urlScheme直接進入到meetingDetailPage會沒有會議室名稱資料。 > [time=Apr 11, 2025] * `更新` 會議室地點增加會議室中文名稱<br>1. meetingRoomDetailPage.settingContent:<br>  (1)meetingRoomName更改為meetingRoomNameEn   (2)新增meetingRoomNameZh 2.meetingRoom.meetingRoomList:   (1)name更改為nameEn   (2)新增nameZh > [time=May 14, 2025] * `更新` meetingRoomDetailPage.settingContent的Response新增欄位meetingRoomCapacity與meetingRoomLocation。雖然已有meetingRoomId,但若是從「通知」透過urlScheme直接進入到meetingDetailPage後,再點入編輯頁面,會沒有會議室相關資料。 > [time=Feb 3, 2026] * `更新` 英文課列表timeslot格式變更,timeslot.brief為簡寫時間段,timeslot.full為完整時間段 ---- ::: ### ✅meetingRoomPage URL: `wss://{domain name}/` Method: `wss` Descirption: `會議室入口頁資訊` <img src="https://hackmd.io/_uploads/S1zm8S8RJg.png" width=250/> #### Remark ``` 1. 在一進入meetingPage時,先行介接meetingRoomInvitationPopupPage.memberList一次,並記錄儲存時間,4小時之內若已存在memberList資料則不需重新介接。 2. 樓層資料的過濾由App端進行,介接資料為一次性全拿 ``` **Request** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料參數 | | selectedDate| string | Y | 選擇日期(預設今日)| ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "meetingRoomPage", "module": "all", "type": "select", "data": { "selectedDate":"2024/1/17" } } ``` **Response** | Parameter | Type | Require | Description | | --------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | array | Y | 手機畫面資訊 | | module | string | Y | 手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容 | <br> **Response datePicker module 日期選擇器** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | today | string | Y | 今日日期 | | startDate | string | Y | 可選日期範圍起始日(今日-3個月)<br>ex:今天是2024/12/18,startDate為2024/9/1 | | endDate | string | Y | 可選日期範圍結束日<br>(今日+12個月)<br>ex:今天是2024/12/18,endDate為2025/12/31 | <br> **Response meetingRoomList module 會議室列表** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | meetingRoomId | int | Y | 會議室id | | nameEn | string | Y | 會議室名稱-英文 | | nameZh | string | Y | 會議室名稱-中文 | | capacity | int | Y | 會議室可容納人數 | | location | string | Y | 會議室位置(16F or 17F) | | isExternal | bool | Y | 是否為外部會議室 | <br> **Response schedule module 會議室行程表** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | meetingRoomId | int | Y | 會議室id | | timeline | array | Y | 會議室行程陣列,僅存放有登記的行程(可接受空陣列) | | scheduleId | string | Y | 會議室行程id | | startTime | string | Y | 會議開始時間 | | endTime | string | Y | 會議結束時間 | | isEditor | bool | Y | 是否為登記者(僅登記者有編輯權限) | | isExternal | bool | Y | 是否登記為外部會議 | | registrant | string | Y | 登記者英文名字(只有名沒有姓) | | desc | string | Y | 會議備註(可接受空值) | ``` 1.desc可以是空值 2.前端顯示畫面時,當時間只有1格(30min)時,優先顯示desc(會議備註),若desc為空值則顯示registrant(登記者英文名字) 3.月曆可視範圍規則:今日該月份往前減3個月 ~ 今日該月份往後加12個月 ex: 若今天為2024/11/26,可視範圍則為 2024/8/1 ~ 2024/11/30 ``` ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomPage", "info": [ { "module": "datePicker", "status": 200, "type": "list", "num": 1, "data": [ { "today": "2024/1/17", "startDate": "2023/1/1", "endDate": "2025/1/31" } ], "datetime": "2023/11/1 12:38:11" }, { "module": "meetingRoomList", "status": 200, "type": "list", "num": 3, "data": [ { "meetingRoomId": 1, "nameEn": "Great Barrier Reef", "nameZh": "大堡礁", "capacity": 10, "location": "16F", "isExternal": false }, { "meetingRoomId": 2, "nameEn": "Isle of Sky", "nameZh": "天空島", "capacity": 10, "location": "16F", "isExternal": true }, { "meetingRoomId": 3, "nameEn": "Ice Land", "nameZh": "冰島", "capacity": 6, "location": "16F", "isExternal": false }, ], "datetime": "2023/11/1 12:38:11" }, { "module": "schedule", "status": 200, "type": "list", "num": 3, "data": [ { "meetingRoomId": 1, "timeline": [ {"scheduleId": 1, "startTime":"07:00", "endTime":"07:30", "isEditor": true, "isExternal": false, "registrant":"Larry", "desc":"設計討論" }, {"scheduleId": 2, "startTime":"08:00", "endTime":"08:30", "isEditor": true, "isExternal": false, "registrant":"Bruce", "desc":"" }, {"scheduleId": 3, "startTime":"11:00", "endTime":"13:00", "isEditor": true, "isExternal": false, "registrant":"Larry", "desc":"設計討論" } ] }, { "meetingRoomId": 2, "timeline": [ { "scheduleId": 1, "startTime":"07:00", "endTime":"07:30", "isEditor": 1, "isExternal": 0, "registrant":"Larry", "desc":"設計討論" }, { "scheduleId": 2, "startTime":"08:00", "endTime":"08:30", "isEditor": 1, "isExternal": 0, "registrant":"Bruce", "desc":"" }, { "scheduleId": 3, "startTime":"11:00", "endTime":"13:00", "isEditor": 1, "isExternal": 0, "registrant":"Larry", "desc":"設計討論" } ] }, { "meetingRoomId": 3, "timeline": [] } ], "datetime": "2023/11/1 12:38:11" } ], "datetime": "2023/11/1 12:38:11" } ``` </br> ### ✅meetingRoomDetailPage URL: `wss://{domain name}/` Method: `wss` Descirption: `會議室預約資訊內容頁` <img src="https://hackmd.io/_uploads/BkfpISUAkl.png" width="250" /> **Request** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料 | | scheduleId | int | Y | 會議室行程id | ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "meetingRoomDetailPage", "module": "all", "type": "select", "data": { "scheduleId":1 } } ``` **Response** | Parameter | Type | Require | Description | | ----------| -------| ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | string | Y | 手機畫面資訊 | | module | string | Y | 手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容陣列 | **Response settingContent module 會議室預約資料** | Parameter | Type | Require | Description | | ---------- | -------| ------- | ----------- | | scheduleId | int | Y | 會議室行程id | | meetingRoomId| int | Y | 會議室id | | meetingRoomNameEn|String| Y | 會議室名稱-英文 | | meetingRoomNameZh|String| Y | 會議室名稱-中文 | | meetingRoomCapacity|int| Y | 會議室可容納人數 | | meetingRoomLocation|String| Y | 會議室地點 | | registrant | string | Y | 預約人英文名字 | | workNo | string | Y | 預約人員工編號 | | date | string | Y | 會議日期 | | startTime | string | Y | 會議時間:起始 | | endTime | string | Y | 會議時間:結束 | | isExternal | bool | Y | 會議類型:是否為外部會議 | | recurringPattern| int | Y | 重複預約規則(0:單次 1:每週) | | recurringIsNeverEnd| bool | Y | 重複預約結束日期的型態(false:選擇日期 true:永不)| | recurringEndDate| string | Y | 重複預約結束日期(可能是空值) | | invitationNum | int | Y | 邀請對象人數 | | invitationList | array | Y | 邀請對象資料陣列 | | workNo| string | Y | 邀請對象員工編號 | | name | string | Y | 邀請對象英文名字 | | dept | string | Y | 邀請對象所屬部門 | | isNeedPush | bool | Y | 是否開啟會議通知<br>(false:關閉 true:開啟)<br><font color='red'>開啟會議通知:意旨所有的情況都會發送,ex:建立新會議、會議前通知、與會者通知<br><br>關閉會議通知:代表靜音模式</font> | | desc | string | Y | 會議備註(可能是空值) | | canEdit | bool | Y | 是否可以編輯<br>(Server端判斷可編輯條件:登入者==登記者 && 會議時間 > 現在時間) | ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomDetailPage", "info": [ { "module": "settingContent", "status": 200, "type": "list", "num": 1, "data": [ { "scheduleId": 1, "meetingRoomId": 2, "meetingRoomNameEn": "Isle of Sky", "meetingRoomNameZh": "天空島", "meetingRoomCapacity": 10, "meetingRoomLocation": "16F", "registrant": "Bruce Huang", "workNo": "NE097", "date": "2024/1/16", "startTime": "11:00", "endTime": "12:00", "isExternal": false, "recurringPattern": 0, "recurringWeeklyDays": 2, "recurringIsNeverEnd": false, "recurringEndDate": "2025/1/16", "invitationNum": 2, "invitationList": [ {"id":3, "workNo":"NE119", "name":"Polly Lai", "dept":"SPWA"}, {"id":2, "workNo":"NE095", "name":"Swing Cheng", "dept":"PG" } ], "desc": "設計討論", "isNeedPush": true, "canEdit": true } ], "datetime": "2024/1/3 12:38:11" } ], "datetime": "2024/1/3 12:38:11" } ``` <br> #### Response for 失敗(預約被刪除) | Parameter | Type | Require | Description | | ----------| -------| ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | errorMsg | string | Y | 錯誤訊息 | | datetime | string | Y | 資料回應時間 | <img src="https://hackmd.io/_uploads/By6m_-dmxx.png" width="250" /> ``` 當預約被刪除時再透過「舊通知」點擊,將會看見錯誤訊息Dialog。 ``` ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomDetailPage", "info": [ { "module": "settingContent", "status": 1032, "errorMsg": "查無此會議預約", "datetime": "2025/8/13 12:38:11" } ], "datetime": "2025/8/13 12:38:11" } ``` </br> ### ✅meetingRoomTimePickerPopupPage URL: `wss://{domain name}/` Method: `wss` Descirption: `會議室設定頁-點選起訖時間的popup視窗頁` ![截圖 2024-11-26 中午12.47.08](https://hackmd.io/_uploads/H1PyQRf71e.png) #### Remark ``` 1. 當點選「起訖時間」Cell時,將展開該會議室當日(所選日期)的所有行程 2. 這裡的timeline格式與meetingRoomPage.schedule.timeline相同,但此頁前端不需顯示會議類型(內/外部) ``` **Request** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料參數 | | meetingRoomId| int | Y | 會議室id | | selectedDate | string | Y | 所選擇的日期 | ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "meetingRoomTimePickerPopupPage", "module": "timeline", "type": "select", "data": { "meetingRoomId":1, "selectedDate":"2024/1/17" } } ``` **Response** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | array | Y | 手機畫面資訊 | | module | string | Y | 手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容陣列 | | scheduleId | string | Y | 會議行程id | | startTime | string | Y | 會議開始時間 | | endTime | string | Y | 會議結束時間 | | isEditor | bool | Y | 是否為登記者(僅登記者有編輯權限) | | isExternal | bool | Y | 是否登記為外部會議 | | registrant | string | Y | 登記者英文名字(只有名沒有姓) | | desc | string | Y | 會議備註(可接受空值) | ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomSchedulePopupPage", "info": [ { "module": "timeline", "status": 200, "type": "list", "num": 3, "data": [ { "scheduleId": 1, "startTime":"09:00", "endTime":"10:00", "isEditor": false, "isExternal": false, "registrant":"Sam", "desc":"面試" }, { "scheduleId": 2, "startTime":"10:00", "endTime":"11:00", "isEditor": true, "isExternal": false, "registrant":"Bruce", "desc":"設計討論" }, { "scheduleId": 3, "startTime":"13:00", "endTime":"14:30", "isEditor": 1, "isExternal": 0, "registrant":"Candy", "desc":"護理師使用" } ], "datetime": "2023/11/1 12:38:11" } ], "datetime": "2023/11/1 12:38:11" } ``` </br> ### ✅meetingRoomRecurringPopupPage-recurringValidate URL: `wss://{domain name}/` Method: `wss` Descirption: `會議室設定頁-選擇重複預約&結束重複的popup視窗頁-重複預約衝突檢核` <img src="https://hackmd.io/_uploads/rkBewBURkl.png" width="250" /> #### Remark ``` 1. 當點選「重複預約」並選擇「每週」後,前端將自動出現「結束重複」這個cell,預設值為「永不」,此時將立刻做檢核動作,判斷這個重複預約是否有衝突。若檢核失敗將無法送出預約(預約按鈕disable) 2. 若「結束重複」選擇「自訂結束日期」,將再新增「結束日期」cell,點選「結束日期」將取得『月曆資訊』。 3. 當「結束日期」選擇完,會再次介接『衝突檢核』。 4. 每次修改「結束日期」的值,都必須介接一次『衝突檢核』。 5. 調整預約時,需要帶入scheduleId,因為Server端需要排除本筆資料再判斷是否合法。 6. 在「重複預約」為『每週』情況下,若起訖時間有變更,需要再次介接recurringValidate API來刷新狀態。 7. 在批次預約中選擇某筆做「單次調整」,此時即便有修改起訖時間,亦不需介接recurringValidate API。 歸納recurringValidate API介接時機: 「重複預約」欄位值為『每週』,且『可以被編輯(Enable)』的情況下。當起訖時間被調整、結束重複改成永不&結束日期被調整(且必須有值)這三種情況下,都要介接recurringValidate API來刷新畫面。 ``` <a href='https://docs.google.com/presentation/d/1her4MO_289JFZo00bvEi1uMAWOHwrOKbCIVarFNKl1k/edit#slide=id.g327d5acc798_0_0' target='_blank'>「循環時段」衝突情況2:新增/調整預約案例,在有循環條件下更改起訖時間</a> <br> **Request for 衝突檢核** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料參數 | | meetingRoomId| int | Y | 會議室id | | selectedDate | string | Y | 所選擇的會議日期 | | startTime | string | Y | 所選擇的會議起始時段 | | endTime | string | Y | 所選擇的會議結束時段 | | recurringPattern| int | Y | 重複預約規則(0:單次 1:每週) | | recurringIsNeverEnd| bool | Y | 重複預約結束日期的型態(false:選擇日期 true:永不)| | recurringEndDate| string | Y | 重複預約結束日期<br><font color=red>當recurringPattern\=\=1 && recurringIsNeverEnd\=\=false情況下,該值不可為空</font> | | scheduleId | int | | 會議行程id (調整預約才需帶入,新增預約時無需帶入) | <br> **選擇 每週、永不結束 情況** ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "meetingRoomRecurringPopupPage", "module": "recurringValidate", "type": "select", "data": { "meetingRoomId": 1, "selectedDate":"2024/1/17", "startTime":"10:00", "endTime":"11:00", "recurringPattern": 1, "recurringIsNeverEnd": true, "recurringEndDate": "" } } ``` **Response** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | string | Y | 手機畫面資訊 | | module | string | Y |手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容陣列 | | recurringIsNeverEnd | bool | Y | 重複預約結束日期的型態(false:選擇日期 true:永不)<br><font color=red>request時recurringIsNeverEnd參數值若為true,response時也回應true | isPass | bool | Y | 是否通過檢查 (false:未通過 true:通過) | | message | string | | 檢查結果描述(說明給申請者未通過原因) | <br> **檢核失敗案例** ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomRecurringPopupPage", "info": [ { "module": "recurringValidate", "status": 200, "type": "list", "num": 1, "data": [ { "recurringIsNeverEnd":true, "isPass":false, "message":"重複預約時段衝突", }, ] } ], "datetime": "2023/11/1 12:38:11" } ``` <br> **檢核成功案例** ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomRecurringPopupPage", "info": [ { "module": "recurringValidate", "status": 200, "type": "list", "num": 1, "data": [ { "recurringIsNeverEnd":true, "isPass":true, "message":"", }, ] } ], "datetime": "2023/11/1 12:38:11" } ``` </br> ### ✅meetingRoomRecurringPopupPage-recurringEndDatePicker URL: `wss://{domain name}/` Method: `wss` Descirption: `會議室設定頁-選擇重複預約&結束重複的popup視窗頁-月曆範圍資訊` | 點選「結束日期」cell | 彈跳出DatePicker Popup | 可能會沒有月曆資料 | | ----------- | -------- | -------- | | ![截圖 2024-12-18 下午3.18.17](https://hackmd.io/_uploads/HJDSwrICke.png) | ![截圖 2024-12-18 下午3.15.43](https://hackmd.io/_uploads/ByagDegBkx.png) | ![截圖 2024-12-18 下午3.16.14](https://hackmd.io/_uploads/S1PZPlxSJx.png) | #### Remark ``` 1. 當點選「結束日期」時介接,取得範圍資訊後畫出月曆顯示。 2. 如果第一個循環就衝突,就有可能會沒有月曆資料。 3. Server端判斷條件:依照recurringPattern(每週),從selectedDate開始往後檢查至「可視範圍的EndDate(今日的月份+12個月月的最後一天)」 ``` **Request** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料參數 | | meetingRoomId| int | Y | 會議室id | | selectedDate | string | Y | 所選擇的會議日期 | | startTime | string | Y | 所選擇的會議起始時段 | | endTime | string | Y | 所選擇的會議結束時段 | | recurringPattern| int | Y | 重複預約規則(0:單次 1:每週) | ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "meetingRoomRecurringPopupPage", "module": "recurringEndDatePicker", "type": "select", "data": { "meetingRoomId": 1, "selectedDate":"2024/1/17", "startTime":"10:00", "endTime":"11:00", "recurringPattern": 1 } } ``` **Response** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | string | Y | 手機畫面資訊 | | module | string | Y |手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容陣列 | | today | string | Y | 今日日期 | | startDate | string | Y | 開始日期 | | endDate | string | Y | 結束日期 | | message | string | | 衝突結果描述 | <br> **有範圍案例** ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomRecurringPopupPage", "info": [ { "module": "recurringEndDatePicker", "status": 200, "type": "list", "num": 1, "data": [ { "today":"2023/8/1", "startDate":"2023/8/23", "endDate":"2023/9/29" } ], "datetime": "2023/11/1 12:38:11" } ], "datetime": "2023/11/1 12:38:11" } ``` <br> **無範圍(全部時段衝突)案例** ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomSchedulePopupPage", "info": [ { "module": "recurringEndDatePicker", "status": 200, "type": "list", "num": 1, "data": [ { "today":"2023/8/1", "startDate":"", "endDate":"", "message":"重複預約時段衝突" }, ], "datetime": "2023/11/1 12:38:11" } ], "datetime": "2023/11/1 12:38:11" } ``` </br> ### ✅meetingRoomInvitationPopupPage URL: `wss://{domain name}/` Method: `wss` Descirption: `會議室設定頁-選擇邀請對象的popup視窗頁` ![截圖 2024-11-26 下午4.22.00](https://hackmd.io/_uploads/HkQPSbXQyg.png) #### Remark ``` 1. 當點選「邀請對象」Cell時,將切換到邀請對象的畫面,並能搜尋與選擇邀請對象。此API將提供完整的員工名單,搜尋功能由APP端實作。 2. 在一進入meetingPage時,先行介接meetingRoomInvitationPopupPage.memberList一次,並記錄儲存時間,4小時之內若已存在memberList資料則不需重新介接。 ``` **Request** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料參數 | ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "meetingRoomInvitationPopupPage", "module": "memberList", "type": "select", "data": {} } ``` **Response** | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | number | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | string | Y | 手機畫面資訊 | | module | string | Y |手機畫面區塊名稱 | | status | number | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容陣列 | | id | string | Y | 員工member_id | | name | string | Y | 員工英文姓名 | | workNo | string | Y | 員工編號 ex:NE097 | | dept | string | Y | 員工所屬部門 ex:PG | ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomInvitationPopupPage", "info": [ { "module": "memberList", "status": 200, "type": "list", "num": 2, "data": [ { "id":1, "name":"Bruce Huang", "workNo":"NE097", "dept":"PG" }, { "id":2, "name":"Swing Cheng", "workNo":"NE095", "dept":"PG" } ], "datetime": "2023/11/1 12:38:11" } ], "datetime": "2023/11/1 12:38:11" } ``` </br> ### ✅meetingRoomSettingPage-booking URL: `wss://{domain name}/` Method: `wss` Descirption: `會議室預約編輯頁-新增預約、調整預約&刪除預約 動作` **Request for 新增/調整** | Parameter | Type | Require | Description | | ----------- | ------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料 | | scheduleId | int | | 預約會議室id (調整/刪除預約才使用) | | meetingRoomId| int | Y | 會議室id | | selectedDate | string | Y | 所選擇的會議日期 | | startTime | string | Y | 所選擇的會議起始時段 | | endTime | string | Y | 所選擇的會議結束時段 | | isExternal | bool | Y | 是否為外部會議 (false:內部 true:外部) | | recurringPattern | int | Y | 重複預約規則(0:單次 1:每週) | | recurringIsNeverEnd | bool | | 重複預約結束日期的型態(false:選擇日期 true:永不)| | recurringEndDate | string | | 重複預約結束日期<br>(若recurringIsNeverEnd為false,recurringEndDate才會有值) | | invitationList | array | Y | 邀請對象,內容為member_id的int陣列| | isNeedPush | bool | Y | 是否開啟會議通知<br>(false:關閉 true:開啟)<br><font color='red'>開啟會議通知:意旨所有的情況都會發送,ex:建立新會議、會議前通知、與會者通知<br><br>關閉會議通知:代表靜音模式</font> | | desc | string | Y | 會議備註 | ``` 以下範例為:新增預約,每週二,從2024/1/16(二)起循環至2025/1/28(二),並且所有的循環預約都會通知2個人 ``` **新增預約** ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "meetingRoomSettingPage", "module": "booking", "type": "insert", "data": { "meetingRoomId": 1, "selectedDate": "2024/1/16", "startTime": "11:00", "endTime": "12:00", "isExternal": false, "recurringPattern": 1, "recurringIsNeverEnd": false, "recurringEndDate": "2025/1/28", "invitationList": [1,2], "isNeedPush": true, "desc": "設計討論" } } ``` <br> **調整預約** <a href="https://docs.google.com/presentation/d/1her4MO_289JFZo00bvEi1uMAWOHwrOKbCIVarFNKl1k/edit#slide=id.g32d14118636_1_38" target="_blank">調整預約動線文件連結</a> ``` [2/12更新] 調整預約情況(type=update)下,request不帶入isRecurringUpdate參數, 因為isRecurringUpdate的值與recurringPattern的值含義相同。 ``` ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "meetingRoomSettingPage", "module": "booking", "type": "update", "data": { "scheduleId": 1, "meetingRoomId": 1, "selectedDate": "2024/1/16", "startTime": "11:00", "endTime": "12:00", "isExternal": false, "recurringPattern": 0, "recurringIsNeverEnd": false, "recurringEndDate": "2026/1/28", "invitationList": [2], "isNeedPush": false, "desc": "設計討論" } } ``` <br> **Response** | Parameter | Type | Require | Description | | --------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | array | Y | 手機畫面資訊 | | module | string | Y | 手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | errorMsg | string | | 錯誤訊息 | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容 | | toast | string | Y | 回應訊息 | | isPositive| bool | Y | 回應訊息是否為積極行為,true:icon顏色為藍色, false:icon顏色為白色 | <br> **新增成功** ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomSettingPage", "info": [ { "module": "booking", "status": 200, "type": "list", "num": 1, "data": [ { "toast": "完成預約", "isPositive": true } ], "datetime": "2023/11/1 12:38:11" } ], "datetime": "2023/11/1 12:38:11" } ``` <br> **Request for 刪除預約** <a href="https://docs.google.com/presentation/d/1her4MO_289JFZo00bvEi1uMAWOHwrOKbCIVarFNKl1k/edit#slide=id.g32d14118636_1_0" target="_blank">刪除預約動線文件連結</a> | Parameter | Type | Require | Description | | ----------- | ------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料 | | scheduleId | int | Y | 預約會議室id (調整/刪除預約才使用) | | isRecurringUpdate| bool| Y | 是否為循環批次修改 (只有刪除預約才使用)<br>(true:批次刪除, false:單次刪除)<br><font color='red'>批次刪除只刪<u>未過期</u>的</font>| **刪除單次預約** ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "meetingRoomSettingPage", "module": "booking", "type": "delete", "data": { "scheduleId": 1, "isRecurringUpdate": false } } ``` <br> **刪除循環預約** ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "meetingRoomSettingPage", "module": "booking", "type": "delete", "data": { "scheduleId": 1, "isRecurringUpdate": true } } ``` <br> **Response** | Parameter | Type | Require | Description | | --------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | array | Y | 手機畫面資訊 | | module | string | Y | 手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | errorMsg | string | | 錯誤訊息 | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容 | | toast | string | Y | 回應訊息 | | isPositive| bool | Y | 回應訊息是否為積極行為,true:icon顏色為藍色, false:icon顏色為白色 | <br> **刪除成功** ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomSettingPage", "info": [ { "module": "booking", "status": 200, "type": "list", "num": 1, "data": [ { "toast": "預約已刪除", "isPositive": false } ], "datetime": "2023/11/1 12:38:11" } ], "datetime": "2023/11/1 12:38:11" } ``` </br> **新增/調整失敗-「起訖時段」衝突案例** <a href='https://docs.google.com/presentation/d/1her4MO_289JFZo00bvEi1uMAWOHwrOKbCIVarFNKl1k/edit#slide=id.g325b2c56631_0_59' target='_blank'>流程動線參考圖-「起訖時段」衝突情況3~4</a> ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomSettingPage", "info": [ { "module": "booking", "status": 1030, "errorMsg": "已有他人在此時段預約,請重新選擇起訖時間", "datetime": "2023/11/1 12:38:11" } ], "datetime": "2023/11/1 12:38:11" } ``` </br> **新增/調整失敗-「循環時段」衝突案例** <a href='https://docs.google.com/presentation/d/1her4MO_289JFZo00bvEi1uMAWOHwrOKbCIVarFNKl1k/edit#slide=id.g3277c61646d_1_0' target='_blank'>流程動線參考圖-「循環時段」衝突情況:新增/調整預約案例</a> ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "meetingRoomSettingPage", "info": [ { "module": "booking", "status": 1031, "errorMsg": "會議時段衝突,請重新選擇循環時段", "datetime": "2023/11/1 12:38:11" } ], "datetime": "2023/11/1 12:38:11" } ``` </br> ### englishClassPage URL: `wss://{domain name}/` Method: `wss` ==需要訂閱== Descirption: `「英文課」選課列表頁` #### [點我前往 - 英文課動線說明文件](https://docs.google.com/presentation/d/18xTOsKylWMeIZTy-JzwRQcjOwRgRetrrBa0yYMy5Fpc/edit?slide=id.g3b6bb2ce568_0_6#slide=id.g3b6bb2ce568_0_6) <img src="https://hackmd.io/_uploads/Hywp-l5VWg.png" width="250"> #### Request | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料參數 | | selectedMonth| string | | 月份數,\[格式yyyy/mm/dd\](若無參數值或參數值不在範圍內,API將給予預設的月份數。)<br><br>selectedMonth預設值規則:<br>1.選課期間 - selectedMonth為開放選課的月份<br>2. 非選課期間 - selectedMonth為當日的月份 | | teacherId | int | | 老師id | <br> :::info 訂閱條件:englishClassPage + selectedMonth。使用者若是停留在6月份,此時7月的資料有異動,不需推送;該使用者只會主動收到其所在月份的資料。 App首次進入englishClassPage並不會給予selectedMonth,但Server端會知道要匹配哪個selectedMonth。 ::: #### Request -首次進入,不帶selectedMonth參數 ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "englishClassPage", "module": "all", "type": "select", "data": { } } ``` <br> #### Request -當使用者自行選擇月份,selectedMonth參數帶入所選值 ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "englishClassPage", "module": "all", "type": "select", "data": { "selectedMonth": "2025/7/1" } } ``` <br> **Response** | Parameter | Type | Require | Description | | --------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | array | Y | 手機畫面資訊 | | module | string | Y | 手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容陣列 | | semesterInfo|(module)| Y | 學期資訊module | | startDate | string | Y | 學期起始時間 | | endDate | string | Y | 學期結束時間 | | selectedMonth | string| Y | 所選月份 \[yyyy/mm/dd\] | | remainingClasses | string| Y | 本月可約堂數 | | completedClasses | string| Y | 本期已上堂數 | | enrollmentStatus | string| Y | 課表狀態:<br>0:尚未執行選課的非選課期間<br>1:選課期間<br>2:已執行選課的非選課期間 | | monthlySchedule|(module) | Y | 當月課程資訊module | | teacherId | string| Y | 課程老師id | | teacherName | string| Y | 課程老師名稱 | | selectedMonth | string| Y | 所選月份 \[yyyy/mm/dd\] | | timeslot | array | Y | 上課時段,陣列index對應timeline.[2025/7/1(日期)]的index | | brief | string | Y | 時段簡寫式,使用在列表頁中。 | | full | string | Y | 時段完整式,使用在<u>新增時</u>的預約設定頁中。 | | timeline | object| Y | 課表,只給予有開課的資料 | | 2025/7/1(日期) | array| Y | 有開課的日期,陣列index對應timeslot的index | | s | int | Y | 狀態id有五種,等同於statusId<br>**0:空值**,無按鈕。<br>代表未開課(或還沒進入選課階段)。<br><br>**1:已截止**,不可點擊。<br>代表有開課+無人選課+已超過選課階段。<br><br>**2:可預約**,點擊後進入「預約設定」。<br>代表有開課+無人選課選課+正在選課階段。<br><br>**3:已預約**,點擊後進入englishClassDetailPage。<br>代表有開課+自己選課。<br><br>**4:額滿**,點擊後進入englishClassDetailPage。<br>代表有開課+有別人選課。| | id | int | Y | 課程id,等同於classId。classId為0代表沒開課 | <br> #### Response - App第一次進入英文課列表,API回覆all ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "status": 200, "page": "englishClassPage", "info": [ { "module": "semesterInfo", "status": 200, "type":"list", "num": 1, "data": [ { "startDate":"2025/7/1", "endDate":"2025/12/31", "selectedMonth": "2025/7/1", "remainingClasses": 3, "completedClasses": 9, "enrollmentStatus": 1 } ], "datetime":"2025/6/16 10:00:01" }, { "module": "monthlySchedule", "status": 200, "type": "list", "num": 2, "data": [ { "teacherId": 1, "teacherName": "Mike", "selectedMonth": "2025/7/1", "timeslot": [ {"brief": "13-14", "full":"13:00-14:00"}, {"brief": "18-19", "full":"18:00-19:00"}, {"brief": "20-21", "full":"20:00-21:00"} ], "timeline": { "2025/7/1": [ { "s": 3, "id": 9812 }, { "s": 0, "id": 0 }, { "s": 1, "id": 9813 } ], "2025/7/6": [ { "s": 0, "id": 9815 }, { "s": 0, "id": 9814 }, { "s": 0, "id": 0 } ], "2025/7/7": [ { "s": 0, "id": 0 }, { "s": 1, "id": 9816 }, { "s": 0, "id": 9817 } ], "2025/7/12": [ { "s": 0, "id": 9828 }, { "s": 0, "id": 9818 }, { "s": 1, "id": 9819 } ], "2025/7/13": [ { "s": 0, "id": 9829 }, { "s": 0, "id": 9820 }, { "s": 2, "id": 0 } ], "2025/7/14": [ { "s": 0, "id": 0 }, { "s": 0, "id": 9822 }, { "s": 1, "id": 0 } ], "2025/7/26": [ { "s": 3, "id": 9830 }, { "s": 0, "id": 9824 }, { "s": 1, "id": 9825 } ], "2025/7/27": [ { "s": 0, "id": 0 }, { "s": 0, "id": 9826 }, { "s": 0, "id": 9827 } ] } }, { "teacherId": 2, "teacherName": "Helene", "selectedMonth": "2025/7/1", "timeslot": [ {"brief": "13-14", "full":"13:00-14:00"}, {"brief": "18-19", "full":"18:00-19:00"}, {"brief": "20-21", "full":"20:00-21:00"} ], "timeline": { "2025/7/1": [ { "s": 0, "id": 0 }, { "s": 0, "id": 9828 }, { "s": 0, "id": 9829 } ], "2025/7/7": [ { "s": 1, "id": 0 }, { "s": 2, "id": 9830 }, { "s": 1, "id": 9831 } ], "2025/7/12": [ { "s": 0, "id": 0 }, { "s": 1, "id": 9832 }, { "s": 1, "id": 9833 } ], "2025/7/14": [ { "s": 0, "id": 0 }, { "s": 1, "id": 9834 }, { "s": 1, "id": 9835 } ], "2025/7/26": [ { "s": 0, "id": 0 }, { "s": 0, "id": 9836 }, { "s": 0, "id": 9837 } ], "2025/7/27": [ { "s": 0, "id": 0 }, { "s": 0, "id": 9838 }, { "s": 1, "id": 9839 } ] } } ], "datetime": "2025/6/17 10:00:01" } ], "datetime": "2025/6/17 12:38:11" } ``` <br> #### Response - 訂閱情況:當Mike課表的2025/7/1 19-20時段被其他人登記時 :::info 訂閱條件:englishClassPage + selectedMonth。使用者若是停留在6月份,此時7月的資料有異動,不需推送;該使用者只會主動收到其所在月份的資料。 ::: ```json= { "requestId": "s87294767-d866-9374-22n9-9we84g9374e1", "status": 200, "page": "englishClassPage", "info": [ { "module": "monthlySchedule", "status": 200, "type": "update", "num": 1, "data": [ { "teacherId": 1, "teacherName": "Mike", "selectedMonth": "2025/7/1", "timeslot": [ {"brief": "13-14", "full":"13:00-14:00"}, {"brief": "18-19", "full":"18:00-19:00"}, {"brief": "20-21", "full":"20:00-21:00"} ], "timeline": { "2025/7/1": [ { "s": 3, "id": 0 }, { "s": 0, "id": 9812 }, { "s": 3, "id": 9813 } ] } } ], "datetime": "2025/6/17 12:38:10" } ], "datetime": "2025/6/17 12:38:11" } ``` <br> #### Response - 沒有權限情況:當使用者沒有權限選課時 <img src="https://hackmd.io/_uploads/SyE4I04Sbl.png" width=480> ```json= { "requestId": "s87294767-d866-9374-22n9-9we84g9374e1", "status": 1062, "page": "englishClassPage", "errorMsg": "您沒有報名本期課程,待有空堂數時才開放選課", "datetime": "2025/6/17 12:38:11" } ``` <br> ### englishClassDetailPage URL: `wss://{domain name}/` Method: `wss` Descirption: `「英文課」內容頁` <img src="https://hackmd.io/_uploads/HyXqC-1L-g.png" width="250"> #### Request | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料參數 | | classId | int | | 課程id,來自englishClassPage中monthlySchedule.timeline的id | ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "englishClassDetailPage", "module": "all", "type": "select", "data": { "classId": 9829 } } ``` <br> **Response** | Parameter | Type | Require | Description | | --------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | array | Y | 手機畫面資訊 | | module | string | Y | 手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容陣列 | | classId | int | Y | 課程id | | teacherName | string | Y | 課堂老師名稱 | | studentName | string | Y | 申請者名稱(學生名稱) | | classDate | string | Y | 預約(課程)日期(包含週幾) | | classTime | string | Y | 預約(課程)時間 | | comment | string | Y | 上課備駐 | | canEdit | bool | Y | 是否可以編輯<br>true:可編輯,下方會多出「調整預約」與「刪除」兩按鈕<br>false:不可編輯,下方無按鈕| #### Response - 一般情況 ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "status": 200, "page": "englishClassDetailPage", "info": [ { "module": "classContent", "status": 200, "type":"list", "num": 1, "data": [ { "classId": 9829, "teacherName":"Mike", "studentName":"NE00277-Leo Yeh", "classDate": "2025/8/21 (週四)", "classTime": "18:00-19:00", "comment": "Business Conversation\r如果有很多字,要可以自動向下延伸", "canEdit":false } ], "datetime":"2025/7/16 10:00:01" } ], "datetime": "2025/7/17 12:38:11" } ``` <br> #### Response - 查無資料情況 ```json= { "requestId": "s87294767-d866-9374-22n9-9we84g9374e1", "status": 1061, "page": "englishClassDetailPage", "errorMsg": "查無此課程", "datetime": "2025/6/17 12:38:11" } ``` <br> ### englishClassSettingPage-booking URL: `wss://{domain name}/` Method: `wss` Descirption: `「英文課」預約設定頁-確認預約(或確認修改)動作` #### Remark ``` 此頁沒有訂閱機制,要顯示資料都來自 englishClassDetailPage,與會議室的預約設定頁類似 ``` <img src="https://hackmd.io/_uploads/HkpHfvXrbe.png" width="250"> #### Request for 新增預約 | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料參數 | | classId | int | Y | 課程id,來自englishClassPage中monthlySchedule.timeline的id | | comment | string | | 上課備註 | ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "englishClassSettingPage", "module": "booking", "type": "add", "data": { "classId": 9829, "comment": "" } } ``` <br> ****Response for 新增預約**** | Parameter | Type | Require | Description | | --------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | array | Y | 手機畫面資訊 | | module | string | Y | 手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容陣列 | | toast | string | Y | 回應訊息 | | isPositive| bool | Y | 回應訊息是否為積極行為,true:icon顏色為藍色, false:icon顏色為白色 | <br> #### Response - 預約成功 ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "englishClassSettingPage", "info": [ { "module": "booking", "status": 200, "type": "list", "num": 1, "data": [ { "toast": "預約成功", "isPositive": true } ], "datetime": "2025/11/1 12:38:11" } ], "datetime": "2025/11/1 12:38:11" } /* 此時會因為remainingClasses與timeline都有所變動 將主動推送engloshClassPage的相關異動資訊給 有訂閱『englishClassPage 且 selectedMonth是7月』的使用者 */ { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "status": 200, "page": "englishClassPage", "info": [ { "module": "semesterInfo", "status": 200, "type":"update", "num": 1, "data": [ { "startDate":"2025/7/1", "endDate":"2025/12/31", "selectedMonth": "2025/7/1", "remainingClasses": 2, "completedClasses": 9, "enrollmentStatus": 1 } ], "datetime":"2025/6/16 10:00:01" }, { "module": "monthlySchedule", "status": 200, "type": "update", "num": 1, "data": [ { "teacherId": 1, "teacherName": "Mike", "selectedMonth": "2025/7/1", "timeslot": [ {"brief": "13-14", "full":"13:00-14:00"}, {"brief": "18-19", "full":"18:00-19:00"}, {"brief": "20-21", "full":"20:00-21:00"} ], "timeline": { "2025/7/1": [ { "s": 3, "id": 9812 }, { "s": 0, "id": 0 }, { "s": 1, "id": 9813 } ] } } ], "datetime": "2025/6/17 12:38:10" } ], "datetime": "2025/6/17 12:38:11" } ``` <br> #### Response - 預約失敗:被其他人搶先一步登記 <a href="https://docs.google.com/presentation/d/18xTOsKylWMeIZTy-JzwRQcjOwRgRetrrBa0yYMy5Fpc/edit?slide=id.g3b8e937346e_1_31#slide=id.g3b8e937346e_1_31">查看案例與動線</a> ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "englishClassSettingPage", "info": [ { "module": "booking", "status": 1064, "errorMsg": "此時段已有人預約", "datetime": "2025/8/13 12:38:11" } ], "datetime": "2025/8/13 12:38:11" } ``` <br> #### Response - 預約失敗:本月已無可預約堂數 案例情境:發生在App畫面停留在「預約設定頁」,後台正好將本月額度降低後,App送出預約登記。 <a href="https://docs.google.com/presentation/d/18xTOsKylWMeIZTy-JzwRQcjOwRgRetrrBa0yYMy5Fpc/edit?slide=id.g3b8e937346e_1_31#slide=id.g3b8e937346e_1_31">查看案例與動線</a> ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "englishClassSettingPage", "info": [ { "module": "booking", "status": 1063, "errorMsg": "本月已無可預約堂數", "datetime": "2025/8/13 12:38:11" } ], "datetime": "2025/8/13 12:38:11" } ``` <br> #### Response - 操作失敗:未知的錯誤 ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "englishClassSettingPage", "info": [ { "module": "booking", "status": 1005, "errorMsg": "目前無法完成操作,請聯絡SPWA相關人員", "datetime": "2025/8/13 12:38:11" } ], "datetime": "2025/8/13 12:38:11" } ``` <br> #### Request for 刪除預約 | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料參數 | | classId | int | Y | 課程id,來自englishClassPage中monthlySchedule.timeline的id | | comment | string | | 上課備註 | ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "englishClassSettingPage", "module": "booking", "type": "delete", "data": { "classId": 9829 } } ``` <br> **Response for 刪除預約** | Parameter | Type | Require | Description | | --------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | array | Y | 手機畫面資訊 | | module | string | Y | 手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容陣列 | | toast | string | Y | 回應訊息 | | isPositive| bool | Y | 回應訊息是否為積極行為,true:icon顏色為藍色, false:icon顏色為白色 | <br> :::info 若收到booking回應的status(狀態代碼)是200,App要強制導頁englishClassPage去顯示toast [點我查看「從通知內容頁前往_查看與刪除自己的預約」案例](https://docs.google.com/presentation/d/18xTOsKylWMeIZTy-JzwRQcjOwRgRetrrBa0yYMy5Fpc/edit?slide=id.g3ba50304bfb_3_320#slide=id.g3ba50304bfb_3_320) ::: #### Response - 刪除成功 ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "englishClassSettingPage", "info": [ { "module": "booking", "status": 200, "type": "list", "num": 1, "data": [ { "toast": "刪除成功", "isPositive": true } ], "datetime": "2025/11/1 12:38:11" } ], "datetime": "2025/11/1 12:38:11" } ``` <br> #### Response - 操作失敗:未知的錯誤 ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "englishClassSettingPage", "info": [ { "module": "booking", "status": 1005, "errorMsg": "目前無法完成操作,請聯絡SPWA相關人員", "datetime": "2025/8/13 12:38:11" } ], "datetime": "2025/8/13 12:38:11" } ``` <br> #### Request for 調整預約 | Parameter | Type | Require | Description | | ----------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | page | string | Y | 手機畫面名稱 | | module | string | Y | 功能區塊名稱 | | type | string | Y | 資料處理型態 | | data | object | Y | 資料參數 | | classId | int | Y | 課程id,來自englishClassPage中monthlySchedule.timeline的id | | comment | string | | 上課備註 | ```json= { "requestId": "64d94767-c926-6156-44a5-8bf08a3691d4", "page": "englishClassSettingPage", "module": "booking", "type": "update", "data": { "classId": 9829, "comment": "Business Conversation" } } ``` <br> **Response for 調整預約** | Parameter | Type | Require | Description | | --------- | -------- | ------- | ----------- | | requestId | string | Y | 對話id | | status | int | Y | [狀態代碼](#狀態代碼) | | page | string | Y | 手機畫面名稱 | | info | array | Y | 手機畫面資訊 | | module | string | Y | 手機畫面區塊名稱 | | status | int | Y | [狀態代碼](#狀態代碼) | | type | string | Y | 資料處理型態 | | num | int | Y | 資料筆數 | | data | array | Y | 資料內容陣列 | | toast | string | Y | 回應訊息 | | isPositive| bool | Y | 回應訊息是否為積極行為,true:icon顏色為藍色, false:icon顏色為白色 | <br> :::info 收到booking回應是200,App要強制導頁englishClassPage去顯示toast [點我查看「從通知內容頁前往_查看與編輯自己的預約」案例](https://docs.google.com/presentation/d/18xTOsKylWMeIZTy-JzwRQcjOwRgRetrrBa0yYMy5Fpc/edit?slide=id.g3ba50304bfb_3_293#slide=id.g3ba50304bfb_3_293) ::: #### Response - 調整成功 ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "englishClassSettingPage", "info": [ { "module": "booking", "status": 200, "type": "list", "num": 1, "data": [ { "toast": "調整成功", "isPositive": true } ], "datetime": "2025/11/1 12:38:11" } ], "datetime": "2025/11/1 12:38:11" } ``` <br> #### Response - 操作失敗:未知的錯誤 ```json= { "requestId": "1fb7d801-4a05-0b1d-ea16-de1d32c97d6c", "status": 200, "page": "englishClassSettingPage", "info": [ { "module": "booking", "status": 1005, "errorMsg": "目前無法完成操作,請聯絡SPWA相關人員", "datetime": "2025/8/13 12:38:11" } ], "datetime": "2025/8/13 12:38:11" } ``` <br> --- <br> <iframe src="https://hackmd.io/zqx1OcNuTKSHCI89YIHMOw?view" width="100%" height="500"></iframe> <!-- ### 狀態代碼 | status | description | | ----- |-------------| | 200 | Success | | 1001 | Not found this page or module. | | 1003 | Not found this DATA. | | 1004 | DATA parameter error. | | 1005 | Data processing error. | | 1006 | 您輸入的帳號或密碼錯誤,請重新輸入 | | 1008 | Your account has been logged in another device. | | 1009 | Touch too fast. | | 1010 | Unknow error. | | 1011 | 身份驗證失敗,請重新登入 | | 1012 | Blacklist. | | 1013 | Not found this lastId. | | 1014 | 已超過書籍借用2本上限 | | 1015 | 此書籍正在借閱中,借閱失敗 | | 1016 | 書籍有人排隊預約,展延失敗 | | 1017 | 時段衝突,此時段已有人預約 | | 1018 | 物品已進入借用狀態,無法取消 | | 1030 | 已有他人在此時段預約\r請重新選擇起訖時間 | | 1031 | 會議時段衝突\r請重新選擇循環時段 | <br> ### socket對話資料處理型態 | type | description | | ----- |-------------| | select | App端請求「顯示用」資料。<br>ex:需要顯示書籍列表時。 | | insert | App端請求「新增」動作。<br>ex:使用者按下借用按鈕時。 | | update | App端請求「更新」動作。<br>ex:使用者更換快速入口項目時。 | | delete | App端請求「刪除」動作。<br>ex:使用者按下取消收藏按鈕時。 | | list | Server端請求刷新整個區塊資料,或僅告知事件已處理完成。<br>ex:需要顯示書籍列表時。 | | add | Server端請求新增資料到區塊中。<br>ex:當後台新增了一筆通知時。 | | modify | Server端請求更新畫面中的某筆資料。<br>ex:當後台修改了某一筆已發出通知的錯字時。 | | remove | App端請求「刪除」動作。<br>ex:大樓消防演練通知會在演練結束後自動在App端移除消失。 | -->