# bypos-collector 按条码批量采集商品档案的小工具(单文件 Windows/Linux 程序,自带本地 Web 控制台)。 数据来源是云店「新增商品」输入条码时所查的同一个中心商品库 `zc.bypos.net`。 采集结果落地为 JSONL,供后续导入本项目(天工/goods)。 > 这是一个**独立模块**(有自己的 `go.mod`),与 `api/` 主服务互不影响, > CI 不会编译它。放在 `tools/` 下仅作代码留存与后期迭代。 ## 目录 | 文件 | 说明 | | --- | --- | | `main.go` | 入口:本地 HTTP 服务 + 启动浏览器 + API 路由(start/stop/stats/download/export.csv) | | `collect.go` | 核心:签名、EAN-13 校验位、范围/清单枚举、并发+限速、JSONL 落库、断点续采 | | `web/index.html` | 内嵌(`go:embed`)的控制台界面 | | `build.sh` | 交叉编译出 `bypos-collector.exe`(windows/amd64)与 linux 测试二进制 | | `使用说明.md` | 面向使用者的操作说明 | ## 构建 ```bash ./build.sh # 产物:bypos-collector.exe(发给 Windows 用户)/ bypos-collector-linux(本地测试) ``` 二进制与采集产物(`*.jsonl`/`*.csv`)已在 `.gitignore` 中排除,不入库。 ## 接口与签名(逆向所得,后期迭代参考) 云店新增商品页输入条码时,前端经服务端代理 `/prod-api/ZmSvr/httpUtil/getGet` 转发到中心库: ``` GET http://zc.bypos.net/byGoodsService/byMessage.asmx/GetGoodsinfo ?sdogid=<账号id>®num=1&barcode=<条码> &sparm1= # 常量,随账号固定 &sparm2= # tsMs = 当前秒*1000(末尾恒为 000) &sparm3= &sparm4=&barcodetype=yunpos ``` 返回 `{...json...}`,内层 JSON 字段: | 上游字段 | 含义 | 归一化字段 | | --- | --- | --- | | item_name | 品名 | name | | item_size | 规格 | spec | | unit_no | 单位 | unit | | item_area | 产地/地区 | area | | birth_com | 生产企业(常空) | manufacturer | | birth_doc | 生产许可(常空) | license | | inprice | 建议进价 | in_price | | sellprice | 建议零售价 | sell_price | | retcode | 1=命中,0=失败 | status(hit/miss/invalid) | `retmsg` 含「非国标条码 / 参数异常」=> invalid;含「条码不存在」=> miss。 ## 配置 - `sdogid`:中心库账号 id(本项目所属云店账号的授权 id)。 优先从环境变量 `BYPOS_SDOGID` 读取,其次是命令行 `-sdogid` 参数, 也可以在 Web 控制台的输入框中填写。**三者都未设时启动会警告、开始采集时会报错。** - 网络错误自动重试(最多 3 次,指数退避 500ms/1s/2s)。 ## 导入 goods/天工库 采集得到的 JSONL 用 ingestion 里的导入任务入库(只导入 `status=hit` 的记录, 按 GTIN 去重 upsert,重复导入幂等): ```bash cd ingestion python -m opengoods.jobs.import_bypos --input products.jsonl # 可选:--limit N 限制条数;--dsn 指定数据库 ``` 字段映射:`barcode→gtin`、`name→name`、`spec`(可解析的质量/体积如 500mL/5kg) `→net_content`、其余规格/单位/产地/许可/进价留存到 `attributes`、`sell_price→` CNY MSRP 快照。来源记为 `bypos中心库`,带字段级 provenance。 ## 注意 批量自动查询比页面逐条更"重",上游可能对账号限频。请低速、分前缀/品类分批采集。