工艺赛题优化方案:基于PLM原生版本能力的完整实现路径
2026-09-04
〇、基本原则(不可违背)
- PLM底座已具备版本能力:SCSAI/Aras 原生支持 newVersion/getHistory/rollBack 等 action,config_id/major_rev/generation/is_current 等字段。底座不缺,缺的是客户端调用层 SCSAI-client.js 未封装这些方法。 本次实现是补客户端封装,不是补底座能力。
- 七大基础能力是底座功能:识别、创建、修复、优化、比对、生成、巡检 + 复制粘贴/导入导出。任意对象(包括复杂关系的对象类)都可以通过这些能力创建、修复和优化。包括 PLM 中原生的对象类,基于业务实际都是可以优化、可以修改的。
- 不重复造轮子:任何功能扩展和实现必须首先基于上述基础能力。我们是基于 PLM 底座和七大基础能力以及一系列工具的工业智能体平台,不是拼凑出来的技能树。
- 版本管理比对必须利用 PLM 原生版本功能:将对象类设置为支持版本的对象类(is_versionable=1),工艺规程、文档等都基于 PLM 原生的版本能力去做,不手搓版本号。
实现准则
| 需求 | 正确做法 | 错误做法 |
|---|---|---|
| 创建新版本 | handleCreate(mode='newVersion') → SCSAI原生newVersion | 手搓version+1写本地表 |
| 查版本历史 | getVersionsByConfigId(config_id) | 用name查同名对象 |
| 版本比对 | compareRelations(mode='version', version_a, version_b) | 自己写diff逻辑 |
| 修正对象类属性 | system-meta-optimizer.optimizeForCreation | 手动改DB |
| 工艺规程校验 | ai-inspector五维评分 | 新写校验逻辑 |
| 对象创建/修复 | handleCreate / repair能力 | 新写CRUD |
一、已有技术基础(可直接复用)
1.1 工艺规程智能生成(已完整)
| 组件 | 文件 | 行数 | 能力 |
|---|---|---|---|
| ProcessSpecGenerator | server/core/process-spec-generator.js | 761 | 三模式generate/complete/optimize + validateAndRepair |
| ProcessDataSearchService | server/services/process-data-search.js | 200 | 按行业/材料/类型搜索工艺数据 |
| ProcessSpecKB | server/core/process-spec-kb.js | 254 | 三行业(机械/磷化工/白酒)归一化知识库 |
| BomProcessLinker | server/core/bom-process-linker.js | 180 | BOM→工艺关联 |
| 工艺知识库 | server/data/sccapp_process_data.db | 16.3万规程 | 28万工序/30万技术数据 |
1.2 关系能力层(已完整,含版本比对)
| 方法 | 文件:行号 | 能力 |
|---|---|---|
| compareRelations | relationship-capability.js:579 | 三维度版本比对(version/cross_object/cross_type) |
| _compareVersionRelations | relationship-capability.js:579-680 | 用version_a/version_b查不同版本关系,比对结构差异 |
| 路由暴露 | server/routes/relationship.js:121-136 | POST /api/relationship/compare |
1.3 基础设施(已完整)
| 组件 | 文件 | 说明 |
|---|---|---|
| 规则引擎 | server/core/rule-engine.js | 10687条规则 |
| 关系引擎 | server/core/relationship-resolver.js | RelationshipResolver |
| 巡检五维评分 | server/core/ai-inspector.js | 完整/一致/合规/时效/分布 |
| 统一创建 | server/routes/unified-create.js | handleCreate统一入口 |
| SCSAI客户端 | server/utils/SCSAI-client.js | sendAML/promoteItem/queryItems |
| 变更影响分析 | server/routes/change.js | analyzeChangeImpact(已支持工艺规程关联) |
| MES工序引擎 | server/routes/production.js | 工序创建/状态机/报工/质量检验 |
| 数字员工 | server/boss-scheduler/staff-router.js | 工艺设计/优化/同步/质量工艺互通管家 |
1.4 对象类版本化配置(已部分正确)
| 类型 | is_versionable | 来源 |
|---|---|---|
| Part | 1 | SCSAI-tools.js:272 + DB |
| Document | 1 | SCSAI-tools.js:273 + DB |
| CAD | 1 | SCSAI-tools.js:274 + DB |
| Manufacturing Order | 1 | DB |
| WorkOrder | 1 | DB |
| ECR/ECO/ECN | 0 | 正确(变更单不版本化) |
| Project | 0 | 正确 |
| Product | 0 | 冲突!SCSAI-tools.js:275定义为1,DB为0 |
二、差距分析(8个差距)
差距1:SCSAI原生版本方法完全缺失 【根因差距】
现状:SCSAI-client.js 25个方法中无任何版本方法。全代码库零调用 action="newVersion"/action="getHistory"/action="rollBack"。
影响:所有版本操作只能手搓或缺失。
文件:server/utils/SCSAI-client.js
差距2:工艺规程未用PLM原生版本
现状:
- process-spec-generator.js 生成的工艺规程无 major_rev/generation 字段
- llm-process-store.js:404-421 手搓版本自增
version = (spec.version || 1) + 1
影响:工艺规程版本无法被PLM原生管理,无法做原生版本比对。
文件:server/core/process-spec-generator.js, server/core/llm-process-store.js
差距3:文档版本手搓
现状:
- document-service.js:218-257 手搓
v1.0→v1.1版本号,自建 doc_versions 表 - SCSAI-document-service.js:188-222 createVersion 手搓 _incrementVersion
- SCSAI-document-service.js:229-258 getVersionHistory 用 name 查询(不可靠),不用 config_id
影响:文档版本与PLM原生版本脱节,无法做原生版本追溯。
文件:server/services/document-service.js, server/services/SCSAI-document-service.js
差距4:变更影响分析不用版本
现状:change.js analyzeChangeImpact 只做Where-Used反查,不用config_id查历史版本。
影响:对版本化对象(如Part),只分析当前版本,忽略历史版本可能被其他BOM引用。
文件:server/routes/change.js
差距5:统一创建无newVersion模式
现状:unified-create.js handleCreate 只支持 action="add",无newVersion模式。版本字段被列为SYSTEM_MANAGED_FIELDS过滤掉。
影响:无法通过统一入口创建对象的新版本。
文件:server/routes/unified-create.js
差距6:前端版本展示伪造
现状:
- StaffCapabilities.vue:1187-1195 loadVersions 伪造单版本列表
- ManagePanel.vue:156-161 伪造初始版本
- useCapability.js:1018-1041 查询条件用
只返回当前版本(应改用) - DocumentCenter.vue:670-687 版本号伪造
V${i+1}
影响:前端无法展示真实版本历史。
文件:src/views/StaffCapabilities.vue, src/components/data-asset/ManagePanel.vue, src/composables/useCapability.js, src/views/DocumentCenter.vue
差距7:system-meta-optimizer不处理版本
现状:system-meta-optimizer.js optimizeForCreation 不检查/修复 is_versionable。
影响:需要版本化的类型可能未被正确设置。
文件:server/core/system-meta-optimizer.js
差距8:Product类型 is_versionable 冲突
现状:DB中Product is_versionable=0,SCSAI-tools.js定义为1。
影响:Product对象无法版本化。
文件:server/data/rule_engine.db + SCSAI服务端
三、差距实现路径(具体到文件、行号、代码)
实现路径1:SCSAI-client.js 新增4个原生版本方法 【差距1,最高优先级】
在 server/utils/SCSAI-client.js 的 promoteItem 方法之后(约第493行)新增:
/**
* 创建新版本(PLM原生 action="newVersion")
* @param {string} itemType - 对象类型(必须 is_versionable=1)
* @param {string} id - 当前版本的对象ID
* @returns {Promise<SCSAIResponse>} 新版本对象
*/
async newVersion(itemType, id) {
if (!itemType || !id) {
return { success: false, items: [], fault: { code: 'PARAM', string: 'newVersion 需要 itemType/id' }, rawXml: '', count: 0 };
}
const aml = `<XJML><Item type="${itemType}" action="newVersion" id="${id}" /></XJML>`;
const res = await this.sendAML(aml);
if (res.success && res.items && res.items.length > 0) {
return res;
}
return {
success: false,
items: [],
fault: { code: 'NEW_VERSION_FAILED', string: `创建 ${itemType} 新版本失败: ${res.fault?.string || '未知错误'}` },
rawXml: res.rawXml, count: 0
};
}
/**
* 获取对象的所有版本(通过 config_id 查询)
* @param {string} itemType - 对象类型
* @param {string} idOrConfigId - 对象ID或config_id(任意版本ID均可)
* @returns {Promise<Array>} 版本列表,按 generation 降序
*/
async getVersionsByConfigId(itemType, idOrConfigId) {
// 1. 先获取 config_id(如果传入的是普通ID)
const configRes = await this.sendAML(
`<XJML><Item type="${itemType}" action="get" select="id,config_id" id="${idOrConfigId}"></Item></XJML>`
);
let configId = idOrConfigId;
if (configRes.success && configRes.items && configRes.items.length > 0) {
configId = configRes.items[0].config_id?._value || configRes.items[0].config_id || idOrConfigId;
}
// 2. 用 config_id 查所有版本
const versionsRes = await this.sendAML(
`<XJML><Item type="${itemType}" action="get" select="id,major_rev,minor_rev,generation,is_current,is_released,state,current_state,created_on,modified_on,created_by_id,modified_by_id" maxRecords="200"><config_id condition="eq">${configId}</config_id></Item></XJML>`
);
if (versionsRes.success && versionsRes.items) {
// 按 generation 降序排列(最新版本在前)
versionsRes.items.sort((a, b) => {
const genA = parseInt(a.generation?._value || a.generation || 0);
const genB = parseInt(b.generation?._value || b.generation || 0);
return genB - genA;
});
return versionsRes.items;
}
return [];
}
/**
* 获取版本历史(PLM原生 action="getHistory")
* @param {string} itemType - 对象类型
* @param {string} id - 对象ID
* @returns {Promise<SCSAIResponse>}
*/
async getVersionHistory(itemType, id) {
const aml = `<XJML><Item type="${itemType}" action="getHistory" id="${id}" /></XJML>`;
return await this.sendAML(aml);
}
/**
* 版本回滚(PLM原生 action="rollBack")
* @param {string} itemType - 对象类型
* @param {string} id - 要回滚到的目标版本ID
* @returns {Promise<SCSAIResponse>}
*/
async rollBack(itemType, id) {
const aml = `<XJML><Item type="${itemType}" action="rollBack" id="${id}" /></XJML>`;
return await this.sendAML(aml);
}
验证方法:
# 1. 语法检查
node --check server/utils/SCSAI-client.js
# 2. 运行时验证(需服务器运行)
curl.exe -X POST http://localhost:3006/api/sciot/query -H "Content-Type: application/json" -d '{"aml":"<AML><Item type=\"Part\" action=\"get\" select=\"id,config_id,major_rev,generation\" maxRecords=\"1\"><item_number>P-1001</item_number></Item></AML>"}'
# 取返回的id,调用 newVersion / getVersionsByConfigId
实现路径2:统一创建新增newVersion模式 【差距5】
在 server/routes/unified-create.js 的 handleCreate 函数中(约第1425行),新增 mode: 'newVersion' 分支:
// 在 handleCreate 函数开头,action 判断之后新增
if (mode === 'newVersion' || action === 'newVersion') {
// 1. 验证目标类型是否版本化
const typeMeta = await db.prepare('SELECT is_versionable FROM sciot_item_types WHERE name = ?').get(item_type);
if (!typeMeta || typeMeta.is_versionable !== 1) {
return { success: false, error: `类型 ${item_type} 不支持版本化(is_versionable=0),无法创建新版本` };
}
// 2. 获取当前版本ID(如果传入的是config_id或item_number)
let currentId = item_id;
if (!/^[0-9A-F]{32}$/i.test(currentId)) {
// 按item_number查找
const findRes = await scsaiClient.queryItems(item_type, `<item_number>${currentId}</item_number>`, 'id,config_id');
if (findRes.success && findRes.items.length > 0) {
currentId = findRes.items[0].id;
}
}
// 3. 调用SCSAI原生newVersion
const newVerRes = await scsaiClient.newVersion(item_type, currentId);
if (!newVerRes.success) {
return { success: false, error: newVerRes.fault?.string || '创建新版本失败' };
}
const newVersionId = newVerRes.items[0].id;
// 4. 如果有properties/relationships,edit新版本
if (properties || relationships) {
await scsaiClient.updateItem(item_type, newVersionId, properties);
// 关系创建复用现有 createRelationshipsRecursive
}
return { success: true, data: { id: newVersionId, item_type, parent_id: currentId } };
}
API暴露:在现有 POST /api/unified/create 路由中,body 新增 mode: "newVersion" 字段。
实现路径3:工艺规程基于PLM原生版本 【差距2】
#### 3a. 工艺规程对象类设为versionable
工艺规程在SCSAI中对应 PPS_Proc 类型。需确保 is_versionable=1:
// server/core/system-meta-optimizer.js optimizeForCreation 中新增
// 检查工艺相关类型是否版本化
const PROCESS_VERSIONABLE_TYPES = ['PPS_Proc', 'PPS_Operation', 'PPS_Step', 'Process Spec', 'Manufacturing Order'];
for (const typeName of PROCESS_VERSIONABLE_TYPES) {
const meta = await db.prepare('SELECT id, is_versionable FROM sciot_item_types WHERE name = ? OR keyed_name = ?').get(typeName, typeName);
if (meta && meta.is_versionable !== 1) {
// 修正为版本化
await db.prepare('UPDATE sciot_item_types SET is_versionable = 1 WHERE id = ?').run(meta.id);
// 同步到SCSAI服务端
const scsaiMeta = await scsaiClient.sendAML(`<XJML><Item type="ItemType" action="get" select="id,name,is_versionable"><name>${typeName}</name></Item></XJML>`);
if (scsaiMeta.success && scsaiMeta.items.length > 0) {
await scsaiClient.sendAML(`<XJML><Item type="ItemType" action="edit" id="${scsaiMeta.items[0].id}"><is_versionable>1</is_versionable></Item></XJML>`);
}
}
}
#### 3b. llm-process-store.js 版本创建改为原生newVersion
// server/core/llm-process-store.js 第404-421行 改造
// 原代码:手搓 version = (spec.version || 1) + 1
// 改为:
if (resolution === 'approved' && newContent) {
if (spec.SCSAI_item_id) {
// 有SCSAI对象ID → 调用原生newVersion
const scsaiClient = require('../utils/SCSAI-client').createFromGlobalConfig();
const newVerRes = await scsaiClient.newVersion('PPS_Proc', spec.SCSAI_item_id);
if (newVerRes.success) {
const newId = newVerRes.items[0].id;
// 更新新版本内容
await scsaiClient.updateItem('PPS_Proc', newId, { content: newContent, change_summary: changeSummary });
// 本地表同步
db.prepare('UPDATE llm_process_specs SET SCSAI_item_id = ?, content = ?, version = version + 1 WHERE id = ?').run(newId, contentStr, specId);
// 旧版本存历史表
db.prepare('INSERT INTO llm_process_spec_versions (spec_id, version, content, SCSAI_item_id, created_at) VALUES (?,?,?,?,?)').run(specId, spec.version, spec.content, spec.SCSAI_item_id, spec.updated_at);
}
} else {
// 无SCSAI对象 → 降级手搓(兼容旧数据)
const newVersion = (spec.version || 1) + 1;
db.prepare('INSERT INTO llm_process_spec_versions ...').run(specId, spec.version, spec.content, ...);
db.prepare('UPDATE llm_process_specs SET content = ?, version = ? WHERE id = ?').run(contentStr, newVersion, specId);
}
}
#### 3c. 工艺规程版本比对(复用compareRelations)
// 新增 API: POST /api/process-spec/compare-versions
// 在 server/routes/production.js 或新建路由中
async function compareProcessSpecVersions(req, res) {
const { item_type, version_a, version_b } = req.body;
const RelationshipCapability = require('../core/relationship-capability');
const rc = new RelationshipCapability();
const result = await rc.compareRelations({
mode: 'version',
item_id: version_a,
item_type,
version_a,
version_b
});
// result 包含: { added, removed, modified, summary }
res.json(result);
}
实现路径4:文档版本改为PLM原生 【差距3】
#### 4a. SCSAI-document-service.js createVersion 改为原生newVersion
// server/services/SCSAI-document-service.js 第188-222行 改造
async createVersion(docId, newContent, changeSummary) {
// 1. 获取当前文档的SCSAI ID
const originalDoc = await this.getDocument(docId);
if (!originalDoc || !originalDoc.SCSAI_id) {
throw new Error('文档未关联SCSAI对象,无法创建原生版本');
}
// 2. 调用SCSAI原生newVersion
const newVerRes = await this.scsaiClient.newVersion('Document', originalDoc.SCSAI_id);
if (!newVerRes.success) {
throw new Error(`创建文档新版本失败: ${newVerRes.fault?.string}`);
}
const newDocId = newVerRes.items[0].id;
// 3. 更新新版本内容
await this.scsaiClient.updateItem('Document', newDocId, {
content: newContent,
change_summary: changeSummary
});
// 4. 返回新版本信息
return {
id: newDocId,
version: newVerRes.items[0].major_rev || 'B',
generation: newVerRes.items[0].generation || 2,
parent_id: originalDoc.SCSAI_id
};
}
#### 4b. getVersionHistory 改为用config_id
// server/services/SCSAI-document-service.js 第229-258行 改造
async getVersionHistory(docId) {
const currentDoc = await this.getDocument(docId);
if (!currentDoc || !currentDoc.SCSAI_id) return [];
// 用 getVersionsByConfigId 查所有版本
const versions = await this.scsaiClient.getVersionsByConfigId('Document', currentDoc.SCSAI_id);
return versions.map(v => ({
id: v.id,
version: v.major_rev?._value || v.major_rev || 'A',
generation: parseInt(v.generation?._value || v.generation || 0),
is_current: v.is_current?._value === '1' || v.is_current === 1,
is_released: v.is_released?._value === '1' || v.is_released === 1,
state: v.state?._value || v.state || '',
created_on: v.created_on?._value || v.created_on || '',
modified_on: v.modified_on?._value || v.modified_on || ''
}));
}
实现路径5:变更影响分析增加版本维度 【差距4】
// server/routes/change.js analyzeChangeImpact 中新增版本维度
// 在 findWhereUsedRecursive 之前,新增版本影响分析
async function analyzeVersionImpact(itemType, itemId) {
const scsaiClient = require('../utils/SCSAI-client').createFromGlobalConfig();
// 1. 获取所有版本
const versions = await scsaiClient.getVersionsByConfigId(itemType, itemId);
if (versions.length <= 1) return { versions: [], impact: [] };
// 2. 对每个版本做Where-Used
const allImpacts = [];
for (const ver of versions) {
const whereUsed = await findWhereUsedRecursive(itemType, ver.id, new Set(), 0);
allImpacts.push({
version: ver.major_rev || `gen${ver.generation}`,
generation: ver.generation,
is_current: ver.is_current,
where_used: whereUsed
});
}
// 3. 汇总:找出只在历史版本中被引用、当前版本不再引用的节点
const currentVersion = versions.find(v => v.is_current == 1 || v.is_current === '1');
const currentImpact = allImpacts.find(i => i.is_current);
const historicalOnlyImpacts = allImpacts.filter(i => !i.is_current).flatMap(i => i.where_used)
.filter(item => !currentImpact || !currentImpact.where_used.some(c => c.id === item.id));
return {
versions: versions.map(v => ({ version: v.major_rev, generation: v.generation, is_current: v.is_current })),
current_impact: currentImpact?.where_used || [],
historical_only_impact: historicalOnlyImpacts, // 只在历史版本中引用的节点
all_impacts: allImpacts
};
}
实现路径6:前端版本展示改为真实查询 【差距6】
#### 6a. useCapability.js runCompare 查询条件修正
// src/composables/useCapability.js 第1018-1041行 改造
// 原代码:用 <id> 查询(只返回当前版本)
// 改为:用 <config_id> 查所有版本
const configRes = await rawQuery(`<AML><Item type="${itemType}" action="get" select="id,config_id" id="${selectedItem.value.id}"></Item></AML>`)
const configId = configItem?.config_id?._value || configItem?.config_id || selectedItem.value.id
const aml = `<AML><Item type="${itemType}" action="get" select="id,name,item_number,state,major_rev,generation,is_current,created_on,modified_on" maxRecords="200"><config_id condition="eq">${configId}</config_id></Item></AML>`
#### 6b. StaffCapabilities.vue loadVersions 改为真实查询
// src/views/StaffCapabilities.vue 第1187-1195行 改造
const loadVersions = async (itemId) => {
try {
const res = await fetch(`/api/sciot/versions?item_type=${props.itemType}&item_id=${itemId}`)
const data = await res.json()
versions.value = data.versions || []
} catch (e) {
versions.value = []
}
}
#### 6c. 新增后端版本查询API
// server.js 中新增路由
if (pathname === '/api/sciot/versions' && req.method === 'GET') {
const { item_type, item_id } = query;
const scsaiClient = require('./utils/SCSAI-client').createFromGlobalConfig();
const versions = await scsaiClient.getVersionsByConfigId(item_type, item_id);
res.end(JSON.stringify({ success: true, versions }));
}
实现路径7:system-meta-optimizer增加版本检查 【差距7】
// server/core/system-meta-optimizer.js optimizeForCreation 中新增
// 在关系类型检查之后,新增版本化检查
const VERSIONABLE_TYPES = ['Part', 'Document', 'CAD', 'Product', 'PPS_Proc', 'PPS_Operation', 'Manufacturing Order', 'WorkOrder'];
for (const typeName of VERSIONABLE_TYPES) {
const meta = await db.prepare('SELECT id, is_versionable FROM sciot_item_types WHERE name = ?').get(typeName);
if (meta && meta.is_versionable !== 1) {
await db.prepare('UPDATE sciot_item_types SET is_versionable = 1 WHERE id = ?').run(meta.id);
console.log(`[meta-optimizer] 已将 ${typeName} 设为版本化`);
}
}
实现路径8:修正Product类型 is_versionable 【差距8】
# 一次性修正
node -e "
const Database = require('better-sqlite3');
const db = new Database('server/data/rule_engine.db');
const r = db.prepare('UPDATE sciot_item_types SET is_versionable = 1 WHERE name = ?').run('Product');
console.log('Product is_versionable 修正:', r.changes, '行');
"
四、版本管理比对完整方案(基于PLM原生版本)
4.1 版本生命周期(PLM原生)
创建新对象 → generation=1, major_rev=A, is_current=1
↓
修改内容 → action="newVersion" → generation=2, major_rev=B, is_current=1 (旧版本is_current=0)
↓
发布版本 → promoteItem → state=Released, is_released=1
↓
版本比对 → compareRelations(version_a=gen1, version_b=gen2) → 三维度差异报告
↓
版本回滚 → rollBack(targetGeneration) → 目标版本变为is_current=1
4.2 工艺规程版本比对完整流程
用户选择工艺规程 → 前端调用 /api/sciot/versions 获取版本列表
↓
用户选择版本A和版本B → 前端调用 /api/relationship/compare
↓
后端 compareRelations(mode='version', version_a, version_b)
↓
三维度比对结果:
1. 关系结构差异: 新增/删除/修改的BOM行、工序行
2. 属性差异: 工艺参数变化(切削速度、进给量等)
3. 规则差异: 校验规则变化
↓
前端展示差异报告(高亮新增/删除/修改项)
4.3 文档版本比对完整流程
用户选择文档 → /api/sciot/versions 获取版本列表
↓
用户选择版本A和版本B → /api/relationship/compare (mode='version')
↓
比对结果: 关联对象差异 + 文档属性差异
↓
可选: 文本内容diff(用现有文本diff能力)
4.4 变更影响分析增加版本维度
用户选择对象 → analyzeChangeImpact
↓
新增: getVersionsByConfigId 获取所有版本
↓
对每个版本做Where-Used → 汇总影响范围
↓
标注"只在历史版本中引用"的节点(可能需要特殊处理)
五、实施优先级
| 优先级 | 路径 | 差距 | 工作量 | 依赖 |
|--------|------|------|--------|------|
| P0 | 路径1: SCSAI-client版本方法 | 差距1 | 0.5天 | 无 |
| P0 | 路径8: 修正Product is_versionable | 差距8 | 5分钟 | 无 |
| P1 | 路径2: 统一创建newVersion模式 | 差距5 | 0.5天 | 路径1 |
| P1 | 路径7: meta-optimizer版本检查 | 差距7 | 0.5天 | 无 |
| P1 | 路径6c: 后端版本查询API | 差距6 | 0.5天 | 路径1 |
| P2 | 路径3: 工艺规程原生版本 | 差距2 | 1天 | 路径1+2 |
| P2 | 路径4: 文档原生版本 | 差距3 | 1天 | 路径1+2 |
| P2 | 路径6a+6b: 前端版本展示 | 差距6 | 1天 | 路径6c |
| P3 | 路径5: 变更影响版本维度 | 差距4 | 0.5天 | 路径1 |
总工作量: 约5.5天(P0+P1约2天可完成核心链路)
六、验证计划
6.1 P0验证(路径1+8)
# 1. 语法检查
node --check server/utils/SCSAI-client.js
# 2. 运行时验证(需服务器运行)
# a. 查P-1001的config_id和当前版本
curl.exe "http://localhost:3006/api/sciot/query?aml=<AML><Item type=\"Part\" action=\"get\" select=\"id,config_id,major_rev,generation\" maxRecords=\"1\"><item_number>P-1001</item_number></Item></AML>"
# b. 调用getVersionsByConfigId查所有版本
curl.exe "http://localhost:3006/api/sciot/versions?item_type=Part&item_id=<上一步返回的id>"
# c. 调用newVersion创建新版本
curl.exe -X POST http://localhost:3006/api/unified/create -H "Content-Type: application/json" -d '{"mode":"newVersion","item_type":"Part","item_id":"<上一步返回的id>"}'
# d. 再次查版本列表,确认新版本出现
6.2 工艺规程版本比对验证
# 1. 创建工艺规程(版本A)
# 2. newVersion创建版本B,修改部分参数
# 3. 调用compareRelations比对
curl.exe -X POST http://localhost:3006/api/relationship/compare -H "Content-Type: application/json" -d '{"mode":"version","item_type":"PPS_Proc","version_a":"<版本A ID>","version_b":"<版本B ID>"}'
# 4. 验证返回的差异报告包含新增/删除/修改项
6.3 文档版本验证
# 1. 创建文档(版本A)
# 2. createVersion创建版本B
# 3. getVersionHistory查版本列表
# 4. 验证版本列表包含A和B两个版本,generation分别为1和2
BossAgents