# 从 sample-data 生成 .opc 数据包 (zip: catalog.json + assets) # 用法: powershell -NoProfile -ExecutionPolicy Bypass -File tools\make-opc.ps1 # 注: M2 起由 Builder 在维护入口内完成此步骤; 本脚本为 M1 的临时打包器。 # catalog.json 手工拼接 (PS 哈希表直接交给 .NET 序列化器会有 PSObject 循环引用问题)。 param( [string]$DataDir = (Join-Path $PSScriptRoot '..\..\sample-data\onb-sc'), [string]$Out = (Join-Path $PSScriptRoot '..\sample\SampleCatalog_2026.08.opc') ) Add-Type -AssemblyName System.IO.Compression.FileSystem $csv = Join-Path $DataDir 'params.csv' if (-not (Test-Path $csv)) { Write-Output "找不到 $csv"; exit 1 } # 1) 变体 (来自参数表): SC + MAQ 两个系列 $varJson = @() foreach ($row in (Get-Content $csv | Select-Object -Skip 1)) { if ([string]::IsNullOrWhiteSpace($row)) { continue } $c = $row.Split(',') $varJson += ('{"modelCode":"' + $c[0] + '","params":{"bore":' + $c[1] + ',"stroke":' + $c[2] + ',"magnet":"' + $c[3] + '","mount":"' + $c[4] + '"},"step":"step/' + $c[5] + '"}') } $varJsonM = @() foreach ($row in (Get-Content (Join-Path $DataDir 'params_maq.csv') | Select-Object -Skip 1)) { if ([string]::IsNullOrWhiteSpace($row)) { continue } $c = $row.Split(',') $varJsonM += ('{"modelCode":"' + $c[0] + '","params":{"bore":' + $c[1] + ',"stroke":' + $c[2] + ',"magnet":"' + $c[3] + '","mount":"' + $c[4] + '"},"step":"step/' + $c[5] + '"}') } # 2) 系列元数据 — 与 sample-data\onb-sc\coding-rules.md 保持一致 $paramsJson = @( '{"code":"bore","nameZh":"缸径","nameEn":"Bore","unit":"mm","type":"number","keywords":"gangjing qigang","values":[16,25,32,40],"display":{}}', '{"code":"stroke","nameZh":"行程","nameEn":"Stroke","unit":"mm","type":"number","keywords":"xingcheng","values":[25,50,75,100],"display":{}}', '{"code":"magnet","nameZh":"磁石","nameEn":"Magnet","unit":"","type":"enum","keywords":"cishi","values":["","S"],"display":{"":"无 None","S":"带磁石 S"}}', '{"code":"mount","nameZh":"安装方式","nameEn":"Mounting","unit":"","type":"enum","keywords":"anzhuang","values":["FA","LB","CB"],"display":{"FA":"前法兰 FA","LB":"脚座 LB","CB":"中摆 CB"}}' ) $rulesJson = @( '{"If":{"Param":"bore","Op":"eq","Value":16},"Then":{"Param":"stroke","Op":"in","Value":[25,50]}}', '{"If":{"Param":"magnet","Op":"eq","Value":"S"},"Then":{"Param":"bore","Op":"in","Value":[25,32,40]}}', '{"If":{"Param":"mount","Op":"eq","Value":"CB"},"Then":{"Param":"stroke","Op":"in","Value":[25,50,75]}}' ) $attJson = @( '{"kind":"dimDrawing","lang":"zh","path":"docs/dim-drawing/SC32x50S-LB.png","model":"SC32x50S-LB"}', '{"kind":"dimDrawing","lang":"zh","path":"docs/dim-drawing/SC16x25-FA.png","model":"SC16x25-FA"}', '{"kind":"datasheet","lang":"zh","path":"docs/datasheet/SC_datasheet_zh.pdf"}', '{"kind":"datasheet","lang":"en","path":"docs/datasheet/SC_datasheet_en.pdf"}' ) # MAQ 系列元数据 (迷你气缸, 无附件) $paramsJsonM = @( '{"code":"bore","nameZh":"缸径","nameEn":"Bore","unit":"mm","type":"number","keywords":"gangjing","values":[6,10,16],"display":{}}', '{"code":"stroke","nameZh":"行程","nameEn":"Stroke","unit":"mm","type":"number","keywords":"xingcheng","values":[10,20,30,40],"display":{}}', '{"code":"magnet","nameZh":"磁石","nameEn":"Magnet","unit":"","type":"enum","keywords":"cishi","values":["","S"],"display":{"":"无 None","S":"带磁石 S"}}', '{"code":"mount","nameZh":"安装方式","nameEn":"Mounting","unit":"","type":"enum","keywords":"anzhuang","values":["FA","LB"],"display":{"FA":"前法兰 FA","LB":"脚座 LB"}}' ) $rulesJsonM = @( '{"If":{"Param":"bore","Op":"eq","Value":6},"Then":{"Param":"stroke","Op":"in","Value":[10,20]}}', '{"If":{"Param":"magnet","Op":"eq","Value":"S"},"Then":{"Param":"bore","Op":"in","Value":[10,16]}}' ) $seriesJsonM = '{"code":"MAQ","nameZh":"MAQ 系列迷你气缸","nameEn":"MAQ Series Mini Cylinder","keywords":"mini minixing qigang","parameters":[' + ($paramsJsonM -join ',') + '],"rules":[' + ($rulesJsonM -join ',') + '],"naming":{"stepNameTemplate":"{model}.step"},"attachments":[],"variants":[' + ($varJsonM -join ',') + ']}' $json = '{"schemaVersion":"1.0","catalogName":"欧霓博气动目录","catalogNameEn":"OUNIBO Pneumatic Catalog",' + '"catalogVersion":"2026.08","defaultLang":"zh","langs":["zh","en"],' + '"categories":[{"code":"ACT","nameZh":"气动执行元件","nameEn":"Pneumatic Actuators","series":["SC","MAQ"]}],' + '"series":[{"code":"SC","nameZh":"SC 系列标准气缸","nameEn":"SC Series Standard Cylinder",' + '"parameters":[' + ($paramsJson -join ',') + '],' + '"rules":[' + ($rulesJson -join ',') + '],' + '"naming":{"stepNameTemplate":"{model}.step"},' + '"attachments":[' + ($attJson -join ',') + '],' + '"variants":[' + ($varJson -join ',') + ']},' + $seriesJsonM + ']}' # 3) 组装临时目录 → zip $tmp = Join-Path $env:TEMP ('opc_' + [Guid]::NewGuid().ToString('N')) New-Item -ItemType Directory -Force -Path $tmp | Out-Null Copy-Item -Recurse -Force (Join-Path $DataDir '*') $tmp | Out-Null [System.IO.File]::WriteAllText((Join-Path $tmp 'catalog.json'), $json, (New-Object System.Text.UTF8Encoding($true))) $outDir = Split-Path $Out New-Item -ItemType Directory -Force -Path $outDir | Out-Null if (Test-Path $Out) { Remove-Item $Out -Force } [System.IO.Compression.ZipFile]::CreateFromDirectory($tmp, $Out) Remove-Item -Recurse -Force $tmp Write-Output ("数据包: " + $Out + " (" + $varJson.Count + " 个变体, catalog.json " + $json.Length + " 字节)")