
做鴻蒙設備的人臉識別門禁對接業務系統這事兒聽起來不復雜真正落地才發現坑不少。我前前后后參與過幾個生產環境的門禁對接項目不是那種實驗室demo是幾十臺設備同時在線、一天幾千條通行記錄壓過來的真實場景。今天這篇不談人臉識別算法本身有多準也不聊刷臉快慢專門聊聊對接業務系統這件事API和MQTT這兩條通道到底怎么分工、怎么定規范、怎么把坑提前踩平。1. 整體架構設計與對接思路拆解1.1 門禁對接為什么需要API和MQTT兩條通道很多開發者第一次接觸門禁對接上來就問一個問題到底是走API還是走MQTT我的答案是成熟的生產項目兩條都要只是分工完全不同。先想清楚業務系統到底需要什么。一個完整的人臉識別門禁項目至少有四類數據在流動人員信息姓名、工號、人臉特征、有效期、門禁權限、設備管理信息設備注冊、在線狀態、算法版本、時間同步、實時通行事件某人某時刷臉通過或未通過、控制指令遠程開門、鎖定、解除告警。前兩類屬于管理面數據特點是低頻、數據量大、對一致性和可靠性要求極高。這類數據最合適的通道就是RESTful API一次請求一次響應成功失敗當場就知道還能配合數據庫事務保證數據不丟不亂。你總不能把幾百人的批量授權通過MQTT去推萬一丟了幾條授權消息某個人在門口刷不開門運營人員還不知道為什么。后兩類屬于實時數據面特點是高頻、單條消息體小、對時延敏感。如果用API輪詢通行記錄既浪費帶寬也很難做到秒級響應。這一層交給MQTT最合適設備端一產生識別結果就推出去業務系統訂閱對應主題毫秒級就能收到。用個生活化的比喻API像去銀行柜臺辦業務填單、取號、確認每一筆都有回執MQTT更像是一個電臺廣播你調到對應頻率就能一直聽內容實時到達但可能有人漏聽一段所以需要靠消息里的編號msgId去發現自己漏了什么。1.2 組合方案的選型考量與生產優勢我之所以堅持API和MQTT并存不是拍腦袋而是從實際項目中總結出來的。第一是分層解耦。管理面和數據面分開兩個通道可以獨立擴容、獨立降級。我做過一個園區項目早高峰幾百人同時進樓MQTT通道壓力很大但API通道幾乎沒波動因為人員授權都是提前下發好的不會到點了才開始拉數據。如果所有流量都擠在一個通道里高峰期任何一個環節抖動門禁系統整體就癱瘓了。第二是異常補償簡單。API天然支持重試斷網了業務系統可以定時補償同步MQTT負責實時數據即使斷了幾秒設備端也能在恢復后把離線期間的通行記錄通過API或MQTT補傳。一快一穩互相兜底。第三是運維視角清晰。日志里一眼能看出問題出在哪一段人員下發走API有HTTP狀態碼可查設備狀態和通行事件走MQTT靠消息ID和主題就能追蹤到消息消失在哪一跳。當然兩條通道也意味著兩套連接、兩套認證、兩套數據格式調試復雜度確實上來了。但跟現場幾百臺設備出問題后到處救火相比這個復雜度完全值得。下面這套工程規范是我在實際項目中反復打磨過的照著落地能幫你在集成階段少踩大部分坑。2. API對接工程規范與核心細節2.1 接口鑒權與安全設計門禁系統里的數據都是敏感的人臉照片、人員工號、門禁權限、通行記錄。接口如果裸奔等于把門禁卡直接丟在大街上。我推薦Token鑒權加請求簽名雙層防護。業務系統和設備端先通過一個認證接口換取Access Token這個接口用appId和appSecret做身份認證。appSecret不能直接在網絡上明文傳輸標準做法是appId、timestamp、nonce隨機數拼接后再做HMAC-SHA256簽名服務端收到后自己用同樣的規則算一遍兩邊比對。POST /api/v1/auth/token { appId: your_app_id, timestamp: 1700000000000, nonce: 7d3c8f62ab1e, sign: a5f8c1d... }服務端拿到請求后第一步檢查timestamp與當前時間差是否在5分鐘以內超出直接拒絕這是防重放攻擊的基本手段。然后用appId查到對應的appSecret本地按同樣的拼接規則重新計算簽名對比一致才算認證通過。Token有效期建議設在2小時左右過期后用refreshToken刷新避免業務系統半夜因為Token過期而批量失敗。簽名計算這塊是踩坑高發區。最常見的坑有兩個一個是拼接順序不一致服務端約定的是appId appSecret timestamp nonce客戶端寫成了appId timestamp nonce appSecret兩邊算出來的簽名永遠對不上另一個是字符編碼不一致有些老設備默認用GBK服務端統一用UTF-8只要參數里出現中文兩邊的簽名結果就完全不一樣。所以簽名規范里必須寫清楚原始字符串直接拼接、不做URL編碼、統一UTF-8編碼、拼接順序固定。還有一個特別容易忽略的點設備端和業務系統的服務器時間必須同步。有一次排查一個項目簽名校驗一直失敗最后發現設備時鐘慢了3分鐘超過了時間戳容差窗口。設備的初始化和運維流程里一定要加上NTP時間同步這一步不然后面全是莫名其妙的鑒權失敗。2.2 核心接口定義與字段約定接口的命名和字段規范決定了聯調階段是省心還是遭罪。我這里給出一份經過生產驗證的接口清單照著這個模板改比從零開始設計靠譜得多。必做的核心接口有五個按調用順序來講。第一個是設備注冊接口設備首次上電后調用把自己注冊到業務系統。請求參數包括設備編號、設備型號、鴻蒙系統版本、人臉識別算法版本。服務端返回deviceId和密鑰設備持久化保存之后的請求都帶deviceId。POST /api/v1/device/register { deviceSn: HW-DOOR-0001, deviceModel: HarmonyDoor-Pro, osVersion: HarmonyOS 5.0, algorithmVersion: 1.4.2 }第二個是人員信息下發接口。這里要注意單個人員新增和批量同步建議拆成兩個接口。單個新增適合管理端手動操作批量同步適合項目初始化導入和歷史數據遷移。字段統一用駝峰命名personId、personName、orgId、faceFeature、faceImageUrl、expireTime、authorizedDoorIds。數據格式統一JSON即可不要為了省流量發明自定義分隔符格式聯調期間會想哭的。第三個是權限變更接口。人員離職、換部門、調整門禁分組都走這個接口。設計要點是增量更新只傳變更部分不要每次全量同步幾千人否則高峰期數據庫壓力會非常大。第四個是遠程控制接口。遠程開門這類指令API和MQTT都能發。我的建議是Web后臺操作員點擊遠程開門直接走MQTT下發指令主題時延更低。但API方式也必須保留用于MQTT通道異常時做應急預案。例如POST /api/v1/device/dev10001/unlock { operator: admin, reason: 訪客通行, requestId: 550e8400-e29b-41d4-a716-446655440000 }服務端返回指令已下發但實際是否開鎖成功依賴設備端后續通過MQTT上報執行回執。也就是說API負責發起動作MQTT負責確認結果兩條通道在業務邏輯上是串聯的。第五個是通行記錄查詢接口用于事后追溯。查詢參數包括日期范圍、人員ID、設備ID、識別結果allow/deny分頁返回。字段里必須有recognitionScore識別分值、passDirection進/出方向、captureTime抓拍時間。接口命名統一RESTful風格資源用名詞復數動作用HTTP方法。路徑里的設備標識統一用穩定不重復的deviceId不要用數據庫自增主鍵否則以后多設備對接時主鍵一遷移就全亂了。所有時間字段統一用毫秒級時間戳不要一個接口傳字符串一個接口傳時間戳解析代碼會寫到崩潰。錯誤返回統一結構{ code: 40001, message: person faceFeature is empty, requestId: 550e8400-e29b-41d4-a716-446655440000 }Code是業務錯誤碼message是給人看的描述requestId用于全鏈路日志追蹤。這個結構看起來簡單但對聯調排障幫助巨大不要只返回一個HTTP 400了事。2.3 回調機制、冪等與重試補償門禁項目里API不只是業務系統請求設備還有設備主動回調業務系統的場景比如識別結果同步、設備狀態變更。回調若設計不好兩個系統就像兩個對不上話的人互相干等。回調第一要務是驗簽。設備回調業務系統時必須攜帶簽名信息業務系統用約定的密鑰驗簽。驗簽失敗直接丟棄并記錄告警日志這能擋住大量偽造請求。我見過一些項目只校驗URL里的參數是不是存在不驗簽結果被腳本刷了幾萬條假通行記錄整個數據全廢。第二要務是冪等。設備回調可能因為網絡超時被重復投遞。同一條通行記錄業務系統收到兩遍如果沒有按msgId去重統計報表里的通行次數直接翻倍。設備端生成每條消息時必須帶唯一的msgId業務系統接收側維護一個近期msgId緩存比如最近一萬條重復收到直接返回成功。緩存不用永久保留24小時已經足夠消息延遲不可能超過一天超過就是異常。第三要務是重試。設備回調失敗不能直接丟棄按指數退避算法重試第一次間隔1秒第二次2秒第三次4秒到最大重試次數比如5次后仍失敗就寫入本地失敗隊列等網絡恢復再補償。這套邏輯看起來基礎卻是我見過的最容易被砍掉的模塊。不寫重試的項目現場網絡一抖動幾分鐘通行記錄丟得稀里嘩啦運營對不上賬最后還是要回來補。重試帶來的副作用是消息重復所以冪等必須和重試配套實現。重試請求保持msgId不變服務端按msgId去重。實際項目中能做到At-Least-Once加冪等去重已經覆蓋絕大多數業務場景沒必要追求復雜的兩階段提交協議。3. MQTT消息通道的工程落地規范3.1 主題設計與消息封裝格式MQTT的一切圍繞主題運轉。主題設計得好壞直接決定消息路由的清晰度和后續權限管理的顆粒度。我推薦分層主題設計基本規則是項目/設備/事件類型三層結構通行事件上報iot/{projectId}/{deviceId}/event/recognize設備狀態上報iot/{projectId}/{deviceId}/event/status設備告警上報iot/{projectId}/{deviceId}/event/alarm遠程開鎖指令iot/{projectId}/{deviceId}/cmd/unlock指令執行回執iot/{projectId}/{deviceId}/reply/unlock層級不要超過5級層級越多主題越長匹配效率越低用云上broker時還容易誤匹配。通配符用的時候要格外小心加號匹配單層井號#匹配多層。比如業務系統統一訂閱某項目所有設備的識別事件用iot/{projectId}//event/recognize訂閱某個設備的所有消息用iot/{projectId}/{deviceId}/#。主題層級設計不規范通配符訂閱要么漏消息要么收到一堆不相關的內容。設備唯一標識建議直接用設備注冊接口返回的deviceId而不是設備SN。原因是SN可能在安全整改中被廠家調整而deviceId在整個生命周期內保持不變用這個標識做路由最穩定。每個主題下的消息體統一用一個envelope結構包裹不要各寫各的{ msgId: 3f5b8e2f6a9c4d1e, type: recognize, timestamp: 1700000000000, version: 1.0, payload: { personId: P10001, name: 張三, authorized: true, score: 0.9876, doorId: D01, direction: in } }外層字段是通用協議內層payload是具體業務數據。好處非常明顯解析代碼可以先不管具體業務把msgId、type、timestamp統一取出來做日志、去重、路由再按type分發給對應的業務處理器。以后新增事件類型只需要加一個type和對應的payload規則協議框架完全不用動。在鴻蒙設備端這個envelope的構建建議封裝成一個公共模塊避免每個業務功能各寫各的序列化方法。我見過同一個項目里出現三種字段命名風格并存的情況有駝峰有下劃線還大小寫混用后端解析代碼寫起來苦不堪言。統一封裝統一序列化統一字段命名后端能少死一大批腦細胞。3.2 QoS級別選擇與消息去重機制MQTT提供三個QoS級別QoS 0最多一次可能丟QoS 1至少一次保證送達但可能重復QoS 2恰好一次最可靠但開銷最大。門禁場景具體怎么選我的經驗是通行事件上報選QoS 1。通行記錄要事后追溯丟了很麻煩重復收到可以靠msgId去重沒必要動用QoS 2那么重的機制。事件量大時QoS 2的協議交互會給broker造成很大壓力幾臺設備用QoS 2可能看不出問題幾十臺上百臺壓過來消息延遲和堆積就會非常明顯。遠程開鎖指令也選QoS 1配合payload里的requestId做冪等。開鎖是安全敏感操作重復執行比丟指令好重復開鎖頂多多開一次門丟指令可能導致人員被鎖在外面。但重復執行畢竟不是理想行為所以必須在設備端做冪等處理。設備收到開鎖指令后把requestId存進最近指令緩存比如5分鐘窗口如果再次收到相同ID就不再執行而是直接返回已經執行過的回執。設備執行完開鎖后發布回執消息格式如下{ msgId: 9a1f2c33d47e41f8, type: unlockReply, timestamp: 1700000000005, payload: { requestId: 550e8400-e29b-41d4-a716-446655440000, result: success, deviceId: dev10001, replyTime: 1700000000005 } }業務系統收到回執才算完整閉環。我還建議加一個指令超時重發機制業務系統下發開鎖指令后5秒內沒收到對應requestId的回執就再發一次超時時間可以配置。重發時仍使用同一個requestId設備端靠冪等性保證不會重復開鎖。3.3 心跳保活、遺囑消息與斷線重連MQTT靠心跳維持連接。設備端每隔keepalive時間發送一次PINGREQbroker如果在1.5倍keepalive時間內沒收到任何包就判定設備離線并斷開連接。鴻蒙設備上的keepalive建議設置在30到60秒之間。低于30秒心跳過于頻繁白白耗電超過60秒遇到4G網絡的NAT超時連接會處于假死狀態設備以為還連著實際上消息已經送不到了。斷線重連是現場項目最能拉開水平差距的部分。最簡單的邏輯是斷開后固定時間重連但這有個隱患如果broker暫時不可用固定頻率的重連會形成大量無效連接壓力。推薦指數退避策略重連間隔從1秒開始每次失敗翻倍1秒、2秒、4秒、8秒最大到30秒。網絡恢復后設備最遲30秒內自動恢復連接。對門禁場景來說30秒內恢復完全可接受。設備重連成功后要做幾件收尾工作重新訂閱之前訂閱過的主題CleanSession設為true時broker不會保留訂閱關系清理斷線期間積壓的本地消息隊列主動上報一次當前設備狀態讓業務系統立刻感知設備已恢復。不要小看這個主動上報很多項目里設備重啟后業務系統一直顯示離線就是因為設備沒在重連成功后上報狀態業務系統只能等服務端的心跳超時判斷白白多等幾分鐘。遺囑消息Will Message是MQTT特有的機制。設備連接broker時可以聲明一條遺囑消息如果設備異常斷開也就是沒有正常發送DISCONNECT包的斷開broker會替設備發布這條遺囑。門禁場景里設備可以設置遺囑為設備離線狀態發布到狀態主題。這樣業務系統不用依賴定時輪詢設備狀態設備一掉線broker馬上就能通知到業務系統。關于CleanSession門禁設備的上報類應用建議設為true因為broker不保留離線會話設備重連后從當前時刻開始接收新消息邏輯簡單不會因為積壓的舊消息導致狀態錯亂。至于離線期間的指令丟失問題由業務系統的超時重發機制兜底比依賴broker的持久會話更可控。很多開發者在CleanSession這里糾結很久我的建議是越簡單越好別把現場排障搞得太復雜。4. 鴻蒙端設備接入的實現要點4.1 鴻蒙應用權限聲明與網絡安全配置鴻蒙應用要聯網、要用攝像頭第一步就是權限聲明。在module.json5中配置{ module: { requestPermissions: [ { name: ohos.permission.INTERNET }, { name: ohos.permission.CAMERA }, { name: ohos.permission.READ_MEDIA }, { name: ohos.permission.GET_NETWORK_INFO } ] } }這里有個現場經常踩的坑鴻蒙應用在API 9及以上版本網絡安全配置默認限制明文HTTP流量。很多開發者在調試階段直接訪問本地HTTP服務發現請求一直失敗查了半天沒想到是網絡安全配置攔截了明文HTTP。調試時可以在網絡安全配置里顯式允許指定域名但生產環境務必關掉人臉特征和門禁記錄走明文傳輸是完全說不過去的。另一個容易忽略的是權限動態申請。相機權限在鴻蒙上屬于用戶級敏感權限運行時需要動態彈窗申請。有些人以為權限聲明寫進配置文件就萬事大吉結果真機上拿不到攝像頭圖像。權限申請要在業務流程開始前主動觸發并且做好被拒絕時的降級處理比如提示用戶去設置頁開啟權限同時把設備狀態置為攝像頭不可用不要傻等著。4.2 人臉識別結果的本地處理與離線補傳人臉識別門禁設備不是每次刷臉都能識別成功。設備端識別流程大致是攝像頭采集幀人臉檢測質量評估角度、亮度、遮擋特征提取與本地人臉庫比對得出結果。鴻蒙設備上攝像頭采集建議使用XComponent承載預覽流或者用相機接口獲取圖像幀。識別結果產生后設備內部先做一次事件分類識別通過、識別失敗、未注冊人員、活體檢測失敗、黑名單等。不同事件類型對應不同的MQTT消息payload。這里的關鍵點是不要把所有識別結果都一股腦丟上MQTT設備端應該做一次過濾聚合。識別通過和識別失敗的信息需要實時上報這關系到出入權限判定。未注冊人員觸發可以做節流比如同一張陌生臉10秒內只上報一次避免陌生人連續在門口試探導致消息風暴。活體檢測失敗屬于安全告警必須立刻上報并且附帶抓拍圖片和序號方便事后追查。本地緩沖也很重要。MQTT連接斷開時識別事件不能直接丟棄。我建議在設備本地做環形緩沖區容量根據存儲空間和業務量設置比如保存最近2000條事件。連接恢復后按順序補報離線期間的事件并在payload里加一個offlineMarker標記業務系統就知道這條是補傳數據時間戳代表原始發生時間不是當前時刻。補報時需要控制速率比如每秒最多20條避免恢復瞬間把設備和broker同時壓垮。這個離線補傳機制幾乎是生產環境的剛需很多項目驗收時不測運營一周后一定會遇到網絡抖動沒做補傳就只能對著缺失的通行記錄干瞪眼。4.3 開閘指令的接收、校驗與執行鴻蒙設備訂閱了指令主題之后收到開鎖指令不能直接執行。執行前必須做五步校驗。第一步查重檢查msgId是否在最近指令緩存里如果在說明是重復消息直接丟棄并返回重復回執。第二步校驗目標doorId是否是本設備不是就忽略。第三步校驗指令時間戳是否在有效窗口內建議前后5分鐘時間戳過舊的可能是延遲很久才到達的舊指令防止執行過期操作。第四步校驗指令來源業務系統下發的指令應帶有token或簽名信息校驗不通過直接告警。第五步檢查設備當前門鎖狀態如果已經處于打開狀態重復執行沒有意義直接返回當前狀態。校驗通過后才調用門鎖控制模塊執行開鎖動作并記錄本地日志。開鎖完成后立即發布回執消息回執里必須帶原始指令的requestId、執行結果、設備ID、執行時間。如果開鎖執行失敗比如鎖體故障、電機卡住回執里要帶錯誤碼和錯誤描述方便現場維護人員直接定位是鎖的問題還是控制板的問題。還有一個細節值得提門禁場景設備經常要連續多人刷臉通行開鎖線圈保持通電的時間通常建議3到8秒用可配置參數控制。指令的實時執行對設備任務優先級有要求MQTT收包之后要放到高優先級任務隊列避免被UI線程或日志線程阻塞導致開鎖延遲。我做過一個項目設備端用同一個線程處理MQTT收包和日志寫入現場日志量大時開鎖延遲最高到了將近2秒把收包和日志拆成獨立線程后延遲才穩定在200毫秒以內。5. 常見問題與排查技巧實錄5.1 API對接高頻問題速查我把這些年項目中遇到的高頻問題整理成一張表遇到類似情況可以按圖索驥。現象可能原因處理方式請求返回401Token過期或未攜帶檢查token緩存和刷新邏輯重新獲取token返回401且簽名校驗失敗簽名拼接順序或編碼不一致對照簽名規范檢查原始字符串拼接順序統一UTF-8返回400請求體字段名不匹配核對接口文檔重點看大小寫和駝峰/下劃線差異返回403設備未注冊或已被禁用檢查設備注冊狀態和授權狀態請求超時防火墻攔截、域名解析慢、后端線程池滿先ping和telnet測試端口連通性再做全鏈路抓包時間戳校驗失敗設備時鐘漂移啟用NTP同步運維時定時校正設備時間這里特別想強調一個后端容易犯的錯分頁參數和排序字段不統一。有的接口用page/pageSize有的用offset/limit有的用current/size排序字段有的叫createTime有的叫create_time。單接口聯調時不容易發現問題一旦寫數據導出和報表統計功能就會折磨死人。接口規范最好在項目啟動時就一次性定死不要拖到聯調后期才來改。5.2 MQTT連接與消息丟失的定位思路MQTT場景的問題一半出在連接上一半出在主題不匹配上。連接類問題定位順序先ping broker的IP和端口確認網絡通不通再看設備日志里TCP建聯是否成功最后看MQTT層的CONNACK返回值。CONNACK返回碼含義明確0連接成功1協議版本不匹配2客戶端ID被拒絕3服務不可用4用戶名密碼錯誤5未授權。遇到連接問題先看CONNACK返回碼能省掉一半排查時間。還有一個很經典的假死問題。設備部署在4G網絡時4G NAT網關的空閑連接回收時間通常只有幾分鐘。如果設備端keepalive設置到120秒NAT已經把連接斷了但設備端不知道還認為自己在線。這時業務系統下發的指令設備根本收不到設備端也不報錯。排查方法很簡單查看broker上的在線連接列表看設備是否真的在線或者用MQTTX手動訂閱設備主題模擬下發消息看設備有沒有響應。解決方案就是keepalive不要超過60秒同時用遺囑消息讓broker及時感知設備離線。消息丟失的話優先懷疑主題名稱不一致。常見坑有業務系統訂閱的topic寫成了iot/project01/dev10001/event/#設備發布的topic實際是iot/project01/dev10001/event/recognize看起來應該能收到但如果業務系統用的是iot/project01/dev10001//#這種組合通配不同broker的通配符匹配行為有差異就可能收不到。還有一種情況消息發送成功了但業務系統沒收到原因往往是QoS設置為0broker在重負載下丟棄了消息。排查時可以在broker上開啟消息日志或者用一個臨時訂閱者訂閱井號主題看消息是否真的到了broker。只要消息到了broker再從broker到訂閱者這段就相對好查了。5.3 聯調階段一定要做好的三件事第一件事先本地模擬再上真實設備。我在本地用EMQX搭了個broker用MQTTX模擬設備端發布消息把業務系統的訂閱邏輯、去重邏輯、解析邏輯全部跑通然后才拿真實鴻蒙設備去現場聯調。這樣做的好處是現場聯調直接測試設備真實業務而不是在現場一邊調業務邏輯一邊查協議。第二件事固定msgId全鏈路打點。從設備生成消息到業務系統落庫全程打印msgId。排查問題時在日志里搜msgId就能看到一條消息完整生命周期什么時候發出、什么時候到broker、什么時候被業務系統消費、處理結果是什么。沒有msgId日志的項目排查消息問題就像盲人摸象。第三件事把異常場景演練一遍。專門測試網絡斷開、broker重啟、設備斷電重啟、指令下發時設備離線這四種場景。每種場景都要確認設備能否自動恢復、離線期間的數據能否補回來、業務系統狀態是否正確、指令是否有超時重發。這些異常場景不在聯調階段測遲早會在運營階段以事故的方式測出來。我自己的習慣是把這四類異常做成一個checklist每次項目上線前過一遍花小半天時間能避免后面現場跑斷腿。5.4 對接前先把四份契約文檔定下來最后分享一個非常實際的經驗做鴻蒙人臉識別門禁對接最忌諱一上來就直接寫代碼。先把四份文檔敲定再動手哪怕團隊只有兩個人也先定契約再編碼。第一份是API接口規范包含所有接口的URL、請求參數、響應格式、錯誤碼。第二份是MQTT主題表包含所有主題路徑、消息方向、QoS級別、payload字段說明。第三份是消息格式定義主要是envelope結構里每個字段的含義、取值范圍、示例。第四份是異常處理機制文檔明確重試策略、冪等規則、離線補傳邏輯、狀態機定義。這四份文檔不需要多長但要具體到可以直接照著寫代碼的程度。尤其是payload字段的命名和含義最好規定到枚舉值級別。比如識別結果字段就明確寫allow表示允許通行deny表示拒絕expired表示授權過期blacklist表示黑名單。不要讓設備端和業務系統各自理解否則聯調時同一個字段兩邊理解不一致來回扯皮能扯一周。我經手的項目里凡是在開頭省了規范設計的后面基本都要靠加班來償還。先把契約定下來后面聯調就是按部就班的事情。