Skills bom-sop-check
BOM与SOP对比校对技能。对比物料清单与作业指导书的物料信息,检测名称规格、位号、数量差异,在SOP文件中标注差异、追加BOM数据并生成报告。校对报告分两个表格显示(SOP独有/BOM独有)。触发场景:用户发送BOM和SOP文件要求对比校对。
install
source · Clone the upstream repo
git clone https://github.com/openclaw/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/2656255594/bom-sop-check/backups/v1.12" ~/.claude/skills/clawdbot-skills-bom-sop-check-ba1457 && rm -rf "$T"
manifest:
skills/2656255594/bom-sop-check/backups/v1.12/SKILL.mdsource content
BOM 与 SOP 校对技能
功能说明
- 解析 BOM 表提取物料信息(编码、名称、规格、数量、位号)
- 解析 SOP 表 AN-BQ 列范围提取物料信息
- 按物料编码匹配,对比名称规格、位号、数量
- 在 SOP 文件中标注差异单元格(红色/黄色)
- 将 BOM 数据追加到 SOP 新列(BS/BT/BU)
- 新增:生成校对报告工作表
- 生成差异报告并发送标注后的文件
v1.10.0 功能特性
核心功能
- BOM 数据追加:将 BOM 的名称规格、数量、位号写入 SOP 新列
- BS 列:BOM 名称规格
- BT 列:BOM 数量
- BU 列:BOM 位号
表头样式
- 第154行添加 BOM 表头
- 表头样式:加粗 + 浅蓝背景 + 边框
- 数据单元格:细边框表格效果
合并单元格支持
- 自动识别 SOP 中的合并单元格
- BOM 数据列与 SOP 格式保持一致
- 仅给有差异的物料添加 BOM 信息
校对报告工作表(v1.10 新增)
- 新增"校对报告"工作表
- 包含 BOM 独有物料列表(BOM有但SOP没有)
- 包含 SOP 独有物料列表(SOP有但BOM没有)
- 表格格式:类型、物料编码、物料名称、名称规格、数量、位号
版本历史
- v1.0:核心对比功能 + 简单标注(红/黄)
- v1.9:新增 BS/BT/BU 列、表头样式、边框、合并单元格支持
- v1.10:新增校对报告工作表
稳定性保障
文件验证
- ✅ 文件存在性检查
- ✅ 文件格式验证(必须是 .xlsx)
- ✅ 文件大小限制(≤100MB)
- ✅ Excel 格式有效性验证(ZIP 结构检查)
数据处理
- ✅ 最大行数限制(10000 行)
- ✅ 字符串长度限制(500 字符)
- ✅ 物料编码格式验证(
)\d{5}-\d{3}-\d{3} - ✅ 空值保护(None → 空字符串)
- ✅ 除零保护(分母为 0 时默认为 1)
对比逻辑
- ✅ 规范化比较(去除多余空格)
- ✅ 数量浮点误差容忍(±0.001)
- ✅ 位号分隔符兼容(逗号、中文逗号、空格)
错误处理
- ✅ 异常捕获与日志记录
- ✅ 友好错误消息
- ✅ 详细模式(
)--verbose
文件格式支持
- 直接处理.xlsx
- 自动解压后处理(支持多个文件或单个文件压缩).zip
压缩文件处理
当用户发送
.zip 文件时:
- 自动解压到临时目录
- 识别其中的 BOM 和 SOP 文件(根据文件名和内容)
- 执行对比校对
- 清理临时文件
文件识别规则
BOM 文件特征:
- 文件名包含 "BOM" 或 "物料清单"
- 列 I 含物料编码格式
XXXXX-XXX-XXX - 有父项/子项结构
SOP 文件特征:
- 文件名包含 "SOP" 或 "作业指导书"
- AN-BQ 列范围存在物料编码
文件接收处理
文件缓存目录
- 缓存路径:
/root/.openclaw/workspace-text-1-feishu-6/skills/bom-sop-check/cache/ - 状态文件:
- 记录已接收的文件信息cache/status.json
场景处理流程
场景1:同时发送多个文件
- 接收所有文件,保存到缓存目录
- 逐一识别文件类型(BOM/SOP)
- 全部识别完成后开始对比
- 完成后清理缓存
场景2:先后发送文件
- 接收第一个文件,识别类型并保存到缓存
- 更新 status.json 记录已接收文件
- 告知用户已接收 X 文件,等待 Y 文件
- 接收到第二个文件后自动开始对比
- 完成后清理缓存
场景3:单个文件包含多个工作表
- 解析所有工作表
- 自动识别哪个 sheet 是 BOM,哪个是 SOP
- 开始对比
- 完成后清理缓存
文件类型识别规则
BOM 文件特征:
- 列 I 含 "物料编码" 或数据格式为 XXXXX-XXX-XXX
- 列 J 含 "物料名称" 或 "子项物料名称"
- 列 K 含 "规格型号" 或 "子项规格型号"
- 有父项/子项结构(列 D 有父项物料编码)
SOP 文件特征:
- AN-BQ 列范围存在数据
- 列 AQ (或对应列) 含物料编码格式 XXXXX-XXX-XXX
- 通常是作业指导书格式
文件格式
BOM 文件
| 列 | 字段 | 说明 |
|---|---|---|
| I | 物料编码 | 格式:XXXXX-XXX-XXX |
| J | 物料名称 | 子项物料名称 |
| K | 规格型号 | 子项规格型号 |
| N | 用量分子 | 用于计算数量 |
| O | 用量分母 | 用于计算数量 |
| P | 备注 | 包含位号信息 |
数量计算:实际用量 = 分子(N) ÷ 分母(O),分母为空或0时默认为1
SOP 文件(作业指导书)
提取物料信息(按用户指定映射):
| 列范围 | 字段 | 实际取值 |
|---|---|---|
| AQ-AW | 物料编码 | AQ 列 |
| AX-BH | 名称规格 | AX 列 |
| BI-BN | 位号 | BI 列 |
| BO-BQ | 数量 | BO 列 |
校对逻辑
对比流程
- 物料编码匹配:BOM 列 I ↔ SOP 列 AQ
- 名称规格对比:BOM 列 J+K ↔ SOP 列 AX
- 位号对比:BOM 列 P ↔ SOP 列 BI
- 数量对比:BOM 列 N÷O ↔ SOP 列 BO
差异定义
- 名称规格差异:名称或规格型号不一致
- 位号差异:位号信息不匹配
- 数量差异:数量值不一致
输出说明
1. 差异报告
| 物料编码 | 名称 | 差异类型 | BOM内容 | SOP内容 |
|---|
差异类型:名称规格、位号、数量
2. 标注文件
标注颜色:
| 颜色 | 含义 | 应用列 |
|---|---|---|
| 🔴 红色 | 名称规格/位号/数量差异 | AX, BI, BO |
| 🟡 黄色 | 仅 SOP 中存在的物料 | AX, BI, BO |
注意:物料编码列(AQ)不标注颜色
3. BOM 数据追加(v1.1 新增)
在 SOP 文件右侧新增三列,写入对应的 BOM 数据:
| 新列 | 内容 | 说明 |
|---|---|---|
| BS | BOM 名称规格 | 方便对比名称差异 |
| BT | BOM 数量 | 方便对比数量差异 |
| BU | BOM 位号 | 方便对比位号差异 |
标注样式:
- 差异物料的 BS/BT/BU 列会标注为红色
- 仅 SOP 存在的物料不追加 BOM 数据
使用方法
步骤1:接收文件并缓存
检查 cache/status.json 状态 保存文件到 cache/ 目录 更新 status.json
步骤2:识别文件类型
根据"文件类型识别规则"判断每个文件是 BOM 还是 SOP。
步骤3:判断是否可以开始对比
- BOM 和 SOP 都已收到 → 开始对比
- 只收到一个 → 提示用户等待另一个文件
步骤4:执行对比校对
- 解析 BOM 提取 I/J/K/N/O/P 列
- 解析 SOP 提取 AN-BQ 范围内的 AQ/AX/BI/BO 列
- 按物料编码匹配并对比各字段
- 在 SOP 文件 AN-BQ 列范围内标注差异单元格
- 生成差异报告
- 发送报告和标注后的 SOP 文件
步骤5:清理缓存
- SOP 物料数据:对比完成后立即删除
,不保留sop_materials.json - BOM 物料数据:保留在
,每周提醒用户手动清理一次bom_materials.json - status.json:对比完成后重置
缓存清理策略
| 文件 | 清理时机 |
|---|---|
| sop_materials.json | 对比完成后立即删除 |
| bom_materials.json | 每周提醒用户清理 |
| compare_result.json | 对比完成后保留(作为历史记录) |
| status.json | 对比完成后重置 |
文件发送方案
优先方案:使用飞书 API 直接发送
当
message 工具或 lightclaw_upload_file 不可用时,使用飞书 API:
# 1. 获取 tenant_access_token TENANT_TOKEN=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \ -H "Content-Type: application/json" \ -d '{"app_id":"<APP_ID>","app_secret":"<APP_SECRET>"}' | jq -r '.tenant_access_token') # 2. 上传文件 FILE_KEY=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/files" \ -H "Authorization: Bearer $TENANT_TOKEN" \ -F "file_type=xlsx" \ -F "file_name=<文件名>.xlsx" \ -F "file=@<本地文件路径>" | jq -r '.data.file_key') # 3. 发送文件消息 curl -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id" \ -H "Authorization: Bearer $TENANT_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"receive_id\":\"<用户open_id>\",\"msg_type\":\"file\",\"content\":\"{\\\"file_key\\\":\\\"$FILE_KEY\\\"}\"}"
备用方案:使用 message 工具
{ "action": "send", "channel": "feishu", "filePath": "/path/to/file.xlsx", "message": "文件说明" }
并发处理方案(v1.11 新增)
问题背景
当多个用户同时请求校对时,单进程会导致排队等待。
解决方案:Sub-Agent 并行处理
使用
sessions_spawn 为每个校对任务启动独立子代理:
用户A请求 ──► spawn sub-agent A ──► 独立进程处理 ──► 完成通知 用户B请求 ──► spawn sub-agent B ──► 独立进程处理 ──► 完成通知 用户C请求 ──► spawn sub-agent C ──► 独立进程处理 ──► 完成通知
使用方法
当收到用户的 BOM 和 SOP 文件后,使用以下流程:
- 保存文件到缓存目录
- 启动 sub-agent 处理:
# 使用 sessions_spawn 启动后台任务 sessions_spawn( task=f"执行 BOM/SOP 校对任务。BOM文件: {bom_path}, SOP文件: {sop_path}。运行命令: python3 {script_dir}/background_compare.py {bom_path} {sop_path}", runtime="subagent", mode="run", timeout_seconds=300 # 5分钟超时 )
- 立即回复用户:"任务已提交,正在后台处理,完成后会通知您"
- sub-agent 完成后:自动发送结果给用户
并发能力
| 用户数 | 处理方式 | 预期效果 |
|---|---|---|
| 1-2 人 | 主进程处理 | 即时响应 |
| 3-5 人 | Sub-Agent 并行 | 每人独立处理,互不阻塞 |
| 5+ 人 | Sub-Agent + 任务队列 | 建议增加任务队列管理 |
后台处理脚本
scripts/background_compare.py - 独立运行的校对脚本,无需依赖主进程上下文。
注意事项
- 标注范围限制:仅在 AN-BQ 列范围内标注,不影响其他列
- 数量精度:分子÷分母结果为整数显示整数,否则保留两位小数
- 防除零:分母为空或0时默认为1
- 文件名保持:输出文件名与原始 SOP 文件名一致
- 大文件上传:超过 20MB 的文件可能上传超时,需设置足够超时时间(--max-time 120)
- 并发处理:多用户同时使用时,自动使用 Sub-Agent 并行处理