[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
留言分享你的想法!
Peter Lu-avatar-img
2
我好需要這個!每天到吃飯時間都煩惱~
Peter Lu-avatar-img
2
Peter Lu-avatar-img
發文者
7 天前
1
月影紗💫 真的!每次中午(準備吃飯)走到路口時,都會想很久要往哪裡走XD
1
Joker-avatar-img
5 天前
Peter Lu-avatar-img
1
這還有紀錄遇到的問題耶~好棒 XD
Peter Lu-avatar-img
1
Peter Lu-avatar-img
發文者
5 天前
Joker 謝謝XD 讓想嘗試的人不要踩雷!
一語-avatar-img
5 天前
Peter Lu-avatar-img
1
ㄒㄩㄢ
Peter Lu-avatar-img
1
Peter Lu-avatar-img
發文者
5 天前
一語 J個是XD?
氣泡水-avatar-img
7 天前
Peter Lu-avatar-img
1
開發這個主題的App 感覺很實用。不太清楚「用身分執行」和「以存取網頁使用者身分執行」的差異性在哪裡?是否用個人的身份執行,需要提供更多個資?
Peter Lu-avatar-img
1
Peter Lu-avatar-img
發文者
7 天前
1
氣泡水 謝謝喜歡~ 以您的身分執行: - 任何人訪問這個網頁應用程式時,都會以您的身分進行操作 - 不需要訪問者登入 Google 帳戶 以存取網頁的使用者身分執行: - 訪問者必須登入自己的 Google 帳戶才能使用該應用 - 如果訪問者沒有特定 Google Sheet 的存取權限,腳本也無法為他們操作這些資源 而會選擇用「以您的身分執行」更適合是因為 1. 系統使用的是單一共享的 Google Sheet 資料庫 2. 使用者不需要登入 Google 帳戶就能使用應用程式 3. 不需要收集使用者的個人資訊
1
AI時代下,生物學家和程式設計師為何不會被取代?提及了這篇文章,趕快過去看看吧!
Peter Lu-avatar-img
1
Peter Lu-avatar-img
發文者
7 天前
1
白勻_道場主 謝謝提及,你的主題是很有趣的探討~
1
在 Laravel 開發 API 時,直接在 Controller 內進行資料加工可能會讓程式碼變得雜亂且難以維護。因此,Laravel 提供 Resource (資源轉換器) 來解決這個問題,讓我們可以統一管理 API 的輸出格式,將模型model或模型集合collection轉換為適合 API
撰寫程式碼時,測試扮演著至關重要的角色,能有效確保程式碼品質與穩定性。本文深入探討單元測試 (Unit Test) 與功能測試 (Feature Test) 的差異、應用場景及實務操作,並以 3A 原則 與 PHPUnit 指令範例,幫助開發者提升程式碼測試效率及可維護性。
本文介紹了 Docker 的基本概念,包括 Docker Image、Docker Container、Dockerfile、Docker Compose 及其應用情境,如開發與測試環境、微服務架構和持續整合/持續部署。瞭解這些內容能幫助開發人員更有效地利用 Docker 進行應用程式的部署和管理。
本文探討如何利用政府提供的YouBike開放數據進行數據分析,以揭示共享單車系統的使用趨勢。作者使用Google Apps Script分析不同時間點的YouBike使用率,並通過線性回歸預測供需平衡,以及針對特定站點的使用模式進行深入挖掘。最後總結了公館不同出口的使用情況,提供了最佳的租借選擇。
在進行SQL查詢邏輯更改時,需要適當地使用SubQuery和join來達到新的排序需求。本文將介紹原本的撈取邏輯、需求以及如何使用SubQuery來解決新的排序需求。
在 Laravel 開發 API 時,直接在 Controller 內進行資料加工可能會讓程式碼變得雜亂且難以維護。因此,Laravel 提供 Resource (資源轉換器) 來解決這個問題,讓我們可以統一管理 API 的輸出格式,將模型model或模型集合collection轉換為適合 API
撰寫程式碼時,測試扮演著至關重要的角色,能有效確保程式碼品質與穩定性。本文深入探討單元測試 (Unit Test) 與功能測試 (Feature Test) 的差異、應用場景及實務操作,並以 3A 原則 與 PHPUnit 指令範例,幫助開發者提升程式碼測試效率及可維護性。
本文介紹了 Docker 的基本概念,包括 Docker Image、Docker Container、Dockerfile、Docker Compose 及其應用情境,如開發與測試環境、微服務架構和持續整合/持續部署。瞭解這些內容能幫助開發人員更有效地利用 Docker 進行應用程式的部署和管理。
本文探討如何利用政府提供的YouBike開放數據進行數據分析,以揭示共享單車系統的使用趨勢。作者使用Google Apps Script分析不同時間點的YouBike使用率,並通過線性回歸預測供需平衡,以及針對特定站點的使用模式進行深入挖掘。最後總結了公館不同出口的使用情況,提供了最佳的租借選擇。
在進行SQL查詢邏輯更改時,需要適當地使用SubQuery和join來達到新的排序需求。本文將介紹原本的撈取邏輯、需求以及如何使用SubQuery來解決新的排序需求。
本篇參與的主題活動
你有沒有發現,人生中總有幾種人讓你忍不住多看幾眼? 不是因為他們長得特別帥、家裡特別有錢,而是他們總能在混亂中找到方向、別人都沒看到的地方發現機會 甚至,你還來不及反應,他們已經在前面三步了。 這種人,你可能以為是「天才」。 但其實,他們只是「開啟了某幾種特別的能力」。 而這些能力,
從根本上說,我們之所以是我們,是因為在某個無法控制的瞬間,另一個真實存在的人回應、拒絕或重新定義了我們。AI 只會永恆地迎合我們的期望,卻無法真正突破我們的自我界限。 如果我們完全隔絕於傷害與干擾之外,我們是否同時也喪失了成為真正「人」的可能性?
Elon Musk於Tesla全體員工大會上,分享了Tesla的未來藍圖,涵蓋電動車、自動駕駛、可持續能源、人形機器人Optimus等,最終願景為實現物質無虞的未來。演講重點提及Tesla的生產成就、工廠擴展、電池技術、自動駕駛技術及AI發展,以及Optimus人形機器人的生產計劃和市場潛力。
我寫小說,也畫畫,剛好方格子正在進行討論 AI 的話題,就來聊一下我自己怎麼運用 AI 的吧。 首先,我並不喜歡直接用 AI 生成的東西取代人工創作,如果可以的話,我會儘可能自己手工創作,因為我使用 AI 的技能並不好,只會跟 ChatGPT 聊天而已。我的經驗是,他創作出來的內容,其實不容易符合
本文探討AI筆記工具的優缺點、選擇建議及未來趨勢,比較NotebookLM、OneNote+Copilot、Notion AI、Obsidian+GPT插件和Palantir Foundry等工具,並強調安全注意事項及個人需求評估的重要性。
你有沒有發現,人生中總有幾種人讓你忍不住多看幾眼? 不是因為他們長得特別帥、家裡特別有錢,而是他們總能在混亂中找到方向、別人都沒看到的地方發現機會 甚至,你還來不及反應,他們已經在前面三步了。 這種人,你可能以為是「天才」。 但其實,他們只是「開啟了某幾種特別的能力」。 而這些能力,
從根本上說,我們之所以是我們,是因為在某個無法控制的瞬間,另一個真實存在的人回應、拒絕或重新定義了我們。AI 只會永恆地迎合我們的期望,卻無法真正突破我們的自我界限。 如果我們完全隔絕於傷害與干擾之外,我們是否同時也喪失了成為真正「人」的可能性?
Elon Musk於Tesla全體員工大會上,分享了Tesla的未來藍圖,涵蓋電動車、自動駕駛、可持續能源、人形機器人Optimus等,最終願景為實現物質無虞的未來。演講重點提及Tesla的生產成就、工廠擴展、電池技術、自動駕駛技術及AI發展,以及Optimus人形機器人的生產計劃和市場潛力。
我寫小說,也畫畫,剛好方格子正在進行討論 AI 的話題,就來聊一下我自己怎麼運用 AI 的吧。 首先,我並不喜歡直接用 AI 生成的東西取代人工創作,如果可以的話,我會儘可能自己手工創作,因為我使用 AI 的技能並不好,只會跟 ChatGPT 聊天而已。我的經驗是,他創作出來的內容,其實不容易符合
本文探討AI筆記工具的優缺點、選擇建議及未來趨勢,比較NotebookLM、OneNote+Copilot、Notion AI、Obsidian+GPT插件和Palantir Foundry等工具,並強調安全注意事項及個人需求評估的重要性。
你可能也想看
Google News 追蹤
Thumbnail
全新 vocus 挑戰活動「方格人氣王」來啦~四大挑戰任你選,留言 / 愛心 / 瀏覽數大 PK,還有新手專屬挑戰!無論你是 vocus 上活躍創作者或剛加入的新手,都有機會被更多人看見,獲得站上版位曝光&豐富獎勵!🏆
Thumbnail
朋友忽然說好久不見想聚餐,我不假思索答應了,順道問了句要吃什麼我來找。 「我想吃點不貴的,省錢,但不要太LOW的。」 找了一些網美餐廳被打槍,忽然她問了另位朋友後,「他想吃饗饗耶,我看了一下也不錯,可以嗎?」 「......那你們想要什麼時候?」 「下禮拜?」 .......去你的下禮拜,
Thumbnail
我要的畫面:晚餐不需要排隊點餐。 現場無人排隊,直接點餐,並且備餐時,還多了一個人協助完成餐食,整個流程順暢且快速,離開時,因為鄰車距離相近,對方還特別移車,讓我方便離開。 回家吃晚餐,食物比平時美味10倍,免不了又感謝一番,活著真好。 可操作重點:保持思想乾淨 如果腦中有懷疑,或是限制性的
Thumbnail
今晚與好飯友翻新了聚餐消費的天花板,兩人都抱著長知識的心情,走入隱密的餐坊,看了一眼紅底的米其林獎盃,內心既期待又怕踩雷,點餐時意外地與飯友默契滿點,親切的店員建議主餐外加小菜三碟,或者不點主餐來個小菜五六碟,兩人都對黑板上的龍蝦墨魚汁烤飯深感興趣,於是再分別點了冷盤、溫熱盤跟招牌各一。 冷盤
Thumbnail
之前跟格友-奇人奕事3.0-在討論區吹水,如果我學他/她講講寫寫一些飲飲食食,我就是在這裏不務正業,他/她回覆我,可作多方嘗試,那我就在今天開始不定時地「不務正業」吧~
一直以來,我都喜歡先想好、規劃好後再去執行,包括我的日常,要去哪吃飯一定要先找好再出門,但總會遇上想吃的店家或料理類型,不是沒開就是我的時間剛好卡到人家的中場休息,往往這個時候,都會跟自已說:算了,找間之前去過的店吧!!但心裡還是會有點小哀怨…然後,在前往餐廳的路上,就會不甘心的想:要不來googl
Thumbnail
帶著一顆空白的心吧,這家餐廳帶給你的體驗或許比你想像中的更多。
Thumbnail
在這個快節奏的生活中,尋找美食成為了一種日常的小確幸。然而,面對無數的選擇和各種疑問,決定吃什麼、在哪吃經常成為一大挑戰。這就是「美食探險家」APP誕生的初衷,一款旨在解決所有餐飲相關痛點的日式漫畫風格美食推薦應用。從「今天吃什麼?」到「這家店評價如何?」,美食探險家應有盡有,是尋找美食的最佳夥伴。
討厭甚麼,每個人心中都有清晰的答案。
Thumbnail
三餐的重要性,各有表述;三餐如何規劃,各有需求與方便性。
Thumbnail
全新 vocus 挑戰活動「方格人氣王」來啦~四大挑戰任你選,留言 / 愛心 / 瀏覽數大 PK,還有新手專屬挑戰!無論你是 vocus 上活躍創作者或剛加入的新手,都有機會被更多人看見,獲得站上版位曝光&豐富獎勵!🏆
Thumbnail
朋友忽然說好久不見想聚餐,我不假思索答應了,順道問了句要吃什麼我來找。 「我想吃點不貴的,省錢,但不要太LOW的。」 找了一些網美餐廳被打槍,忽然她問了另位朋友後,「他想吃饗饗耶,我看了一下也不錯,可以嗎?」 「......那你們想要什麼時候?」 「下禮拜?」 .......去你的下禮拜,
Thumbnail
我要的畫面:晚餐不需要排隊點餐。 現場無人排隊,直接點餐,並且備餐時,還多了一個人協助完成餐食,整個流程順暢且快速,離開時,因為鄰車距離相近,對方還特別移車,讓我方便離開。 回家吃晚餐,食物比平時美味10倍,免不了又感謝一番,活著真好。 可操作重點:保持思想乾淨 如果腦中有懷疑,或是限制性的
Thumbnail
今晚與好飯友翻新了聚餐消費的天花板,兩人都抱著長知識的心情,走入隱密的餐坊,看了一眼紅底的米其林獎盃,內心既期待又怕踩雷,點餐時意外地與飯友默契滿點,親切的店員建議主餐外加小菜三碟,或者不點主餐來個小菜五六碟,兩人都對黑板上的龍蝦墨魚汁烤飯深感興趣,於是再分別點了冷盤、溫熱盤跟招牌各一。 冷盤
Thumbnail
之前跟格友-奇人奕事3.0-在討論區吹水,如果我學他/她講講寫寫一些飲飲食食,我就是在這裏不務正業,他/她回覆我,可作多方嘗試,那我就在今天開始不定時地「不務正業」吧~
一直以來,我都喜歡先想好、規劃好後再去執行,包括我的日常,要去哪吃飯一定要先找好再出門,但總會遇上想吃的店家或料理類型,不是沒開就是我的時間剛好卡到人家的中場休息,往往這個時候,都會跟自已說:算了,找間之前去過的店吧!!但心裡還是會有點小哀怨…然後,在前往餐廳的路上,就會不甘心的想:要不來googl
Thumbnail
帶著一顆空白的心吧,這家餐廳帶給你的體驗或許比你想像中的更多。
Thumbnail
在這個快節奏的生活中,尋找美食成為了一種日常的小確幸。然而,面對無數的選擇和各種疑問,決定吃什麼、在哪吃經常成為一大挑戰。這就是「美食探險家」APP誕生的初衷,一款旨在解決所有餐飲相關痛點的日式漫畫風格美食推薦應用。從「今天吃什麼?」到「這家店評價如何?」,美食探險家應有盡有,是尋找美食的最佳夥伴。
討厭甚麼,每個人心中都有清晰的答案。
Thumbnail
三餐的重要性,各有表述;三餐如何規劃,各有需求與方便性。