# Zhsports API --- ## 更新紀錄 - 2024/02/16 - [取得場地資訊(for預約)](#取得場地資訊(for預約)) 新增了paid,occupied_name兩個欄位 - 新增場地類別相關 [場地類別](#場地類別) - 2024/02/19 - [建立使用者資料](#建立使用者資料), [修改使用者基本資料](#修改使用者基本資料) 多了緊急聯絡人欄位 - [場地關閉維護](#場地關閉維護), [場地價格維護](#場地價格維護) 多一個欄位==until==可以指定結束日期 - 2024/02/21 - 修改[取得場地列表](#取得場地列表), 新增[修改場地資料](#修改場地資料), [上傳場地圖片](#上傳場地圖片) - 2024/02/25 - 修改[透過場地類別取得場地資訊(for預約)](#透過場地類別取得場地資訊(for預約)) and [取得場地資訊(for預約)](#取得場地資訊(for預約)) 的已經預約資料會多一個==reservation== - 新增[商品價格試算](#商品價格試算)目前只支援場地預約 - 2024/03/03 - 新增[透過場地類別取得場地價格設定列表](#透過場地類別取得場地價格設定列表),[透過場地類別設定場地預設價格](#透過場地類別設定場地預設價格),[透過場地類別新增場地價格](#透過場地類別新增場地價格),[透過場地類別刪除場地價格](#透過場地類別刪除場地價格),[透過場地類別取得場地關閉設定列表](#透過場地類別取得場地關閉設定列表),[透過場地類別新增場地關閉](#透過場地類別新增場地關閉),[透過場地類別刪除場地關閉](#透過場地類別刪除場地關閉)共七支API - 修改[透過場地類別修改場地價格](#透過場地類別修改場地價格) - 2024/03/05 - 修改[預約](#預約),多一個==occupied_name==會自動建立資料 - 2024/04/02 - 新增[其他功能](#其他功能) - 2024/04/12 - 新增[卡片相關功能](#卡片相關功能) - 2024/04/22 - 新增[批次場地預約](#預約) - 2024/04/23 - 新增[搜尋預約記錄(透過場地類別)](#搜尋預約記錄(透過場地類別)) - 2024/04/25 - 新增[重新預約(限定已取消且時段都還沒過期的)](#重新預約(限定已取消且時段都還沒過期的)) - 2024/05/22 - 新增[固定電話驗證碼](#固定電話驗證碼) - 2024/05/23 - 新增[修改固定驗證碼](#修改固定驗證碼) - 2024/06/05 - 新增[課程](#課程) - 修改[商品價格試算](#商品價格試算)新增支援課程報名結帳試算 - 2024/06/11 - 修改[課程](#課程)新增[刪除課程(還未有人報名時)](#刪除課程(還未有人報名時)),[修改課程(還未有人報名時)](#修改課程(還未有人報名時)),[刪除單堂(還未有人報名時)](#刪除單堂(還未有人報名時)),[取得選課資料(for繳費)](#取得選課資料(for繳費)) - 2024/07/01 - 新增[發票入庫(兩種做法)](#發票入庫(兩種做法)) - 2024/07/15 - 修改[拿敬老卡列表(沿用舊系統的員工卡列表加上參數)](#拿敬老卡列表(沿用舊系統的員工卡列表加上參數))加了月卡相關的回應 - 2024/07/18 - 新增[透過QRCode課程報到](#透過QRCode課程報到) - 2024/07/22 - 新增[補票查詢](#補票查詢),[補票](#補票),[列印信用卡簽單](#列印信用卡簽單) - 2024/08/01 - 修改[取得選課資料(for繳費or點名)](#取得選課資料(for繳費or點名))新增回應的欄位==invoice== - 修改[取得場地資訊(for預約)](#取得場地資訊(for預約))新增回應的資料==order_info== - 2024/08/09 - 修改[拿敬老卡列表(沿用舊系統的員工卡列表加上參數)](#拿敬老卡列表(沿用舊系統的員工卡列表加上參數))新增type參數==app_monthly== - 2024/08/16 - 新增[交易紀錄查詢](#交易紀錄查詢),[交易紀錄查詢(單筆)](#交易紀錄查詢(單筆)),[交易紀錄作廢/折讓](#交易紀錄作廢/折讓) - 2024/08/20 - 新增[統計(會員人數)](#統計(會員人數)) - 2024/08/26 - 修改[預約](#預約)加入了==備註== - 2024/08/27 - 修改[交易紀錄查詢](#交易紀錄查詢),新增參數==by== - 2024/09/10 - 新增[Kiosk相關](#Kiosk相關), [結帳](#結帳), [取得結帳紀錄](#取得結帳紀錄) - 2024/09/11 - 修改[取得場地資訊(for預約)](#取得場地資訊(for預約))新增回應的資料==order_info中的vat== - 2024/09/16 - 新增[結帳(POS版)](#結帳(POS版)), [取得結帳紀錄(POS版)](#取得結帳紀錄(POS版)) - 2024/09/19 - 新增[課程欄位解說](#課程欄位解說)的數個新欄位:==enable_returning_student_discount, previous_course, returning_student_threshold, returning_student_after_discount_unit_price, returning_student_after_discount_total_price== - 2024/09/24 - 修改[商品價格試算](#商品價格試算)新增支援==課程舊生優惠== - 2024/09/26 - 新增[確認有無符合舊生優惠](#確認有無符合舊生優惠) - 2024/10/11 - 新增[取得Kiosk印表機狀態(建議每30秒call一次)](#取得Kiosk印表機狀態建議每30秒call一次) - 2024/10/21 - 修改[取得結帳紀錄](#取得結帳紀錄) - 修改[取得結帳紀錄(POS版)](#取得結帳紀錄(POS版)) - 2024/10/23 - 新增[取得Kiosk設定及狀態(POS及KIOSK用)](#取得Kiosk設定及狀態(POS及KIOSK用)) - 新增[設定Kiosk(POS用)](#設定Kiosk(POS用)) - 2024/10/26 - 新增KIOSK的api[Heartbeat](#Heartbeat) - 修改[取得Kiosk設定及狀態(POS及KIOSK用)](#取得Kiosk設定及狀態(POS及KIOSK用)),回傳多一個欄位==app_alive== - 2024/10/27 - 修改[取得Kiosk設定及狀態(POS及KIOSK用)](#取得Kiosk設定及狀態(POS及KIOSK用))及[設定Kiosk(POS用)](#設定Kiosk(POS用)),多一個欄位==enable== - 2024/11/13 - 新增[查詢場地預約紀錄](#查詢場地預約紀錄) - 2025/01/03 - 新增[建立APP通知任務](#建立APP通知任務) - 新增[取得APP通知任務列表](#取得APP通知任務列表) - 新增[修改APP通知任務](#修改APP通知任務正在執行中的無法修改date-time) - 新增[刪除/取消APP通知任務](#刪除取消APP通知任務會將執行到一半的任務取消) - 2025/01/13 - 新增[發票相關特別操作](#發票相關特別操作) - 2025/02/26 - 修改[交易紀錄查詢](#交易紀錄查詢),多一個欄位:==transaction_id== - 2025/03/07 - 新增[建立APP的操作](#建立APP的操作) - 新增[修改APP的操作](#修改APP的操作) - 新增[刪除APP的操作](#刪除APP的操作) - 新增[取得APP的操作列表](#取得APP的操作列表) - 2025/03/14 - 新增[建立月卡的操作](#建立月卡的操作) - 新增[執行月卡的操作](#執行月卡的操作) - 新增[刪除月卡的操作](#刪除月卡的操作) - 新增[取得月卡的操作列表](#取得月卡的操作列表) - 2025/04/14 - 修改[建立月卡的操作](#建立月卡的操作),多一個欄位:==specific== - 2025/04/29 - 修改[建立APP的操作](#建立APP的操作),多了兩個欄位:==comment==, ==reason== - 2025/05/08 - 修改[查詢場地預約紀錄](#查詢場地預約紀錄),多一個欄位:==canceled_at== - 新增[建立報表類別](#建立報表類別) - 新增[修改報表類別](#修改報表類別) - 新增[刪除報表類別](#刪除報表類別) - 新增[取得報表類別列表](#取得報表類別列表) - 2025/05/29 - 修改[建立報表類別](#建立報表類別) [修改報表類別](#修改報表類別) [取得報表類別列表](#取得報表類別列表) 多一個欄位:==childrn== - 2025/06/11 - 修改[建立報表類別](#建立報表類別) [修改報表類別](#修改報表類別) [取得報表類別列表](#取得報表類別列表) 多一個欄位:==code== - 2025/07/29 - 修改[取得使用者列表](#取得使用者列表),修改成支援分頁排序及搜尋 - 2025/08/19 - 新增[補印](#補印) --- ``` Test Url: http://192.168.5.206:8964 Product Url: http://192.168.5.200:8964 ``` ## 注意事項 - 他們會需要編輯自己的商品id, 所以零售商品/購課他們都會有自己編的id - 除了登入以外所有的Request都會需要Authorization Header: zhs [token] ## 登入員工 ``` POST /staff ``` - Body ```jsonld= { "account": "richard", "password": "richard" } // or curtis/curtis allen/allen ``` - Response ``` [token] // 將這個token放到之後所有的Request中的Header: Authorization=zhs [token] ``` ## 取得登入員工帳號的資訊 ``` GET /me ``` - Response ```jsonld= { "expired_at": 1707143598, // [unix timstamp] 這個token過期的時間 "functions": [ { "desc": "建立員工帳號", "method": "POST", "path": "/staff", "type": "api" }, { "desc": "結帳", "method": "POST", "path": "/checkout", "type": "api" }, { "desc": "編輯使用者帳號", "method": "PUT", "path": "/user/:id", "type": "api" }, { "desc": "取得角色列表", "method": "GET", "path": "/roles", "type": "api" }, { "desc": "取得使用者清單", "method": "GET", "path": "/users", "type": "api" }, { "desc": "建立使用者帳號", "method": "POST", "path": "/user", "type": "api" }, { "desc": "建立角色", "method": "POST", "path": "/role", "type": "api" }, { "desc": "取得員工帳號列表", "method": "GET", "path": "/staffs", "type": "api" }, { "desc": "編輯零售商品", "method": "PUT", "path": "/retail/:id", "type": "api" }, { "desc": "建立權限功能", "method": "POST", "path": "/function", "type": "api" }, { "desc": "刪除權限功能", "method": "DELETE", "path": "/function/:id", "type": "api" }, { "desc": "取得後台統計數字", "method": "GET", "path": "/statistics", "type": "api" }, { "desc": "刪除員工帳號", "method": "DELETE", "path": "/staff/:id", "type": "api" }, { "desc": "編輯員工帳號", "method": "PUT", "path": "/staff/:id", "type": "api" }, { "desc": "取得零售商品列表", "method": "GET", "path": "/retails", "type": "api" }, { "desc": "建立零售商品", "method": "POST", "path": "/retail", "type": "api" }, { "desc": "取得權限列表", "method": "GET", "path": "/functions", "type": "api" }, { "desc": "編輯角色權限", "method": "PUT", "path": "/role/:id", "type": "api" } ], "id": "e6a590ea-8eba-4b99-9ec1-0ab321d1de88", "name": "richard", "role": "super" } ``` --- # 會員系統 ## 建立使用者資料 ``` POST /user ``` - Body ```jsonld= { "phone": "+886972957297", // 這個是主key之後app登入也是用這個務必要用+886開頭 "profile": { "name": "Richard", "email": "test@gmail.com", "gender": "男", // 男/女/不指定 "birthday": "1984/01/01", "emergencyContactName": "tester", "emergencyContactPhone": "0212345678" } } ``` - Response ```jsonld= { "banned": false, "id": "pos_bfc40179-6e27-4ce5-97a0-e78fecd5e221", "inserted_at": "2024-02-05T02:40:06", "latest_sync": 1707100806, "phone": "+886972957297", "profile": { "birthday": "1984/01/01", "email": "test@gmail.com", "gender": "男", "name": "Richard", "emergencyContactName": "tester", "emergencyContactPhone": "0212345678" }, "updated_at": "2024-02-05T02:40:06", "headshot": "http://zhs.toolset.biz:8964/user/headshot/pos_bfc40179-6e27-4ce5-97a0-e78fecd5e221" } ``` ## 上傳使用者頭像 ``` POST /user/[user id]/headshot ``` - Body [form-data] ``` headshot: [頭像檔案.png/.jpg] ``` - Response ``` ok ``` ## 取得使用者列表 ``` GET /users ``` - Query Parameters - search_key: phone(預設) or name or id - term: 關鍵字,電話(可以是09/9/+886/886/其他號碼開頭) - size: 每頁的筆數 - page: 第幾頁 - dir: asc or desc排序方向(目前寫死以電話排序) - Response(無參數時) ```jsonld= [ { "banned": false, "id": "pos_bfc40179-6e27-4ce5-97a0-e78fecd5e221", "headshot": [頭像url], "inserted_at": "2024-02-05T02:40:06", "latest_sync": 1707100806, "phone": "+886972957297", "profile": { "birthday": "1984/01/01", "email": "test@gmail.com", "gender": "男", "name": "Richard", "emergencyContactName": "tester", "emergencyContactPhone": "0212345678" }, "updated_at": "2024-02-05T02:40:06" } ] ``` - Response(有參數時) ```jsonld= { "count": 17144, // 總筆數 "dir": "desc", // 排序方向 "list": [ { "banned": false, "headshot": "https://zhs.mraytec.com/user/headshot/pos_83500963-89cb-417b-8c7c-23dd6f741c86?t=43224", "id": "pos_83500963-89cb-417b-8c7c-23dd6f741c86", "inserted_at": "2024-09-17T02:18:21", "latest_sync": 1726539501, "phone": "+886999999999", "profile": { "name": "維修中" }, "updated_at": "2024-09-17T02:18:21" }, ... ], "max_page": 858, // 總頁數 "page": 1, // 目前是第幾頁 "size": 20 // 每頁的筆數 } ``` ## 搜尋使用者 ``` GET /users/search ``` - Query Parameters - term: 會員電話關鍵字(可以是09/9/+886/886/其他號碼開頭) - Response ```jsonld= [ { "banned": false, "id": "pos_bfc40179-6e27-4ce5-97a0-e78fecd5e221", "inserted_at": "2024-02-05T02:40:06", "latest_sync": 1707100806, "phone": "+886972957297", "profile": { "birthday": "1984/01/01", "email": "test@gmail.com", "gender": "男", "name": "Richard", "emergencyContactName": "tester", "emergencyContactPhone": "0212345678" }, "updated_at": "2024-02-05T02:40:06" } ] ``` ## 修改使用者基本資料 ``` PUT /user/[user_id] ``` - Body ```jsonld= { "name": "Richard123", "email": "test123@gmail.com", "gender": "男", "birthday": "1984/02/01", "emergencyContactName": "tester", "emergencyContactPhone": "0212345678" } ``` - Response ``` ok ``` --- # 其他功能 ## 開門 ``` PUT /gate/pass ``` - Body ```jsonld= { "position": "pool", // "pool" 泳池 "fitness" 健身房 "direction": "enter" // "enter" 進去 "exit" 出來 } ``` - Response ``` ok ``` ## 取得人流 ``` GET /state/:position ``` - position: "pool" 泳池 "fitness" 健身房 - Response ```jsonld= { "value": 0 // 人數 } ``` ## 統計(會員人數) ``` GET /statistics/users ``` - Response ```jsonld= { "app": 5088, // APP註冊的 "pos": 1630 // POS建的 } ``` ## 取得Kiosk印表機狀態(建議每30秒call一次) ``` GET /machine/notify ``` - Response ```jsonld= { "alert": false, // 當為true時將下面message的訊息show出來 "message": "所有印表機狀態正常" } ``` ## 取得Kiosk設定及狀態(POS及KIOSK用) ``` GET /machine/kiosks ``` - Response (POS的) ```jsonld= { "kiosks": [ { "alive": false, // 機台狀態 "comment": "", // 備註 "course_attend": false, // 啟用課程報到 "fitness_compansate": false, // 啟用健身房補票 "fitness_ticket": false, // 啟用健身房全票 "ip": "192.168.17.41", // ip "location": "unknown", // 位置 "name": "櫃台售票機", // 名稱 "pool_ticket": false, // 啟用泳池全票 "printer": false, // 印表機狀態 "app_alive": false, // Kiosk APP狀態 "enable": true // 啟用?true/false }, { "alive": false, "comment": "", "course_attend": false, "fitness_compansate": false, "fitness_ticket": false, "ip": "192.168.17.43", "location": "unknown", "name": "Kiosk3", "pool_ticket": false, "printer": false, "app_alive": false, "enable": true }, { "alive": false, "comment": "", "course_attend": false, "fitness_compansate": false, "fitness_ticket": false, "ip": "192.168.17.42", "location": "大廳", "name": "櫃台售票機2", "pool_ticket": false, "printer": false, "app_alive": false, "enable": true } ] } ``` - Response (KIOSK的會給的資料是根據送request的ip) ```jsonld= { "alive": false, "comment": "", "course_attend": false, "fitness_compansate": false, "fitness_ticket": false, "ip": "192.168.17.42", "location": "大廳", "name": "櫃台售票機2", "pool_ticket": false, "printer": false, "app_alive": false, "enable": true } ``` ## 設定Kiosk(POS用) ``` PUT /machine/kiosks/[ip] ``` - Body ```jsonld= { "name": "櫃台售票機2", // 名稱 "location": "大廳", // 位置 "fitness_ticket": false, // 啟用健身房全票 "pool_ticket": false, // 啟用泳池全票 "fitness_compansate": false, // 啟用健身房補票 "course_attend": false, // 啟用課程報到 "enable": false, // 啟用?true/false "comment": "" // 備註 } ``` - Response ``` ok ``` ## 補印 ### 小白單 ``` PUT /print/course_detail ``` - Body ```jsonld= { "order_id": "xxxxxxxxx", // 訂單id } ``` ### 報到QRCode ``` PUT /print/course_attendance ``` - Body ```jsonld= { "phone": "+886912345678", "course": "course id" } ``` - Response ``` ok ``` --- # APP相關 ## 建立APP通知任務 ``` POST /notifications ``` - Body ```jsonld= { "course": "課程id", "phone": "+886xxxxxxxxx", // 使用者電話 phone跟student必須要有一個 "student": "xxxxxxxxx" // 學生id phone跟student必須要有一個 } ``` - Response ``` ok ``` ## 取得APP通知任務列表 ``` GET /notifications ``` - Response ```jsonld= [ { "id": "935aa73d-94d2-4134-bfb4-f9f4fff54a84", "status": "未執行", // 目前狀態 "date": "2025/01/03", "time": "12:25", "progress": null, // 目前進度 會以(已發送/總數)顯示如:10/999 還沒開始會是null "title": "test title", "comment": "test", "content": "test content", "inserted_at": "2025/01/03 12:17", "updated_at": "2025/01/03 12:17" } ] ``` ## 修改APP通知任務(正在執行中的無法修改date, time) ``` PUT /notifications/[notification id] ``` - Body ```jsonld= { "date": "2025/01/03", // 日期 *無法比目前早 "time": "12:30", // 時間 "title": "test title", // 標題 "content": "test content", // 內容 "comment": "test" // comment } ``` - Response ``` ok ``` ## 刪除/取消APP通知任務(會將執行到一半的任務取消) ``` DELETE /notifications/[notification id] ``` - Response ``` ok ``` ## 建立APP的操作 ``` POST /app_operations ``` - Body ```jsonld= // 建立app公告 { "comment": "xxoo", "reason": "ooxx", "type": "announce", // 公告必定是announce "start": "2025-03-06 00:00:00", // 開始 "until": "2025-03-08 23:00:00", // 結束 "announce_title": "重大公告", // 公告標題 "announce_content": "系統將於2025年3月6日進行維護,預計維護時間為2025年3月6日00:00:00至2025年3月8日23:00:00。維護期間,系統將無法正常使用,請您提前做好準備。" // 公告內容 } // 建立app的售票,場地,課程這三項服務的關閉 { "comment": "xxoo", "reason": "ooxx", "type": "service", // 服務必定是service "start": "2025-03-06 00:00:00", // 開始 "until": "2025-03-08 23:00:00", // 結束 "ticket": false, // 售票false是關閉預設是開啟 "reservation": false, // 場地預約 "course": false // 課程報名 } ``` - Response ```jsonld= // 公告 { "announce_content": "系統將於2025年3月6日進行維護,預計維護時間為2025年3月6日00:00:00至2025年3月8日23:00:00。維護期間,系統將無法正常使用,請您提前做好準備。", "announce_title": "重大公告", "comment": "xxoo", "reason": "ooxx", "created_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4", "enabled": true, // 這個設定的開關true是開false是關 "id": "a32bb1f4-bf64-4037-9aa0-7527664089be", "inserted_at": "2025/03/07 10:57:44", "start": "2025/03/06 00:00:00", "type": "announce", "until": "2025/03/08 23:00:00", "updated_at": "2025/03/07 10:57:44", "updated_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4" } // 服務 { "enabled": true, // 這個設定的開關true是開false是關 "id": "23958b65-90dc-4904-8c5d-a1fc5a25f33f", "start": "2025/03/06 00:00:00", "type": "service", "until": "2025/03/06 23:00:00", "comment": "xxoo", "reason": "ooxx", "ticket": false, "inserted_at": "2025/03/07 11:42:21", "updated_at": "2025/03/07 11:42:21", "course": false, "created_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4", "updated_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4", "reservation": false } ``` ## 修改APP的操作 ``` PUT /app_operations/[app operation id] ``` - Body ```jsonld= // 公告 { "announce_title": "test123" } // 服務 { "ticket": true, "reservation": true, "course": true } ``` - Response ``` 同建立 ``` ## 刪除APP的操作 ``` DELETE /app_operations/[app operation id] ``` - Response ``` ok ``` ## 取得APP的操作列表 ``` GET /app_operations ``` - Response ```jsonld= { "count": 2, "rows": [ { "enabled": true, "id": "a32bb1f4-bf64-4037-9aa0-7527664089be", "start": "2025/03/06 00:00:00", "type": "announce", "until": "2025/03/08 23:00:00", "comment": "xxoo", "reason": "ooxx", "inserted_at": "2025/03/07 10:57:44", "updated_at": "2025/03/07 11:00:58", "created_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4", "updated_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4", "announce_content": "系統將於2025年3月6日進行維護,預計維護時間為2025年3月6日00:00:00至2025年3月8日23:00:00。維護期間,系統將無法正常使用,請您提前做好準備。", "announce_title": "test123" }, { "enabled": true, "id": "23958b65-90dc-4904-8c5d-a1fc5a25f33f", "start": "2025/03/06 00:00:00", "type": "service", "until": "2025/03/06 23:00:00", "comment": "ooxx", "reason": "xxoo", "ticket": false, "inserted_at": "2025/03/07 11:42:21", "updated_at": "2025/03/07 11:42:21", "course": false, "created_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4", "updated_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4", "reservation": false } ] } ``` --- --- # Kiosk相關 ## Tokens - Kiosk1: k_125dddf4-4a11-4ac3-a092-e57fa15331ce - Kiosk2: k_acd1854a-915e-4e8e-a79f-c15c537c9a56 - Kiosk3: k_ff8066f1-1f9e-4f57-b5f7-abff8620e744 ## HTTP Header ``` Authorization: Kiosk [token] ``` ## 結帳 ``` PUT /creditcardsettlement ``` - Body ```jsonld= { "token": "[token]", // 請用[員工登入]拿到的token "data": { // 隨便要放什麼都可以 "test1": "value1", "test2": "value2" } } ``` - Response ``` ok ``` ## 取得結帳紀錄 ``` GET /creditcardsettlement ``` - Query Parameters - token: 請用[員工登入]拿到的token,必填 - filter: today/week/month/date 可以用這三個參數不給的時候預設today,其他就代表從今天往後7天/30天 - date: yyyy/MM/dd 只有當filter為date時才會生效 - Response: ```jsonld= { "count": 1, "datas": [ { "data": { // 結帳時用存入的資料 "test1": "value1", "test2": "value2" }, "date": "2024/09/10", // 結帳的日期 "time": "14:35:10", // 結帳的時間 "from": "127.0.0.1", // 哪一臺結的帳 "by": "richard" // 哪個帳號結的帳 } ] } ``` ## Heartbeat ``` PUT /machine/kiosks/heartbeat ``` - Response: ``` ok ``` --- --- # 一般POS功能 ## 上架零售商品 ``` POST /retail ``` - Body ```jsonld= { "id": "R001", "name": "毛巾(小)", "desc": "小條毛巾", "price": 300 } ``` - Response ```jsonld= { "comment": null, "created_by": "6bf4f54c-9e69-40a8-87f9-0e2ab6b2b1fa", "desc": "小條毛巾", "hide": null, "id": "R001", "inserted_at": "2024-02-05T05:00:25", "name": "毛巾(小)", "price": 300, "updated_at": "2024-02-05T05:00:25" } ``` ## 取得零售商品列表 ``` GET /retails?all=false ``` - Query Parameters - all: false就不會包括hide=true的 - Response ```jsonld= [ { "comment": null, "created_by": "6bf4f54c-9e69-40a8-87f9-0e2ab6b2b1fa", "desc": "小條毛巾", "hide": false, "id": "R001", "inserted_at": "2024-02-05T05:00:25", "name": "毛巾(小)", "price": 300, "updated_at": "2024-02-05T05:00:25" } ] ``` ## 使用id搜尋零售商品 ``` GET /retails/search ``` - Query Parameters - key: 商品id的內容 ex: R - Response ```jsonld= [ { "comment": null, "created_by": "6bf4f54c-9e69-40a8-87f9-0e2ab6b2b1fa", "desc": "小條毛巾", "hide": false, "id": "R001", "inserted_at": "2024-02-05T05:00:25", "name": "毛巾(小)", "price": 300, "updated_at": "2024-02-05T05:00:25" } ] ``` ## 修改零售商品資料 ``` PUT /retail/[retail id] ``` - Body ```jsonld= { "price": 1000, "hide": true, "comment": "test" } ``` - Response ``` ok ``` ## 商品價格試算 ``` PUT /checkout/calculate ``` - Body ```jsonld= { "items": [ // 以下是當場地預約試算價格時要傳 { "type": "reservation", "field": "3樓羽球場A", "date": "2024/02/26", "time": "12:00", "duration": 150 }, // 以下是當課程報名試算價格時要傳 { "type": "course", "takes": [...] // 報名id array } ] } ``` - Response ```jsonld= { "items": [ { "date": "2024/02/26", "duration": 150, "field": "3樓羽球場A", "price": 1250, // 各個品項的價格 "time": "12:00", "type": "reservation" }, { "type": "course", "takes": [...], // 報名id array "price": 100, "match_returning_student_discount": true/false, // 有無符合舊生優惠 "origin_price": 200 // 原價,當match_returning_student_discount==true時才會有 } ], "total": 2250 // 總金額 } ``` ## 結帳 ``` POST /checkout ``` - Body ```jsonld= { "items": [ { "type": "retail", "item": "R001", "price": 300, "count": 2, "cost": 550 }, { "type": "retail", "item": "R001", "price": 300, "count": 2, "cost": 600 } ] } ``` - Response ``` ok ``` ## 發票入庫(兩種做法) ``` POST /invoices ``` - Body [form-data] (上傳CSV) ``` file: [.csv] // 一定要是財政部的csv ``` - Body (手動) ```jsonld= { "month": "113/09~113/10", // 發票的月份 "word_track": "CC", // 發票頭兩碼 "begin": "00000000", // 發票起 "finish": "00000100" // 發票迄 } ``` - Response ``` ok ``` ## 補票查詢 ``` GET /pass/[掃到的內容] ``` - Response ```jsonld= { "overtime": 60, // 超時的秒數, "enter_at": "2024/07/22 05:19", // 進場的時間 "name": "ooxx", //票券名稱 "compensate": 50, // 試算出的補票金額 "after_compensate": "2024/07/22 07:19" // 補票後要什麼時候之前離開 } ``` ## 補票 ``` POST /sales ``` - Body (欄位與結帳的一模一樣,但是多了一個欄位) ```jsonld= { "amount": 50, "carrier_num": "/14ZREPR", "carrier_type": 0, "creditcard": "", "items": [ { "count": 1, "item": 4, "price": 50, "type": 0, "ticket": "ooxx" // 讀卡機讀取到的內容,必填不然不會自動補票,只會產生一筆交易 } ], "love_code": "", "paymentType": 0, "print_detail": true, } ``` ## 列印信用卡簽單 ``` PUT /print/creditcardtx ``` - Body ```jsonld= 卡機給的所有資料的json ``` - Response ``` ok ``` --- ## 交易紀錄查詢 ``` GET /orders ``` - Query Parameters (date預設當日,start必須與end一起使用不然沒有效果,date與start/end一起用時只會生效date,==用by的時候其他條件都會忽略==) - date: 指定日期(yyyy/MM/dd) - start: 開始日期(yyyy/MM/dd) - end: 結束日期日期(yyyy/MM/dd) - ==by: 訂單擁有者(+886開頭會員,目前不支援pos機)== - Response ```jsonld { "count": 123, //筆數 "rows": [ { "id": 2024080100001, // 訂單編號 "fid": "20240801000030", // 訂單假編號(APP上顯示) "status": "已付款", // 狀態直接顯示就好 "date": "20240801", // 日期 "time": "00:00:30", // 時間 "source": "APP", // 訂單來源 "pay_type": "APP線上刷卡", // 付款方式 "invoice": "DN02586742", // 發票號碼 "by": "+886970363575", // 訂單擁有者+886開頭是會員 pos機會用uuid "cost": 300, // 總金額 "transaction_id": "txxxxxxx" // 金流平台上的交易編號 } ... ] } ``` ## 交易紀錄查詢(單筆) ``` GET /orders/[訂單編號] ``` - Response ```jsonld { "id": 2024080100001, // 訂單編號 "fid": "20240801000030", // 訂單假編號(APP上顯示) "status": "已付款", // 狀態直接顯示就好 "date": "20240801", // 日期 "time": "00:00:30", // 時間 "source": "APP", // 訂單來源 "pay_type": "APP線上刷卡", // 付款方式 "invoice": "DN02586742", // 發票號碼 "by": "+886970363575", // 訂單擁有者+886開頭是會員 pos機會用uuid "cost": 300, // 總金額 "items": [ { "name": "3樓羽球場E", // 品名 "count": 1, // 數量 "price": 300, // 單價 "cost": 300, // 總價 } ] } ``` ## 交易紀錄作廢/折讓 ``` DELETE /orders/[訂單編號] ``` - Response ```jsonld ok or 下載折讓單 ``` ## 結帳(POS版) ``` PUT /creditcardsettlement ``` - Body ```jsonld= { "token": "[Kiosk的token]", // 不放時下面的api from會是call api的機器ip, 有給的話就會是token "data": { // 隨便要放什麼都可以 "test1": "value1", "test2": "value2" } } ``` - Response ``` ok ``` ## 取得結帳紀錄(POS版) ``` GET /creditcardsettlement ``` - Query Parameters - filter: today/week/month/date 可以用這三個參數不給的時候預設today,其他就代表從今天往後7天/30天 - date: yyyy/MM/dd 只有當filter為date時才有用 - Response: ```jsonld= { "count": 1, "datas": [ { "data": { // 結帳時用存入的資料 "test1": "value1", "test2": "value2" }, "date": "2024/09/10", // 結帳的日期 "time": "14:35:10", // 結帳的時間 "from": "127.0.0.1", // 哪一臺結的帳 "by": "richard" // 哪個帳號結的帳 } ] } ``` ## 發票相關特別操作 ``` PUT /invoices/[invoice_number]/[method] ``` - methods - ==cancel_creditnote== 取消折讓 - ==force_cancel== 直接作廢(超過一天以上也可以) - ==undo_cancel== 取消作廢 *==取消的操作不會回復場地預約跟課程報名== - Response ``` ok ``` # 場地預約 ## 取得場租類型列表 ``` GET /reservation_types ``` - Response ```jsonld= [ { "id": "handicapped", "name": "身心障礙", "color": "#d20382" // 區塊背景顏色 }, { "id": "normal", "name": "臨租長租", "color": "#b37a1f" }, { "id": "event", "name": "活動包場", "color": "#7d00f0" }, { "id": "classroom", "name": "課程使用", "color": "#77c137" } ] ``` ## 取得場地列表 ``` GET /fields ``` ### 欄位解說 * id: 場地的id * disabled: 這個場地無法預約(也不會顯示在app) * image: 場地的圖片網址 * profile: app上面顯示的訊息有可能為null(目前先用introduction) - Response ```jsonld= [ { "disabled": false, "id": "3樓羽球場A", "profile": null, "image": [url] }, { "disabled": false, "id": "3樓羽球場B", "profile": { "introduction": "ooxx" }, "image": [url] }, ... ] ``` ## 上傳場地圖片 ``` POST /field/[field id]/image ``` - Body [form-data] ``` image: [.png/.jpg] ``` - Response ``` ok ``` ## 修改場地資料 ``` PUT /field/[field_id] ``` - Body ```jsonld= { "introduction": "介紹..." } ``` - Response ``` ok ``` ## 場地價格維護 ### 注意事項 - 當時間有重疊時會選擇較高金額(不包含預設) ### 欄位解說 - date: 開始的日期格式必須要是yyyy/MM/dd - repeat_type: `base在新增的時候不會用上` ```jsonld [ { "id": "base", "name": "預設" }, { "id": "no_repeat", "name": "不重複" }, { "id": "daily", "name": "每日" }, { "id": "weekly", "name": "每週" }, { "id": "monthly", "name": "每月" }, { "id": "yearly", "name": "每年" } ] ``` - until: 結束日期,有給repeat_type才生效,不給就是不會結束,格式與date一樣==會計算到當天結束== - price: 金額 - start_time: 開始時間格式請用hh:mm(24小時制),可以不給代表整天 - end_time: 有給start_time才需要給,格式一樣,一定要大於start_time - comment: 備註, 加強可讀性 ### 取得場地價格設定列表 ``` GET /field/[場地id]/price ``` - Response ```jsonld= [ { "id": "233a6aba-e8c9-48da-b59e-7533307f4394", "date": "1980/01/01", "comment": "預設價格", "inserted_at": "2024-02-06T07:34:33", "updated_at": "2024-02-06T08:37:27", "end_time": "23:59", "price": 1000, "repeat_type": "base", "start_time": "00:00" }, { "id": "f6a5e476-2721-463a-bd36-568a3dc8d240", "date": "2024/01/06", "comment": "每個週六的06:00~20:00價格提高到3000直到2024/02/28", "inserted_at": "2024-02-06T08:44:49", "updated_at": "2024-02-06T08:44:49", "end_time": "20:00", "price": 3000, "repeat_type": "weekly", "until": "2024/02/28", "start_time": "06:00" } ] ``` ### 設定場地預設價格 ``` PUT /field/[場地id]/price/base ``` - Body ```jsonld= { "price": 1000 } ``` - Response ``` ok ``` ### 新增場地價格 ``` POST /field/[場地id]/price ``` - Body ```jsonld= { "date": "2024/01/06", "repeat_type": "weekly", "until": "2024/02/28", "price": 3000, "start_time": "06:00", "end_time": "20:00", "comment": "每個週六的06:00~20:00價格提高到3000" } ``` - Response ``` ok ``` ### 刪除場地價格 ``` DELETE /field/[場地id]/price/[場地價格id] ``` - Response ``` ok ``` ## 場地關閉維護 ### 欄位解說 - date: 開始的日期格式必須要是yyyy/MM/dd - repeat_type: ```jsonld [ { "id": "no_repeat", "name": "不重複" }, { "id": "daily", "name": "每日" }, { "id": "weekly", "name": "每週" }, { "id": "monthly", "name": "每月" }, { "id": "yearly", "name": "每年" } ] ``` - until: 結束日期,有給repeat_type才生效,不給就是不會結束,格式與date一樣==會計算到當天結束== - start_time: 開始時間格式請用hh:mm(24小時制),可以不給代表整天 - end_time: 有給start_time才需要給,格式一樣,一定要大於start_time - comment: 備註, 加強可讀性 ### 取得場地關閉設定列表 ``` GET /field/[場地id]/close ``` - Response ```jsonld= [ { "id": "f6a5e476-2721-463a-bd36-568a3dc8d240", "date": "2024/01/06", "comment": "每個週六的06:00~20:00休息直到2024/02/28", "inserted_at": "2024-02-06T08:44:49", "updated_at": "2024-02-06T08:44:49", "end_time": "20:00", "repeat_type": "weekly", "until": "2024/02/28", "start_time": "06:00" } ] ``` ### 新增場地關閉 ``` POST /field/[場地id]/close ``` - Body ```jsonld= { "date": "2024/01/06", "repeat_type": "weekly", "until": "2024/02/28", "start_time": "06:00", "end_time": "20:00", "comment": "每個週六的06:00~20:00休息直到2024/02/28" } ``` - Response ``` ok ``` ### 刪除場地關閉 ``` DELETE /field/[場地id]/close/[場地關閉id] ``` - Response ``` ok ``` ## 場地類別 ### 取得場地類別列表 ``` GET /field/categories ``` - Response ```jsonld= [ { "id": "羽球", "fields": null } ] ``` ### 新增場地類別 ``` POST /field/category ``` - Body ```jsonld= { "id": "羽球" } ``` - Response ``` ok ``` ### 修改場地類別包含的場地 ``` PUT /field/category/[類別id] ``` - Body ```jsonld= { "fields": ["3樓羽球場A","3樓羽球場B"] } ``` - Response ``` ok ``` ### 刪除場地類別 ``` DELETE /field/category/[類別id] ``` - Response ``` ok ``` ### 透過場地類別取得場地資訊(for預約) ``` GET /field/category/[類別id] ``` - Query Parameters - mode: half 時段模式(不給的話是1小時一個時段,給half是半小時一個時段) - date: 指定日期 - Response ```jsonld= [ { "field": "[場地id]", "blocks": [ ...// 結構跟 [取得場地資訊(for預約)] 一樣 ] }, ... ] ``` ### 透過場地類別取得場地價格設定列表 ``` GET /field/category/[類別id]/price ``` - Response ```jsonld= [ { "id": "233a6aba-e8c9-48da-b59e-7533307f4394", "date": "1980/01/01", "comment": "預設價格", "inserted_at": "2024-02-06T07:34:33", "updated_at": "2024-02-06T08:37:27", "end_time": "23:59", "price": 1000, "repeat_type": "base", "start_time": "00:00" }, { "id": "f6a5e476-2721-463a-bd36-568a3dc8d240", "date": "2024/01/06", "comment": "每個週六的06:00~20:00價格提高到3000直到2024/02/28", "inserted_at": "2024-02-06T08:44:49", "updated_at": "2024-02-06T08:44:49", "end_time": "20:00", "price": 3000, "repeat_type": "weekly", "until": "2024/02/28", "start_time": "06:00" } ] ``` ### 透過場地類別修改場地價格 ``` PUT /field/category/[類別id]/price/:fp_id ``` ==fp_id是base時是設定預設價格其他就用上面的API拿到的id== - Body ```jsonld= { "price": 1000 } ``` - Response ``` ok ``` ### 透過場地類別新增場地價格 ``` POST /field/category/[類別id]/price ``` - Body ```jsonld= { "date": "2024/01/06", "repeat_type": "weekly", "until": "2024/02/28", "price": 3000, "start_time": "06:00", "end_time": "20:00", "comment": "每個週六的06:00~20:00價格提高到3000" } ``` - Response ``` ok ``` ### 透過場地類別刪除場地價格 ``` DELETE /field/category/[類別id]/price/[場地價格id] ``` - Response ``` ok ``` ### 透過場地類別取得場地關閉設定列表 ``` GET /field/category/[類別id]/close ``` - Response ```jsonld= [ { "id": "f6a5e476-2721-463a-bd36-568a3dc8d240", "date": "2024/01/06", "comment": "每個週六的06:00~20:00休息直到2024/02/28", "inserted_at": "2024-02-06T08:44:49", "updated_at": "2024-02-06T08:44:49", "end_time": "20:00", "repeat_type": "weekly", "until": "2024/02/28", "start_time": "06:00" } ] ``` ### 透過場地類別新增場地關閉 ``` POST /field/category/[類別id]/close ``` - Body ```jsonld= { "date": "2024/01/06", "repeat_type": "weekly", "until": "2024/02/28", "start_time": "06:00", "end_time": "20:00", "comment": "每個週六的06:00~20:00休息直到2024/02/28" } ``` - Response ``` ok ``` ### 透過場地類別刪除場地關閉 ``` DELETE /field/category/[類別id]/close/[場地關閉id] ``` - Response ``` ok ``` ## 場地預約相關 ### 注意事項 - 系統這裡會控制可以預約的時間(`目前是3天`) - 每個時段目前預設1個小時(有參數可以切換成半小時) ### 取得場地資訊(for預約) ``` GET /field/[場地id] ``` - Query Parameters - mode: half 時段模式(不給的話是1小時一個時段,給half是半小時一個時段) - date: 指定日期 - Response ```jsonld= [ { "date": "2024/02/07", // 日期 "blocks": [ // 時段列表 { "available": false, // 可預約與否 "comment": "超時", // 無法預約的原因 "price": 1500, // 價格 "start_time": "00:00", // 時段開始時間 "end_time": "00:59" // 時段結束時間 }, { "available": false, "comment": "整修", "price": 1500, "start_time": "01:00", "end_time": "01:59" }, { "available": false, "comment": "超時", "price": 1500, "start_time": "02:00", "end_time": "02:59" }, { "available": true, "price": 1500, "start_time": "03:00", "end_time": "03:59" }, { "available": true, "price": 1500, "start_time": "04:00", "end_time": "04:59" }, { "available": true, "price": 1500, "start_time": "05:00", "end_time": "05:59" }, { "available": true, "price": 1500, "start_time": "06:00", "end_time": "06:59" }, { "available": true, "price": 1500, "start_time": "07:00", "end_time": "07:59" }, { "available": true, "price": 1500, "start_time": "08:00", "end_time": "08:59" }, { "available": true, "price": 1500, "start_time": "09:00", "end_time": "09:59" }, { "field": "3樓羽球場A", // 已預約的場地id "available": false, "price": 1500, "start_time": "10:00", "end_time": "10:59", "occupied_by": "pos", // 從哪預約 pos/phone/app "occupied_id": "+886972957297", // 預約會員電話(務必要用+886開頭) "occupied_name": "Richard", // 預約會員姓名 "bgcolor": "#b37a1f", // 區塊背景顏色 "border_color": "#000000", // 區塊邊框顏色 "paid": true, // 已付款? true/false "reservation_type": "normal", // 對應到上面的reservation_types api "reservation_id": "1ed3fe67-18d5-4be3-b1e8-4774dea55047", // 預約的id可用來之後的操作, "reservation": { ... // 格式請參考[搜尋預約記錄] }, "order_info": { // 訂單相關內容 "order": 2024080100001, // 訂單編號 "invoice": "AA00000001", // 發票號碼,有開才會有 "created_at": "2024/08/01 07:00:00", // 預約時間,預約產生的時間 "paid_at": "2024/08/01 07:02:00", // 繳費時間,成功繳費的時間 "vat": "ooxx" // 統編,null的時候代表沒有或者已作廢折讓 } }, { "available": true, "price": 1500, "start_time": "11:00", "end_time": "11:59" }, { "available": true, "price": 1500, "start_time": "12:00", "end_time": "12:59" }, ... ] }, ... ] ``` ### 預約 ``` POST /reservation ``` - 注意事項 - ==批次預約是提供一個方便的介面,實際上是根據參數展開成數個時段!== - Body ```jsonld= { "type": "normal", // 對應上面的reservation_types "occupied_by": "pos", // 從哪預約 pos/phone/app (現場/電話/APP) "occupied_id": "+886972957297", // 預約會員電話(務必要用+886開頭) "occupied_name": "tester", // 要是沒有撈到會員資料時給這個欄位會自動建立使用者 "cost": 1000, //.實收金額 這個金額會在結帳時帶入 "comment": "備註", // 備註 "items": [ { "field": "3樓羽球場A", // 場地id "date": "2024/02/07", // 預約日期 "time": "10:00", // 預約時段 "duration": 60 // 預約的長度(單位是分鐘 預設是60 半小時模式是30) }, { "type": "expand", // 目前需要批次預約才會要用這個 其他情況下照上面的 "field": "3樓羽球場A", "repeat_type": "weekly", // 與設定價格一樣的用法 不支援no_repeat! "repeat_range": 1, // 指定重複的間距 ex: repeat_type=weekly repeat_range=1就是每個禮拜,2就是每兩個禮拜 "date": "2024/01/06", // 開始時間 "until": "2024/02/28", // 結束日期 "time": "10:00", // 預約時段 "duration": 60 // 預約的長度(單位是分鐘 預設是60 半小時模式是30) } ] } ``` - Response - 200: ok - 400: 與已預約場地衝突 ### 搜尋預約記錄 ``` GET /reservation/search ``` - Query Parameters - phone: 會員電話(一定要是+886開頭的完整電話,可以透過上面的會員搜尋功能,拿到完整的電話號碼) - paid: true/false 要包含已付款/未付款 (預設是false) - Response ```jsonld= [ { "id": "1ed3fe67-18d5-4be3-b1e8-4774dea55047", "status": "pending", // 狀態 pending/paid/cancel 待繳費/已繳費/已取消 "type": "normal", // 對應上面的reservation_types "items": [ { "id": "ecff976d-2ae5-4ddc-8f53-541331900ed7", "date": "2024/02/07", // 預約日期 "time": "10:00", // 時段 "field_id": "3樓羽球場A", // 場地 "duration": 60, // 時長 "end_time": 1707274800, // 結束時間 "reservation_id": "1ed3fe67-18d5-4be3-b1e8-4774dea55047" } ], "deadline": 1707270600, // 最後繳費時間 "comment": null, "occupied_by": "pos", // 預約方式 pos/phone/app "occupied_id": "+886972957297", // 會員電話 "cost": 1000, // 應繳金額 "ext": null, "inserted_at": "2024-02-06T17:48:51", "updated_at": "2024-02-06T17:48:51" }, { "id": "78860f55-401f-4370-8215-25922ded2d2c", "status": "pending", "type": "normal", "items": [ { "id": "98131b49-196a-49a7-be6e-67d5bbee8a29", "date": "2024/02/07", "time": "12:00", "field_id": "3樓羽球場A", "duration": 60, "end_time": 1707282000, "reservation_id": "78860f55-401f-4370-8215-25922ded2d2c" } ], "deadline": 1707277779, "comment": null, "occupied_by": "pos", "occupied_id": "+886972957297", "cost": 1000, "ext": null, "inserted_at": "2024-02-07T03:39:39", "updated_at": "2024-02-07T03:39:39" } ] ``` ### 搜尋預約記錄(透過場地類別) ``` GET /field/category/[類別id]/reservation/search ``` - Response ```jsonld= [ { "id": "1ed3fe67-18d5-4be3-b1e8-4774dea55047", "status": "pending", // 狀態 pending/paid/cancel 待繳費/已繳費/已取消 "type": "normal", // 對應上面的reservation_types "items": [ { "id": "ecff976d-2ae5-4ddc-8f53-541331900ed7", "date": "2024/02/07", // 預約日期 "time": "10:00", // 時段 "field_id": "3樓羽球場A", // 場地 "duration": 60, // 時長 "end_time": 1707274800, // 結束時間 "reservation_id": "1ed3fe67-18d5-4be3-b1e8-4774dea55047" } ], "deadline": 1707270600, // 最後繳費時間 "comment": null, "occupied_by": "pos", // 預約方式 pos/phone/app "occupied_id": "+886972957297", // 會員電話 "cost": 1000, // 應繳金額 "ext": null, "inserted_at": "2024-02-06T17:48:51", "updated_at": "2024-02-06T17:48:51" }, { "id": "78860f55-401f-4370-8215-25922ded2d2c", "status": "pending", "type": "normal", "items": [ { "id": "98131b49-196a-49a7-be6e-67d5bbee8a29", "date": "2024/02/07", "time": "12:00", "field_id": "3樓羽球場A", "duration": 60, "end_time": 1707282000, "reservation_id": "78860f55-401f-4370-8215-25922ded2d2c" } ], "deadline": 1707277779, "comment": null, "occupied_by": "pos", "occupied_id": "+886972957297", "cost": 1000, "ext": null, "inserted_at": "2024-02-07T03:39:39", "updated_at": "2024-02-07T03:39:39" } ] ``` ### 重新預約(限定已取消且時段都還沒過期的) ``` PUT /reservation/[預約id]/redo ``` - Response ``` ok ``` ### 取消預約(標記取消,不會刪除紀錄) ``` PUT /reservation/[預約id]/cancel ``` - Body ```jsonld= { "reason": "沒有理由" } ``` - Response ``` ok ``` ### 刪除預約紀錄(慎用) ``` DELETE /reservation/[預約id] ``` - Response ``` ok ``` ### 查詢場地預約紀錄 ``` GET /field/[場地id]/reservations ``` - Query Parameters ==用了start_date/end_date就不用date格式都是yyyy/MM/dd== - date: 指定日期 - start_date: 開始日期 ==需與end_date一起否則忽略直接使用當天== - end_date: 結束日期 - Response ```jsonld= { "count": 11, // 共有幾筆 "rows": [ { "created_at": "2024/11/09 05:50:51", // 使用者預約日期及時間 "order_id": "", // 訂單編號 "invoice_number": "", // 發票號碼 "status": "未付款", // 交易狀態 "cancel_reason": "", // 取消原因 "cost": 300, // 金額 "range": "2024/11/11 06:00~06:59", // 場地被預約日期及時間 "created_from": "pos", // 結帳櫃檯 "created_by": "+886910814601", // 結帳人員 "cancel_from": "", // 取消櫃檯 "cancel_by": "", // 取消人員 "canceled_at": "" // 取消時間 }, ... ] } ``` --- ## 卡片相關功能 ### 建立敬老卡(沿用舊系統的建立員工卡加上參數) ``` POST /card2/[掃RFID拿到的卡號] ``` - Body ```jsonld= { "type": "elder", "name": "ooxx", // 姓名 "profile": { // 裡面可以放資料如:警急聯絡人,電話等...key可以自己取 ... } } ``` - Response ``` ok ``` ### 拿敬老卡列表(沿用舊系統的員工卡列表加上參數) ``` GET /card2 ``` - Query Parameters -- type: elder/employee/monthly/app_monthly (elder: 敬老卡, employee: 員工卡, monthly: 月卡, app_monthly: APP月卡) - Response ```jsonld= { "count": 1, "rows": [ { "id": "[卡號]", "sn": "[卡號]", "type": "elder", "name": "ooxx", "profile": { ... } }, ... ], "monthly_valids": { // 當type == "monthly" 的時候會出現,代表可以用的月卡數量 "fitness": 33, "pool": 94 } } ``` ### 修改敬老卡(沿用舊系統的建立員工卡加上參數) ``` PUT /card2/[掃RFID拿到的卡號] ``` - Body ```jsonld= { "type": "elder", "name": "ooxx", // 姓名 "profile": { // 裡面可以放資料如:警急聯絡人,電話等...key可以自己取 ... } } ``` - Response ``` ok ``` ### 建立月卡的操作 ``` POST /monthly_operations ``` - Body ```jsonld= { "specific": "all", // default: "all" 指定的場地:all 全部 pool 游泳池 fitness 健身房 "date": "2025-03-20", // 指定什麼時候到期後的月卡 "extend_days": 1, // 延長幾天 "comment": "因為xxx所以xxx" // 備註 } ``` - Response ```jsonld= { "id": "bd28d94b-3bcd-4d12-a7fc-cb9e6a93a5a6", "specific": "all", // 指定的場地 "status": "初始化", // 狀態 "date": "2025/03/20", "comment": "因為xxx所以xxx", "extend_days": 1, "created_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4", "executed_at": "", "inserted_at": "2025/03/14 15:32:32", "updated_at": "2025/03/14 15:32:32" } ``` ### 執行月卡的操作(已刪除) ``` PUT /monthly_operations/[monthly operation id] ``` - Response ```jsonld= { "id": "bd28d94b-3bcd-4d12-a7fc-cb9e6a93a5a6", "specific": "all", "status": "已完成", "date": "2025/03/20", "comment": "因為xxx所以xxx", "extend_days": 1, "created_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4", "executed_at": "2025/03/14 15:35:07", // 執行時間 "inserted_at": "2025/03/14 15:32:32", "updated_at": "2025/03/14 15:35:07" } ``` ### 刪除月卡的操作 ``` DELETE /monthly_operations/[monthly operation id] ``` - Response ``` ok ``` ### 取得月卡的操作列表 ``` GET /monthly_operations ``` - Response ```jsonld= { "count": 1, "rows": [ { "id": "bd28d94b-3bcd-4d12-a7fc-cb9e6a93a5a6", "specific": "all", "status": "已完成", "date": "2025/03/20", "comment": "因為xxx所以xxx", "inserted_at": "2025/03/14 15:32:32", "updated_at": "2025/03/14 15:35:07", "created_by": "722543ea-bdcc-48c4-aa9e-baf4e0f2fac4", "executed_at": "2025/03/14 15:35:07", "extend_days": 1 } ] } ``` ### 建立報表類別 ``` POST /report_categories ``` - Body ```jsonld= { "code": "TestA", // code "name": "NameA", // 名稱 "comment": "NameA", // 備註 "weight": 3, // 權重與排序有關(越大越前面) "products": [ 1 ], // product id 的 array "children": [], "parent_id": "1" // 上一層類別的id(不給就是第一層) } ``` - Response ```jsonld= { "id": "ooxxxxxx", "code": "TestA", "name": "NameA", "comment": "NameA", "weight": 3, "products": [ 1 ], "children": [], "parent_id": "ooxxxxx" } ``` ### 修改報表類別 ``` PUT /report_categories/[report category id] ``` - Body ```jsonld= { "code": "testB", "name": "NameA_Update", "comment": "NameA_Update", "weight": 0, "products": [ 2 ], "children": [], "parent_id": "2" } ``` - Response ``` ok ``` ### 刪除報表類別 ``` DELETE /report_categories/[report category id] ``` - Response ``` ok ``` ### 取得報表類別列表 ``` GET /report_categories ``` - Response ```jsonld= { "count": 2, "rows": [ { "id": "ooxx", "code": "TestA", "name": "NameA", "comment": "NameA", "products": [ { "id": 1, "name": "體適能-全票", "price": 50 } ], "children": [], "parent_id": null, "weight": 3 }, { "id": "xxoo", "code": "TestB", "name": "NameB", "comment": "NameB", "products": [ { "id": 1, "name": "體適能-全票", "price": 50 } ], "children": [], "parent_id": "ooxx", "weight": 0 } ] } ``` --- --- ## 固定電話驗證碼 ### 建立固定驗證碼 ``` POST /phonecodes ``` - Body ```jsonld= { "phone": "+886912345678", "code": "123456" // 固定六位數字 } ``` - Response ```jsonld= { "phone": "+886912345678", "code": "123456" } ``` ### 拿驗證碼列表 ``` GET /phonecodes ``` - Response ```jsonld= { "count": 1, "rows": [ { "phone": "+886912345678", "code": "123456" }, ... ] } ``` ### 刪除驗證碼 ``` DELETE /phonecodes/[電話號碼(+886開頭)] ``` - Response ``` ok ``` ### 修改固定驗證碼 ``` PUT /phonecodes/[電話號碼(+886開頭)] ``` - Body ```jsonld= { "code": "123456" // 固定六位數字 } ``` - Response ``` ok ``` --- --- ## 課程 ### 課程欄位解說 * id: string 課程的id(客戶自己編) * name: string 課程名稱 * type: string 課程類別的id * teacher: string 老師的id * classroom_type: string 教室類型("classroom", "field") * classroom: string 當classroom_type=="classroom"時用教室id,當classroom_type=="field"時用場地id * description: string 課程說明 * picture1: string url 照片1 * picture2: string url 照片2 * picture3: string url 照片3 * hide: true/false 封存? * enable: true/false 啟動? * app: true/false 開放app報名? * begin: string yyyy/MM/dd 開始報名日期 * app_begin: string yyyy/MM/dd APP開始報名日期 * deadline: string yyyy/MM/dd 截止報名日期 * app_deadline: string yyyy/MM/dd APP截止報名日期 * open_threshold: integer 開課人數 * full: integer 滿班人數 * app_limit: integer 開放APP報名人數 * checkin_before: integer 開課前幾分鐘可報到 * checkin_after: integer 開課後幾分鐘可報到 * unit_price: integer 單堂價格 * total_price: integer 課程總價 * taste_price: integer 單次體驗價 * status_name: string 用在ui上的課程狀態 * enable_returning_student_discount: true/false 啟用舊生優惠? * previous_course: string 關聯課程的id * returning_student_threshold: integer 關聯課程需報名付款的堂數 * returning_student_after_discount_unit_price: integer 折扣後單堂價格 * returning_student_after_discount_total_price: integer 折扣後總價 * schedules: array 單堂資料(欄位下列) * open_months: 開課年月 ### 課程單堂欄位解說 * id: string 單堂的id(系統自動產生) * date: string 日期yyyy/MM/dd * start: string 時間HH:mm * duration: integer 時長(分鐘) * comment: string 該堂說明 ### 新增課程 ``` POST /courses ``` - Body ```jsonld= { ..., //使用課程欄位解說所有欄位 "schedules": [ ..., // 使用課程單堂欄位解說所有欄位 ] } ``` - Response ```jsonld= { ... //使用上面所有欄位 } ``` ### 取得課程列表 ``` GET /courses ``` - Response ```jsonld= { "count": 1, "rows": [ ... //使用上面課程所有欄位 ] } ``` ### 選課 ``` POST /courses/[課程id]/takes ``` - Body ```jsonld= { "user": "[user的電話號碼+886開頭]", "student": "[student id]", // student/user必須要選一個填 "schedules": [...] // 放schedule的id } ``` - Response ```json ok ``` ### 取得選課資料(for繳費or點名) ``` GET /courses/[課程id]/takes ``` - Response ```jsonld= { "count": 1, "rows": [ { "id":"49055e94-6291-4e85-b39a-96158bddfb00", // 報名id "course":"C001", // 課程id "paid": false, // 是否繳費 "invoice": "AA00000001", // 發票號碼, 有繳費才會有 "attend":false, // 已報到 "isAbsent":false, "isLeave":false, "isShift":false, "isTakeOff":false, "schedule":"fffd2f91-b492-4d74-8499-02c6ec7f2bfa", // 課程單堂id "student":"b9907b0a-7b54-48b6-933a-bc63cbe84915", // 報名學生id "user":null, // 報名使用者電話 "name": "ooxx", //報名者名稱 "comment":null // 備註 }, ... ] } ``` ### 取消選課(尚未繳費時用) ``` DELETE /courses/takes/[選課id] ``` - Response ```jsonld ok ``` ### 課程報名結帳(其他參數與一般結帳及場地預約結帳一樣只列出不同之處) ``` POST /sales ``` - Body ```jsonld= { "items": [ { "type": "course", "price": 金額(會照這個金額開發票), "items": [...] // 報名id array } ] } ``` ### 刪除課程(還未有人報名時) ``` DELETE /courses/[課程id] ``` - Response ```jsonld ok ``` ### 修改課程(還未有人報名時) ``` PUT /courses/[課程id] ``` - Body ```jsonld= { ..., //使用課程欄位解說所有欄位,有帶的就會修改 "schedules": [ // 如有修改單堂資料請將所有課堂的資料都帶進來,如沒有修改請勿使用這個key(也不要用空array) { ..., // 使用課程單堂欄位解說所有欄位(id除外) } ] } ``` - Response ```jsonld ok ``` ### 刪除單堂(還未有人報名時) ``` DELETE /courses/schedules/[單堂id] ``` - Response ```jsonld ok ``` ### 取得選課資料(for繳費) ``` GET /courses/takes ``` - Query Parameters ==下面兩個參數選一個就好== - phone: 會員電話(+886開頭) - student: student id - Response ```jsonld= { "count": 3, "rows": [ { "id": "49055e94-6291-4e85-b39a-96158bddfb00", // 報名id用來帶到繳費api "name": "student", "comment": null, "schedule": { // 報名的課堂資料 "id": "fffd2f91-b492-4d74-8499-02c6ec7f2bfa", "start": "10:00", "date": "2024/06/04", "until": "11:00", "comment": "1234", "course": "C001", "isTakeOff": false, "isShift": false, "duration": 60, "weekday": "二" }, "course": { // 報名的課程資料 "picture3": "https://cosmic-jaybird-regularly.ngrok-free.app/files/image/712d17dc6d95935019f226f54e676ce177551b190ce9ff75d5a06e28dbe970cb?t=19026", "app_begin": "2024/06/04", "checkin_after": 15, "open_threshold": 10, "picture2": "https://cosmic-jaybird-regularly.ngrok-free.app/files/image/712d17dc6d95935019f226f54e676ce177551b190ce9ff75d5a06e28dbe970cb?t=13680", "type": "37776f6f-4729-41fb-b606-a6fdebd2b091", "classroom_type": "classroom", "app_intro": { "schedule_count": 3, "schedule_range": "2024/06/04 ~ 2024/06/08", "take_range": "2024/06/04 ~ 2024/07/04", "takes_count": 2, "teacher": "teacher" }, "unit_price": 100, "deadline": "2024/07/04", "begin": "2024/06/04", "pictures": [ "https://cosmic-jaybird-regularly.ngrok-free.app/files/image/712d17dc6d95935019f226f54e676ce177551b190ce9ff75d5a06e28dbe970cb?t=78238", "https://cosmic-jaybird-regularly.ngrok-free.app/files/image/712d17dc6d95935019f226f54e676ce177551b190ce9ff75d5a06e28dbe970cb?t=13680", "https://cosmic-jaybird-regularly.ngrok-free.app/files/image/712d17dc6d95935019f226f54e676ce177551b190ce9ff75d5a06e28dbe970cb?t=19026" ], "name": "測試課程", "app_limit": 8, "app_enable": true, "classroom": "a9f2f48a-f825-4787-a78a-6c70e0112952", "taste_price": 200, "full": 10, "type_name": "class_c", "courseType": "37776f6f-4729-41fb-b606-a6fdebd2b091", "enable": true, "classroom_name": "舞蹈教室", "status_name": "未知", "total_price": 5000, "description": "測試課程AAABBBCCCDDD", "app_status": "報名進行中", "id": "C001", "app_deadline": "2024/07/04", "schedules": [ { "id": "fffd2f91-b492-4d74-8499-02c6ec7f2bfa", "start": "10:00", "date": "2024/06/04", "until": "11:00", "comment": "1234", "course": "C001", "isTakeOff": false, "isShift": false, "duration": 60, "weekday": "二" }, { "id": "7283fa51-7910-47c9-85e7-3c73547c5218", "start": "10:00", "date": "2024/06/06", "until": "11:00", "comment": null, "course": "C001", "isTakeOff": false, "isShift": false, "duration": 60, "weekday": "四" }, { "id": "5dc3b8c8-cd13-4bf3-892d-e7091033bf53", "start": "10:00", "date": "2024/06/08", "until": "11:00", "comment": null, "course": "C001", "isTakeOff": false, "isShift": false, "duration": 60, "weekday": "六" } ], "hide": false, "app": true, "checkin_before": 15, "picture1": "https://cosmic-jaybird-regularly.ngrok-free.app/files/image/712d17dc6d95935019f226f54e676ce177551b190ce9ff75d5a06e28dbe970cb?t=78238", "teacher": "a82fbfed-7f8f-44c9-84d4-9e9965d6058a" }, "attend": false, "isTakeOff": false, "isShift": false, "isLeave": false, "isAbsent": false, "paid": false // 是否已繳費 }, ... ] } ``` ### 透過QRCode課程報到 ``` PUT /courses/take ``` - Body ```jsonld= { "code": "xxoo" // QRCode的內容 } ``` - Response ```jsonld= { "status": "報到成功", // 報到結果 "time": "2024/07/18 17:03:28", // 報到的時間 "schedule": "2024/07/18 17:00", // 報到的課堂時間 "course": "測試課程" // 課程名稱 } ``` ### 確認有無符合舊生優惠 ``` PUT /courses/[course_id]/discount ``` - Body ```jsonld= { "ref_id": "xxoo" // 學生id or 會員id } ``` - Response ```jsonld= { "match_returning_student_discount": true/false // 有/無符合 } ``` ---