[side project] 今天吃什麼?

更新於 發佈於 閱讀時間約 3 分鐘

需求

在現代快節奏的生活中,「今天吃什麼」常常成為一個讓我頭疼的問題。每天面對眾多餐廳選擇,很容易陷入決策疲勞。為了解決這個日常煩惱,我設計了一個簡單的餐廳推薦系統,參考交友軟體的左右滑動機制,讓使用者能夠輕鬆選擇餐廳。

系統的核心需求如下:

  • 模仿交友軟體的交互方式,讓使用者能左滑(不喜歡)或右滑(喜歡)餐廳
  • 記錄所有選擇,形成個人化的用餐歷史記錄
  • 使用 Google Sheet 作為後端資料庫儲存餐廳資訊和歷史記錄
  • 使用 JavaScript 實現前端,並整合 Google Apps Script 作為後端
  • 能夠直接從介面新增餐廳

發想過程

在設計初期,我考慮了幾個關鍵功能:

  1. 隨機推薦功能:當使用者完全沒想法時,系統能隨機推薦餐廳。
  2. 個人化推薦:根據使用者過去的選擇和喜好來優化推薦。
  3. 記錄功能:追蹤使用者的用餐歷史,分析喜好模式。

經過重重思考,我決定將交友軟體的左右滑動機制應用到餐廳選擇中,這種直覺的交互方式不僅易於使用,而且能夠快速收集使用者的喜好資料。

我選擇純靜態的 HTML + CSS + JavaScript 開發前端,因為這樣能輕鬆部署在任何網頁伺服器上,而使用 Google Apps Script 和 Google Sheet 作為後端,則能免去建立和維護資料庫伺服器的麻煩。

系統設計結構


前端架構

  • HTML 負責基本頁面結構,包含三個主要畫面:推薦卡片、歷史記錄和新增餐廳表單
  • CSS 負責所有樣式和動畫,包括卡片滑動效果
  • JavaScript 實現所有邏輯功能和與後端的交互

後端架構

  • Google Sheet 作為資料庫,包含兩個表格:
    • Restaurants 表格:儲存餐廳基本資訊
    • History 表格:記錄使用者的選擇
  • Google Apps Script 作為後端 API,提供幾個主要功能:
    • 獲取所有餐廳資料
    • 獲取歷史記錄
    • 新增餐廳
    • 儲存使用者選擇

資料流程

  1. 前端頁面載入時,通過 API 請求獲取餐廳資料
  2. 使用者左右滑動做出選擇,選擇結果發送到後端存儲
  3. 歷史記錄頁面展示所有過去的選擇
  4. 使用者可以從介面新增餐廳,資料傳送到後端存儲在 Sheet 中

實作過程

前端實作

  1. 主畫面設計:創建一個可左右滑動的卡片,顯示餐廳名稱、類型和地址等資訊
  2. 滑動機制:實現觸控和滑鼠的滑動事件處理,添加視覺反饋
  3. 歷史記錄頁面:設計一個直觀的列表,展示過去的選擇
  4. 餐廳新增表單:使用下拉選單選擇餐廳類型,確保資料一致性

後端實作

  1. Google Sheet 設計:設計兩個表格的結構,包括所有必要欄位
  2. Google Apps Script 開發
    • 實現各個 API 端點
    • 處理各種請求類型(GET、POST)
    • 確保資料安全性和完整性

整合連接

使用 JavaScript 的 fetch API 與後端連接,處理資料的傳送和接收。由於 CORS 限制,我最終採用 JSONP 和表單提交方式繞過這些限制。

實作中遇到的問題及解決方案

1. CORS 跨域問題

問題描述:當前端嘗試向 Google Apps Script 發送請求時,遇到了跨來源資源共享 (CORS) 的限制,導致無法正常獲取資料。

錯誤信息

"API 錯誤詳情:" "無法讀取響應內容,請檢查 CORS 設置"

解決方案

  • 對於 GET 請求,採用 JSONP (JSON with Padding) 技術:
    • 創建一個動態的 <script> 標籤
    • 通過 URL 參數傳遞回調函數名稱
    • Google Apps Script 返回執行這個回調函數的 JavaScript
  • 對於 POST 請求,採用表單提交方式:
    • 動態創建並提交表單到隱藏的 iframe
    • 通過表單欄位傳遞數據
    • 這種方式不受跨域限制

2. Google Apps Script 資料存取問題

問題描述:嘗試使用 SpreadsheetApp.openById() 時遇到權限問題。

錯誤信息

"歷史記錄加載成功:" 
{
"success": false,
"message": "獲取歷史記錄失敗: Exception: Unexpected error while getting the method or property openById on object SpreadsheetApp."
}

解決方案

  • 確保 Google Apps Script 使用正確的部署設置:
    • 部署時選擇「以您的身分執行」而非「以存取網頁的使用者身分執行」
    • 確保試算表 ID 正確無誤
    • 重新授權應用訪問 Google Sheet

最終成果

  1. 直覺的使用者介面:左右滑動選擇餐廳,模仿交友軟體的體驗
  2. 完整的歷史記錄:記錄所有選擇,方便回顧
  3. 簡單的餐廳管理:直接從介面添加新餐廳
  4. 無伺服器架構:使用 Google Apps Script 和 Google Sheet 作為後端,無需管理伺服器
  5. 響應式設計:適配不同設備,從手機到桌面都有良好體驗

小小心得

在實作過程中,遇到了各種技術挑戰,尤其是跨域的問題,這促使我探索和學習了更多前端技術解決方案。最終我採用了 JSONP 和表單提交的方式,成功繞過了 CORS 限制。

這個專案的一個關鍵優勢是使用了 Google 的雲端服務作為後端,大大簡化了部署和管理。對於個人專案或小型應用來說,這種方式非常適合,既節省成本又容易維護。(這次幾乎都是用AI快速產生程式來實作的POC結果,懶得弄部署雲端資料庫所以才用GAS XD

未來,可以考慮添加更多功能,如基於歷史記錄的智能推薦算法、社群共享功能等,進一步提升用戶體驗。甚至可能會轉會成前後端系統(如果真的很好用的話XD)

留言
avatar-img
留言分享你的想法!
avatar-img
欸! 是彼得的資料庫
68會員
50內容數
歡迎來到彼得的沙龍,在這裡,我將與你分享書籍精華的智慧、人際溝通的技巧、理財增值的秘訣,以及情緒管理的策略。不僅幫助你打好財務基礎,還能引領你在人生的每個環節中游刃有餘。如果你渴望成長,並追求更充實的生活,這裡就是你值得關注的空間。立即加入,與我一起探索成長的無限可能!
2025/04/01
什麼是 MCP?簡單來說,MCP (Model Context Protocol) 是一種讓 AI 變得更聰明的協議,它讓 AI 可以直接使用各種外部工具,例如你的檔案系統、Notion 等等,從而大幅提升 AI 的功能和效率。本文深入淺出地解釋 MCP 的三大組成架構,並透過實際案例和常見問題。
Thumbnail
2025/04/01
什麼是 MCP?簡單來說,MCP (Model Context Protocol) 是一種讓 AI 變得更聰明的協議,它讓 AI 可以直接使用各種外部工具,例如你的檔案系統、Notion 等等,從而大幅提升 AI 的功能和效率。本文深入淺出地解釋 MCP 的三大組成架構,並透過實際案例和常見問題。
Thumbnail
2025/03/20
在 Laravel 開發 API 時,直接在 Controller 內進行資料加工可能會讓程式碼變得雜亂且難以維護。因此,Laravel 提供 Resource (資源轉換器) 來解決這個問題,讓我們可以統一管理 API 的輸出格式,將模型model或模型集合collection轉換為適合 API
Thumbnail
2025/03/20
在 Laravel 開發 API 時,直接在 Controller 內進行資料加工可能會讓程式碼變得雜亂且難以維護。因此,Laravel 提供 Resource (資源轉換器) 來解決這個問題,讓我們可以統一管理 API 的輸出格式,將模型model或模型集合collection轉換為適合 API
Thumbnail
2025/01/14
撰寫程式碼時,測試扮演著至關重要的角色,能有效確保程式碼品質與穩定性。本文深入探討單元測試 (Unit Test) 與功能測試 (Feature Test) 的差異、應用場景及實務操作,並以 3A 原則 與 PHPUnit 指令範例,幫助開發者提升程式碼測試效率及可維護性。
Thumbnail
2025/01/14
撰寫程式碼時,測試扮演著至關重要的角色,能有效確保程式碼品質與穩定性。本文深入探討單元測試 (Unit Test) 與功能測試 (Feature Test) 的差異、應用場景及實務操作,並以 3A 原則 與 PHPUnit 指令範例,幫助開發者提升程式碼測試效率及可維護性。
Thumbnail
看更多
你可能也想看
Thumbnail
常常被朋友問「哪裡買的?」嗎?透過蝦皮分潤計畫,把日常購物的分享多加一個步驟,就能轉換成現金回饋。門檻低、申請簡單,特別適合學生與上班族,讓零碎時間也能創造小確幸。
Thumbnail
常常被朋友問「哪裡買的?」嗎?透過蝦皮分潤計畫,把日常購物的分享多加一個步驟,就能轉換成現金回饋。門檻低、申請簡單,特別適合學生與上班族,讓零碎時間也能創造小確幸。
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
朋友忽然說好久不見想聚餐,我不假思索答應了,順道問了句要吃什麼我來找。 「我想吃點不貴的,省錢,但不要太LOW的。」 找了一些網美餐廳被打槍,忽然她問了另位朋友後,「他想吃饗饗耶,我看了一下也不錯,可以嗎?」 「......那你們想要什麼時候?」 「下禮拜?」 .......去你的下禮拜,
Thumbnail
朋友忽然說好久不見想聚餐,我不假思索答應了,順道問了句要吃什麼我來找。 「我想吃點不貴的,省錢,但不要太LOW的。」 找了一些網美餐廳被打槍,忽然她問了另位朋友後,「他想吃饗饗耶,我看了一下也不錯,可以嗎?」 「......那你們想要什麼時候?」 「下禮拜?」 .......去你的下禮拜,
Thumbnail
我要的畫面:晚餐不需要排隊點餐。 現場無人排隊,直接點餐,並且備餐時,還多了一個人協助完成餐食,整個流程順暢且快速,離開時,因為鄰車距離相近,對方還特別移車,讓我方便離開。 回家吃晚餐,食物比平時美味10倍,免不了又感謝一番,活著真好。 可操作重點:保持思想乾淨 如果腦中有懷疑,或是限制性的
Thumbnail
我要的畫面:晚餐不需要排隊點餐。 現場無人排隊,直接點餐,並且備餐時,還多了一個人協助完成餐食,整個流程順暢且快速,離開時,因為鄰車距離相近,對方還特別移車,讓我方便離開。 回家吃晚餐,食物比平時美味10倍,免不了又感謝一番,活著真好。 可操作重點:保持思想乾淨 如果腦中有懷疑,或是限制性的
Thumbnail
想吃點心但是沒時間吃點心QQ
Thumbnail
想吃點心但是沒時間吃點心QQ
Thumbnail
今天帶大家去餐廳的廚房看看,平時可是不招呼外人哦,所以要把握機會了!
Thumbnail
今天帶大家去餐廳的廚房看看,平時可是不招呼外人哦,所以要把握機會了!
Thumbnail
之前跟格友-奇人奕事3.0-在討論區吹水,如果我學他/她講講寫寫一些飲飲食食,我就是在這裏不務正業,他/她回覆我,可作多方嘗試,那我就在今天開始不定時地「不務正業」吧~
Thumbnail
之前跟格友-奇人奕事3.0-在討論區吹水,如果我學他/她講講寫寫一些飲飲食食,我就是在這裏不務正業,他/她回覆我,可作多方嘗試,那我就在今天開始不定時地「不務正業」吧~
Thumbnail
   食慾是這樣,當沒有看到什麼美食介紹時,就有可能按照自己的步調來進食。一切按照計劃來,可說是沒有什麼期待感。而這並不代表,不能去安排大餐的享用,或者是依照客戶的需求,為其尋找適合的龍蝦餐廳或是和牛餐廳。看著菜色,想著客戶可能會喜歡怎樣的,這還是做得到的。而購物慾是這樣,沒有看到什麼優惠訊息
Thumbnail
   食慾是這樣,當沒有看到什麼美食介紹時,就有可能按照自己的步調來進食。一切按照計劃來,可說是沒有什麼期待感。而這並不代表,不能去安排大餐的享用,或者是依照客戶的需求,為其尋找適合的龍蝦餐廳或是和牛餐廳。看著菜色,想著客戶可能會喜歡怎樣的,這還是做得到的。而購物慾是這樣,沒有看到什麼優惠訊息
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News