實(shí)戰(zhàn)|拼豆制圖43:壓縮字符矩陣上線前如何攔住錯(cuò)位圖紙)
把 70×70 圖紙壓成字符行很節(jié)省體積.表示空格0-9和A-F表示最多 16 種顏色。但這種格式的危險(xiǎn)也很直接——少一個(gè)字符、混入一個(gè)全角符號(hào)運(yùn)行時(shí)仍可能繼續(xù)解析直到編號(hào)圖出現(xiàn)錯(cuò)位、統(tǒng)計(jì)數(shù)不一致或某一行突然變短。這篇文章給《拼豆制圖》的PatternAssetCharts增加一層數(shù)據(jù)入口校驗(yàn)。目標(biāo)不是等 ArkUI 渲染異常后再排查而是在資源進(jìn)入 Harmony os 應(yīng)用時(shí)就給出圖紙 ID、行號(hào)、列號(hào)和錯(cuò)誤原因。一、壓縮格式必須先寫成契約當(dāng)前資源模型很簡(jiǎn)潔exportinterfaceAssetChart{colors:string[];previewRows:string[];chartRows:string[];}僅靠接口無法表達(dá)以下約束chartRows不得為空每一行寬度必須相同字符只能來自.、0-9、A-Ftoken 對(duì)應(yīng)的顏色索引不能超過colors.length - 1顏色必須是六位十六進(jìn)制值預(yù)覽寬高要與約定一致。這些規(guī)則應(yīng)該由一個(gè)入口統(tǒng)一執(zhí)行而不是散落在渲染代碼中。二、為校驗(yàn)結(jié)果保留位置上下文直接拋出“資源錯(cuò)誤”對(duì) 50 張圖紙幾乎沒有幫助。定義結(jié)構(gòu)化問題exportinterfaceAssetIssue{patternId:string;field:string;row:number;col:number;message:string;}exportinterfaceAssetValidationResult{valid:boolean;issues:AssetIssue[];}行列從 0 還是 1 開始要統(tǒng)一。對(duì)開發(fā)日志建議展示 1 基坐標(biāo)和編輯器行號(hào)更接近。三、第一關(guān)空數(shù)組與矩陣寬度privatestaticvalidateRows(patternId:string,field:string,rows:string[],issues:AssetIssue[]):void{if(rows.length0){issues.push({patternId,field,row:0,col:0,message:矩陣為空});return;}constexpectedWidthrows[0].length;if(expectedWidth0){issues.push({patternId,field,row:1,col:0,message:首行為空});}for(letrow0;rowrows.length;row){if(rows[row].length!expectedWidth){issues.push({patternId,field,row:row1,col:rows[row].length,message:行寬應(yīng)為${expectedWidth}實(shí)際為${rows[row].length}});}}}當(dāng)前rowWidth()只讀取第一行后續(xù)短行不會(huì)自動(dòng)補(bǔ)齊。提前拒絕不規(guī)則矩陣可以防止width × height與格子數(shù)量失配。四、第二關(guān)token 字符集privatestaticvalidateTokens(patternId:string,field:string,rows:string[],colorCount:number,issues:AssetIssue[]):void{for(letrow0;rowrows.length;row){for(letcol0;colrows[row].length;col){consttokenrows[row].charAt(col);if(token.){continue;}constindex0123456789ABCDEF.indexOf(token);if(index0){issues.push({patternId,field,row:row1,col:col1,message:非法字符${token}});}elseif(indexcolorCount){issues.push({patternId,field,row:row1,col:col1,message:顏色索引${index}超出調(diào)色板});}}}}實(shí)現(xiàn)時(shí)不要把未知字符靜默當(dāng)成空格。靜默降級(jí)會(huì)讓錯(cuò)誤圖紙看起來“只是少了幾顆豆”反而更難定位。五、錯(cuò)誤位置統(tǒng)一轉(zhuǎn)換成人類坐標(biāo)數(shù)組下標(biāo)從 0 開始而資源編輯人員習(xí)慣從第 1 行、第 1 列定位??梢园炎鴺?biāo)轉(zhuǎn)換集中到一個(gè)入口避免某條規(guī)則報(bào) 0 基坐標(biāo)、另一條規(guī)則報(bào) 1 基坐標(biāo)privatestaticaddIssue(issues:AssetIssue[],patternId:string,field:string,rowIndex:number,columnIndex:number,message:string):void{issues.push({patternId:patternId,field:field,row:rowIndex1,col:columnIndex1,message:message});}這樣日志中的第 12 行第 8 列可以直接對(duì)應(yīng)文本編輯器中的位置不需要修復(fù)人員每次手動(dòng)加一。自動(dòng)化測(cè)試則繼續(xù)向addIssue()傳入數(shù)組下標(biāo)內(nèi)部語(yǔ)義保持清楚。六、第三關(guān)顏色格式與重復(fù)色號(hào)privatestaticvalidateColors(patternId:string,colors:string[],issues:AssetIssue[]):void{constseennewSetstring();for(leti0;icolors.length;i){constvaluecolors[i].toUpperCase();if(!/^#[0-9A-F]{6}$/.test(value)){issues.push({patternId,field:colors,row:i1,col:0,message:顏色格式錯(cuò)誤${colors[i]}});continue;}if(seen.has(value)){issues.push({patternId,field:colors,row:i1,col:0,message:重復(fù)顏色${value}});}seen.add(value);}}重復(fù)顏色不一定導(dǎo)致崩潰但會(huì)讓兩個(gè)色號(hào)視覺相同用戶備料時(shí)很容易誤判因此值得作為資源問題暴露出來。七、統(tǒng)一校驗(yàn)入口staticvalidate(patternId:string,asset:AssetChart):AssetValidationResult{constissues:AssetIssue[][];AssetChartValidator.validateColors(patternId,asset.colors,issues);AssetChartValidator.validateRows(patternId,previewRows,asset.previewRows,issues);AssetChartValidator.validateRows(patternId,chartRows,asset.chartRows,issues);AssetChartValidator.validateTokens(patternId,previewRows,asset.previewRows,asset.colors.length,issues);AssetChartValidator.validateTokens(patternId,chartRows,asset.chartRows,asset.colors.length,issues);return{valid:issues.length0,issues};}Repository 只能接收valid的資源。開發(fā)構(gòu)建可以直接拋錯(cuò)線上構(gòu)建可以隱藏?fù)p壞條目并記錄 ID但不應(yīng)繼續(xù)把壞矩陣交給詳情頁(yè)。八、批量資源校驗(yàn)50 張資源適合一次性遍歷constidsPatternAssetCharts.ids();constallIssues:AssetIssue[][];for(leti0;iids.length;i){constassetPatternAssetCharts.get(ids[i]);if(asset!null){allIssues.push(...AssetChartValidator.validate(ids[i],asset).issues);}}expect(allIssues).assertEqual([]);若數(shù)據(jù)由腳本生成還應(yīng)讓生成腳本和 ArkTS 測(cè)試使用同一套 token 契約避免兩端規(guī)則逐漸偏離。九、常見問題與修復(fù)問題表現(xiàn)修復(fù)未知字符當(dāng)空格圖案缺豆但不報(bào)錯(cuò)非.的未知字符必須失敗只校驗(yàn)首行寬度中間行錯(cuò)位遍歷每一行比較寬度token 合法但無對(duì)應(yīng)顏色某色塊變白對(duì)比索引與調(diào)色板長(zhǎng)度顏色字符串解析出NaN導(dǎo)出顏色異常入口校驗(yàn)六位十六進(jìn)制問題信息要優(yōu)先服務(wù)于資源修復(fù)人員。與其只寫“圖紙非法”不如給出圖紙 ID、矩陣字段、行列位置、實(shí)際字符和允許范圍。信息越接近源數(shù)據(jù)越不需要在頁(yè)面、倉(cāng)庫(kù)和資源文件之間反復(fù)定位。十、驗(yàn)證清單空矩陣會(huì)返回明確問題。任意短行都能定位到具體行號(hào)。全角數(shù)字、空格和小寫外字符不會(huì)被吞掉。超出調(diào)色板的 token 會(huì)被拒絕。每個(gè)問題包含圖紙 ID 與字段名。批量資源測(cè)試在新增圖紙時(shí)自動(dòng)執(zhí)行。提交新資源前應(yīng)同時(shí)跑單張邊界用例和 50 張批量用例。單張用例負(fù)責(zé)證明每條規(guī)則能夠報(bào)出預(yù)期位置批量用例負(fù)責(zé)證明現(xiàn)有資源整體閉合兩者結(jié)合才不會(huì)出現(xiàn)規(guī)則本身寫錯(cuò)卻被全量數(shù)據(jù)“恰好通過”的情況。十一、總結(jié)字符矩陣壓縮了資源體積也把很多錯(cuò)誤推遲到了運(yùn)行時(shí)。為寬度、字符集、調(diào)色板和顏色格式建立統(tǒng)一入口校驗(yàn)Harmony os 應(yīng)用才能把“某張圖看起來不對(duì)”變成一條可定位、可復(fù)現(xiàn)、可阻斷的問題記錄。標(biāo)簽Harmony os、ArkTS、數(shù)據(jù)校驗(yàn)、字符矩陣、資源工程