跳至主要內容
YIP NEWS
生活 美食生活

小票上的字終於不毛了,而收銀臺後面的人最先鬆了一口氣

一位工程師在58與80公釐熱感紙上被鋸齒折磨兩週的開發故事,被我們翻譯成小喫店收銀臺、午高峯出單與那張帶著微焦味的小票的滋味故事。

YIP NEWS 編輯室 閱讀約 6 分鐘

(本文回顧的原始事件發表於 2026 年 9 月 2 日。)

先聞到味道,才看見畫面。那是一種很淡、很特別的焦香,熱感紙滑過列印頭的瞬間被燙出字來,紙張還帶著溫度,微微捲曲。你一定聞過。鹽酥雞攤的老闆娘撕下那張細長的單子塞進塑膠袋,牛肉麵店午高峯時櫃臺前整排人等著叫號,小票從機器裡鑽出來的速度,幾乎決定了隊伍往前挪的速度。

那天看到一篇文章,是一位工程師寫的。他把門市收銀系統從舊的桌面程式搬到瀏覽器,然後在 58 公釐和 80 公釐的熱感紙上,被列印問題折騰了整整兩週。他說那是他最不想碰、又不得不碰的一塊。我讀著讀著,眼前浮現的全是收銀臺後面那些人的臉。

你以為是機器壞了,其實是字在跟你作對

他最痛苦的不是紙窄,也不是店員每次都要伸手去點那個列印確認框。是一個聽起來很小的東西:鋸齒。

字邊像爬樓梯,條碼的豎條一根一根毛開來,掃碼槍掃半天掃不進去。面單上的粗體英文尤其明顯。他一度以為是熱感頭壞了,或者哪臺機器沒裝好驅動。這種心情,在小喫店裡其實有個一模一樣的版本。

你去市場裡的麵攤,老闆的發票機印出來的字如果糊了,他第一個反應也是拍機器。換紙、重開機、檢查卡紙。因為在櫃臺後面的人眼裡,紙會動、機器會響,那就是機器的事。很少有人會想到,問題可能出在「把字畫到紙上」的那一段看不見的路。

這位工程師後來做了一件很聰明的事。同一份單據,同一臺熱敏印表機,同一個驅動,他只換列印的入口:用 Chrome 印一次,用 WPS 印一次,用 Adobe Acrobat 印一次。結果出來,Google 瀏覽器和 WPS 印出來的字邊都發毛,條碼中間還有細細的橫紋,紙上實際就是那樣,不是拍照失焦。Adobe 印同一份,肉眼乾淨一截,細線不容易斷,條碼一掃就過。

他從這裡得出一個土辦法:Adobe 也糊,先查機器和紙;Chrome 和 WPS 都糊、只有 Adobe 清楚,那就別再懷疑熱感頭,是列印入口把灰邊和光柵渲出來的方式不一樣。

這整套排查的思路,跟廚房裡除錯很像。湯鹹了,你不會先怪鹽,你會先問同一鍋湯、同樣的鹽量,換個爐子還鹹不鹹。控制變因,一次只換一樣。這道理在爐臺上是常識,在收銀臺上,是兩週的折磨換來的。

靜默列印,翻譯成櫃臺的語言就是「不能讓店員多按一下」

文章裡有個技術圈的老規矩:瀏覽器裡的網頁程式,繞不過系統的列印對話框去直接指揮那臺 USB 熱敏印表機。所以「純前端靜默列印」這種事,要嘛根本靜默不了,要嘛背後其實掛了一個裝在本機的小程式在幫忙。

「靜默」這兩個字,翻譯成櫃臺的語言很具體。中午十二點半,你排在第六位,前面五個人的單子都在機器裡等著。店員每出一張單都要多按一次確認、多看一次彈出來的視窗,隊伍就多停三秒。三秒乘上整個午高峯,就是老闆娘額頭上的汗。

所以「能不能靜默」從來都是體驗問題,是排隊的人餓不餓的問題。工程師後來的方向是:服務端把單據生成 PDF,再交給本機的程式送去印表機。中間換了好幾家橋接的工具,JSON 格式各寫各的,前端為了適配它們堆了越來越厚的程式碼。他自嘲說,讓他自己從頭寫一個,肯定不想寫,太折磨人。最後他在 GitHub 上找到一個叫 web-print-pdf 的 npm 套件,直接對接。

這一段讀起來,像極了 kitchen 裡找一把順手的刀。你可以用菜刀切一切,勉強能過;你可以買一把很重的德國刀,握起來手痠;也可以一直換,換到有一把刀的重量、弧度、握感剛好落在你的手上。工具沒有信仰,順手就好,這是每一個在爐臺前站過的人都很早就學會的事。

對接的好幾天,其實是一種很老派的做事方式

裝上套件,事情也沒有立刻解決。紙寬、指定印表機、面單的鋸齒,他跟對方開發者在羣裡來回丟日誌和實拍照,對方前後改了好幾個版本:有的紙寬對了鋸齒還在,有的靜默穩了條碼邊又毛了。來回打了不少樣,最後才到「完全好了,沒一點問題」。

我把這一段讀了兩遍。因為這種來回,現在越來越少見了。

它像市場裡訂貨的老方式。你跟菜販說這批絲瓜太老了,他明天換一批來;你說芥藍要再嫩一點的,他記在心裡,下次進貨先留給你。沒有人一次到位,靠的是你一句我一句,加上一次一次實際的、上桌見真章的交付。列印出來的樣張,就是端上桌的那盤菜,毛不毛、糊不糊,紙上見。

這也讓我想到之前寫過的給媒體試喫的那盤,總是比你點的體面一點。測試環境和實際上路的東西之間,往往有一段落差,而願意盯著那段落差來回修的人,值得被記一筆。

他還踩過紙寬的坑。網頁樣式裡寫了 80 公釐,外層頁面還是 A4 的尺寸,結果左右兩邊全被切掉。後來的解法是把生成頁面的寬高寫死、四邊邊距全部歸零,印表機名稱從本機清單裡取,不寫死在某個名字上;本地服務沒開就先跳出提示,別讓店員面對一整排看不懂的錯誤訊息。午高峯的多聯列印,改成在本機批次串著出,頁面就少卡一點。

每一條,背後都站著一個具體的人。寫死印表機名字,換一臺機器櫃臺就停擺;錯誤訊息直接噴出來,站在櫃臺後面的工讀生只會慌。這些體貼,跟你家巷口那家永遠記得你不要辣的老闆,是同一種東西。

那張紙最後去了哪裡

文章的最後,他留下的是一小段包裝好的程式碼,檢查本地服務連上了沒,沒連上就丟出一句清楚的話。專案裡就剩這麼一點封裝,乾乾淨淨。

而對我們這些站在櫃臺前面的人來說,這兩週折騰的終點,是那張印得清清楚楚的小票。字邊利落,條碼一根是一根,掃碼槍紅光一閃就響。你可能從來沒注意過一張小票印得清不清楚,就像你沒注意過一家店的出單速度快不快,直到你在別家排過一次慢的隊。這也像海灘上擠了幾百個人而沒有人打架,這件事夜市老闆最懂裡聊過的:秩序這種東西,做得好的時候沒人看見,卻讓每一個人都喫得安穩。

下次你在麵攤結帳,等那張紙從機器裡鑽出來的兩三秒,聞一下那股淡淡的焦香,摸一下那點餘溫。那後面有一臺熱敏印表機、一份生成好的單據、一條本地服務的連線,還有一個曾經被鋸齒按在地上磨了兩週的人。他把字磨利了,隊伍就快了,你的麵就早兩分鐘上桌。

一張小票能管到的事,大概就這麼多。但一頓飯的順利,常常就是由這些「就這麼多」疊起來的。

#小喫店結帳#收銀臺日常#熱感紙小票