---
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視窗頁`

#### 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 | 可能會沒有月曆資料 |
| ----------- | -------- | -------- |
|  |  | 
|
#### 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視窗頁`

#### 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端移除消失。 |
-->