快轉到主要內容

我為履歷寫了個點餐網站,它(也許)幫我找到工作了

· 10842 字 · 18 分鐘
黃紅橙
作者
黃紅橙
現為軟體工程師,偶爾做遊戲影片
目錄

MOM POS Logo

專案簡介
#

MOM POS - 簡單、聰明、好用,專為餐廳設計的智慧銷售點系統。

🔗 線上 Demo

🔗 Github Repo

🛑 在使用之前提醒你一下 🛑 鑒於我找到工作了,MOM POS 的專案就告了一段落,目前使用後端的 Docker 已關閉(每個月可是實實在在還在給我扣款),只剩下部署於 GitHub Pages 的前端還會留著,主要幾隻 API 改為固定回傳值,留下前端作展示。

多功能、跨裝置的線上點餐網站
#

MOM POS 是一個點餐網站,一方面提供餐飲業者方便又快速的建立編輯菜單、管理客戶資料,另一方面能讓顧客登入會員、線上點餐,具備 RWD、權限管理等功能。

每位媽媽都說好用的 POS 系統 👍
#

整個專案的靈感是由我媽出發,我希望能打造連我媽都說簡單好用的 POS 系統,也希望 MOM POS 就像媽媽一樣的精打細算、細心周到,幫你省下時間,及精確的掌握店內營銷。

MOMPOS
#

MOMPOS 的意思是 Master of Mangement Point of Sale,簡稱 MOM POS。(對我當初就是想來個酷酷的諧音梗,現在看來有點好笑。)


專案心路歷程
#

這是我 2024 大學實習結束後,想說在當兵前後的空窗期開發一個 Demo 網站,目的是希望能用這個網站作為履歷的一環,以幫助我找到第一份軟體工程師的正職工作。大約在 2025 年 2 月才正式的完成,前後花了 8 個月左右。最有印象的時候就是過年前,冷冷的冬天裡在房間中埋頭苦幹一整天,桌上放滿了各個茶類水搖飲料杯,連續幾個禮拜這樣幹,到後來生理時鐘還顛倒了,每天下午 3 點起來,一路做到早上 4 點,可能是因為也還沒找到工作,所以作息很亂。

理想原本是覺得三個月內就能完成,但現實是殘酷的,從部署開始就滿滿的問題,記得有一次為了一個功能要部署 Docker 時,不知道為什麼怎麼都 Fail,重試了我記得可能快 20 次有,精神快崩潰。我想也是因為我自己配 AI 開發,沒人可以詢問,就覺得特別沮喪,那可能是我最接近要放棄這個專案的時候,對這個網站可以說是又愛又恨啊啊。

如果你問我用 AI 開發網站簡單嗎,我會說看你的需求。如果只是一個純前端的簡易網站,GitHub Pages 部一部的話可能幾天就完成了。2026 的 AI 甚至一行 code 都不用寫,一兩個小時跑一跑就完成了。但我是要拿來面試用的,所以當初是想完整規劃一個產品,並且想要把各種技能都試一次,所以才搞得特別累。

至於最後這個網站對我找工作有幫助嗎?其實我也不是很確定,畢竟面試看的東西很多,Demo 作品也只是幾十個問題中可能會被拿出來提的一個。

但我後來面上的工作,也就是我現在的主管,他說他有特別點開我的網站來玩一下,也有幾次面試被 HR 或是主管們問到這個網站,這時他們主動提的時候,至少我有東西可以講,這時候就是自己比較有把握的加分題了,所以或多或少無形中都有幫助我面試~

技術架構
#

三層式架構
#

Three Tier Architecture With C#

使用前後端分離:

  • 前端:Vue.js + Quasar
  • 後端:C# .NET Core
  • 資料庫:MSSQL

會這樣規劃也是因為我前一間實習公司做的專案都碰過這些技術,比較多自己嘗試的地方是部署的部份,還有一些細節的設計。

部署後端與資料庫
#

  • 使用 Docker + GitHub Actions + Digital Ocean Droplets

後端跟資料庫是各自一個容器,資料庫接口只對後端,後端接口對前端。

Digital Ocean 我買 12 美元的方案,一開始用最便宜方案還裝了 MSSQL 2022,殊不知那個規格我最便宜方案跑不動😂,後端 + 資料庫引擎要能 Run 不可能用這麼低,後來才改方案,並改用 MSSQL 2019。

部署前端
#

  • 使用 GitHub Pages + CloudFlare

這些都免費用,一般來說也不可能到收費標準,買網址我是去 NameCheap 買的,經濟實惠。


功能介紹
#

點餐 UI
#

菜單頁面

靈感參考各大線上點餐系統,其中我覺得最漂亮簡單的是麥味登的 APP,在做的時候就想著要比他還美的心情在設計。

雖然用 AI 寫前端已經很方便了,但前端對我來說有時候就是卡一個感覺,某些細節就是不對,我就還是要改蠻久的。

會員系統
#

登入頁面

會員登入系統

基本上是用 Cookie 來維持登入,登入後會存一串加密後的 Token,並且用 Middleware 來確保特定 API 有驗證 Key。實際的密碼輸入後,是用 Password Hash,所以也不用擔心有明碼存的安全問題。

還有設了一些針對 IP 防止亂 Try 登入的機制,如果 30 分鐘內嘗試登入 15 次就會被我關進小黑屋兩天。

順道一提,購物車裡面的內容也是用 Cookie 來記著的。

菜單編輯器
#

菜單編輯器

管理員菜單編輯功能

🔗 點擊進入菜單編輯器

我真的是瘋了才想出這個需求。

前端設計上就卡了一堆問題,彈窗的設計也好,儲存的設計也罷,都是刪刪改改後才勉強做出來。

我最後決定是把順序、刪除品項、隱藏品項放在外層,如果使用者有任何這類的修正,右下角的綠色儲存鈕就會亮起。而品項的資料跟圖片都會放到內層這個彈窗。

菜單編輯器內層

啊對了,圖片上傳的話是用 Cloudinary 圖床的 API,所以我一直沒有真正開放這個菜單編輯器的功能過,因為風險太大了。我是有想過針對不同使用者非等級,某一個等級才可以上傳圖片之類的。

如果還要讓不同使用者真的開一家店,還需要設計一下各店的網址,並且確保不會跨店,也要考慮有沒有人有惡意亂 Try API 的問題,需求的工非常大。

但想想有這樣的需求,有人會用我的網站 Demo 用到這麼深嗎?那他應該要直接來跟我聯絡,我線上 Demo 給他看就好 🤣。

總之,最後這個對使用者不同等級的劃分確實是我最後一個還未完成的需求,那時候覺得網站成熟了,就不再繼續開發,開始投履歷面試了。

其他怪設計
#

  • 夜間模式:開了會幫媽媽戴上墨鏡
  • Logo:我設計的,用日本免版權素材網的圖來改
  • 配色:橘黃色我覺得是最有食慾的顏色
  • i18n:多語系設計我覺得很酷,但比想像中麻煩
  • 最上面的工具欄:你絕對想不到我花了多少時間設計這裡,AI 根本不懂美學,但 CSS 又真的很煩人,只能慢慢調。
  • RWD:如果你用手機版會發現完全不一樣,我一直覺得菜單按鈕放下面手機才好按,而網頁則是要放上面。
  • 最下面的作者欄:你用手機版或把視窗縮小,會看到跑馬燈。
    alt text

資料庫設計
#

物件關係設計
#

到底是多對多還是一對多關係?
#

菜單、分類、品項,特製項目的關係,這部份設計上我想了很久,尤其是資料庫的設計,那時候還是小白,不知道這種每一個食物跟食物的特製到底是要一對多關係還是多對多,可能是因為平常都習慣了飲料都是去冰/少冰/正常冰,這樣一組可以共用,會一直想成多對多關係。

這另一個原因也是因為 Uber Eats 的後台我有用過,他們確實能設定一組客製選項後套用到不同商品上,所以我就很想學。但考慮到這花我太多時間搞太複雜,光開資料庫 Table 我就開不出來了。後面就改成一對多關係,比較簡單。

物件設計
#

物件有以下:

  • 菜單 (MenuConfiguration):同一家餐廳可以設計多組菜單,但同時只能用一組,這個有參考 Uber Eats 後台
  • 分類 (Category):飯/湯/甜點這一類不同種類的分類
  • 品項 (MenuItem):實際的一道菜
  • 特製項目 (MenuItemOptions):每一道菜各自的細節選項,如不要辣/少糖等

彼此關係是:

菜單 MenuConfiguration (1) ──→ (N) 分類 Category
分類 Category (1) ──→ (N) 品項 MenuItem
品項 MenuItem (1) ──→ (N) 特製項目 MenuItemOptions

另外還有比較簡單的:

  • UserInfo:使用者註冊資料
  • RegisterInfo:第一次註冊時要的使用者帳密,密碼是 Hash 過的

這一切到這裡都還好,但是一旦加入了訂單 (Order) 我就頭昏了。為了直觀一點,我直接貼後端的物件:

訂單物件設計
#

public class Order
{
    [Key]
    public int OrderId { get; set; }
    public DateTime OrderDate { get; set; }
    public decimal TotalAmount { get; set; }
    public required ICollection<OrderItem> OrderItems { get; set; }
    public int UserInfoId { get; set; }
    public UserInfo? UserInfo { get; set; }
}

public class OrderItem
{
    [Key]
    public int OrderItemId { get; set; }
    public int OrderId { get; set; }
    public Order? Order { get; set; }
    public int MenuItemId { get; set; }
    public MenuItem? MenuItem { get; set; }
    public int Quantity { get; set; }
    public decimal TotalPrice { get; set; }
    public decimal UnitPrice { get; set; }
    public string Options { get; set; } = string.Empty;
}

也就是 Order 中會有 N 個 OrderItem,Order 是匯整整個訂單,OrderItem 再與他關聯。

最主要讓我比較卡的是 OrderItem 的概念,最後我是以:

同一商品 + 同一選項 = 一組 OrderItem

也就是:

  • 三份招牌河粉 酸辣口味 = 一份 OrderItem
  • 三杯冰咖啡,兩杯咖啡要去冰(一份),一杯咖啡冰塊要更多(一份) = 兩份 OrderItem

這樣的設計是考慮到有些選項可能是會影響到價錢的,也就是我加冰塊可能要多加五塊。

其實做這些設計比較困難的部份是我也沒有明確的 PO 或是客戶定義需求,所以我自己得控制好做起來的難度跟價值,不然會越想越多,越想越複雜。


結語
#

大致上就這樣,寫到後來對自己的網站/產品還真的有點革命感情,Show 給朋友看都會有一種叫小孩在長輩面前表演才藝的感覺 XD (你看你看,他會這個喔)。原本想說一找到工作就關掉網站,拖了半年才關起來。

對程式碼生氣、沮喪、開心、感動,真的是很奇怪的感覺,但這個網站確實是我的孩子,不是說真的很多人能拿來用或是技術很屌,畢竟要比的話可以看一下星露谷物語作者的故事,只是做個工程師的履歷做到出了一個暢銷遊戲。

但我想這個網站對我來說很有意義,見證從我最苦的時候,到我有了第一份正職。

以此文紀念這段歷程,也希望能給正在找工作或是想開發 Demo 網站的你一點參考,或是給正在開發 Demo 網站的你一點鼓勵。如果你看到這裡,我要特別提醒你,千萬不要只做 Demo 網站,所有該準備面試的東西都要準備,從行為問題、leetcode、履歷設計都要準備,Demo 網站老實講都不比這些還要重要,總之就是加油啦!