SCSAI 对象 CRUD 操作指南

SCSAI 对象 CRUD 操作指南

基于 server/utils/SCSAI-client.js 代码整理

适用对象:Part、Vendor、Manufacturer Part、Part BOM、Part AML 等所有 SCSAI ItemType


一、初始化 SCSAIClient

const { SCSAIClient } = require('./server/utils/SCSAI-client');

const SCSAI = new SCSAIClient({
    serverUrl: 'https://ylxt.chat/scplm',
    database: 'SCPLM',
    username: 'root',
    password: 'gyc123456;',   // 注意:密码末尾有分号
    timeout: 30000
});

关键说明:

  • 密码必须经过 MD5 哈希后放在 AUTHPASSWORD 请求头(内部自动处理)
  • MD5 哈希结果必须为 大写
  • password 字段原样传入,内部调用 _md5() 处理

二、查找对象(Query / 查询)

方法1:queryItems()(推荐,简单查询)

// 查所有 Vendor(最多100条)
const res = await SCSAI.queryItems('Vendor', {
    select: 'id,name,contact_email,overall_rating',
    maxRecords: 50
});

if (res.success) {
    const vendors = res.items;  // Array<Object>
    vendors.forEach(v => console.log(v.id, v.name, v.contact_email));
}

方法2:queryItems() 带条件

// 查 approved 状态的 Vendor
const res = await SCSAI.queryItems('Vendor', {
    select: 'id,name,status,contact_email',
    where: '<status>approved</status>',
    maxRecords: 50
});

方法3:sendAML()(高级,支持复杂查询)

// 查 contact_email 不为空的 Vendor
const aml = `<AML>
  <Item type="Vendor" action="get" maxRecords="50" select="id,name,contact_email">
    <contact_email condition="is not null"></contact_email>
  </Item>
</AML>`;
const res = await SCSAI.sendAML(aml);
const vendors = res.items;

方法4:查关系对象(如 Part BOM)

// 查某个 Part 的 BOM(子件)
const parentId = 'D4F2F90F01D34399B07A0BEFEEBDCB86';
const aml = `<AML>
  <Item type="Part BOM" action="get" maxRecords="100" select="source_id,related_id,quantity">
    <source_id>${parentId}</source_id>
  </Item>
</AML>`;
const res = await SCSAI.sendAML(aml);
// res.items 中每个元素:
//   source_id = 父件 ID(或对象)
//   related_id = 子件 ID(或对象)
//   quantity = 用量

响应结构

{
    success: true,
    items: [ { id: '...', name: '...', ... } ],
    fault: null,
    rawXml: '...',
    count: 3
}

items 中字段的两种形态:

  • 普通字段:name: 'Clamp'(直接是值)
  • 引用字段:source_id: 'D4F2F...'(只是 ID 字符串)
  • 如果要展开引用对象,AML 中用 select="source_id(keyed_name,item_number)"

三、添加对象(Create / 创建)

方法1:createItem()(推荐)

const res = await SCSAI.createItem('Vendor', {
    name: '测试供应商有限公司',
    vendor_number: 'V-2026-0099',
    contact_email: 'tuan_zhang@sina.com',
    contact_name: '张经理',
    type: 'manufacturer',
    status: 'approved',
    overall_rating: '90',
    country: '中国',
    province: '广东',
    city: '深圳'
});

if (res.success) {
    const newId = res.items[0].id;
    console.log('创建成功,ID =', newId);
} else {
    console.error('创建失败:', res.fault);
}

方法2:sendAML()(高级,支持更多控制)

const aml = `<AML>
  <Item type="Vendor" action="add">
    <name>测试供应商有限公司</name>
    <vendor_number>V-2026-0099</vendor_number>
    <contact_email>tuan_zhang@sina.com</contact_email>
    <contact_name>张经理</contact_name>
    <type>manufacturer</type>
    <status>approved</status>
    <overall_rating>90</overall_rating>
  </Item>
</AML>`;
const res = await SCSAI.sendAML(aml);

创建关系对象(如 Part BOM)

// 创建 BOM 行:父件 → 子件
const aml = `<AML>
  <Item type="Part BOM" action="add">
    <source_id type="Part">D4F2F90F01D34399B07A0BEFEEBDCB86</source_id>
    <related_id type="Part">2C1DE8449A7F4B5ABC9315C770874C3A</related_id>
    <quantity>2</quantity>
  </Item>
</AML>`;
const res = await SCSAI.sendAML(aml);

关键: 引用字段(source_id、related_id)必须用 type="Part" 指定目标 ItemType。


四、修改对象(Update / 编辑)

方法1:updateItem()(推荐)

const vendorId = 'V-001';  // 要修改的 Item ID
const res = await SCSAI.updateItem('Vendor', vendorId, {
    contact_email: 'tuan_zhang@sina.com',
    overall_rating: '95',
    status: 'strategic'
});

if (res.success) {
    console.log('修改成功');
} else {
    console.error('修改失败:', res.fault);
}

方法2:sendAML()(高级)

const vendorId = 'V-001';
const aml = `<AML>
  <Item type="Vendor" action="edit" id="${vendorId}">
    <contact_email>tuan_zhang@sina.com</contact_email>
    <overall_rating>95</overall_rating>
  </Item>
</AML>`;
const res = await SCSAI.sendAML(aml);

批量修改

// SCSAI 不支持真正的批量 update,需要逐条发送
for (const v of vendors) {
    await SCSAI.updateItem('Vendor', v.id, { status: 'approved' });
}

五、删除对象(Delete / 删除)

方法1:deleteItem()(推荐)

const vendorId = 'V-001';
const res = await SCSAI.deleteItem('Vendor', vendorId);

if (res.success) {
    console.log('删除成功');
} else {
    console.error('删除失败:', res.fault);
}

方法2:sendAML()

const aml = `<AML>
  <Item type="Vendor" action="delete" id="V-001" />
</AML>`;
const res = await SCSAI.sendAML(aml);

警告:

  • 删除是物理删除(SCSAI 默认不进回收站,取决于 ItemType 配置)
  • 有级联引用的对象可能无法删除(会报 SOAP Fault)

六、添加对象属性(Property / 字段)

如果 ItemType 缺少某个字段(如 Vendor 缺少 contact_email),需要先在 SCSAI 中创建 Property 定义,然后才能写入数据。

通过 AML 创建 Property(给 ItemType 加字段)

// 给 Vendor 对象类型添加 contact_email 字段
const aml = `<AML>
  <Item type="Property" action="add">
    <name>contact_email</name>
    <label xml:lang="en">Contact Email</label>
    <data_type>string</data_type>
    <stored_length>128</stored_length>
    <is_required>0</is_required>
    <is_hidden>0</is_hidden>
    <is_indexed>0</is_indexed>
    <source_id type="ItemType">9F23A02D1E464F44A3A93A1EFB732B5C</source_id>
    <sort_order>1544</sort_order>
  </Item>
</AML>`;
const res = await SCSAI.sendAML(aml);

注意: source_id 的 value 是 Vendor 的 ItemType ID,需要从 SCSAI 中先查到。


七、常见错误与排查

错误1:ValidateUser 失败(ItemNotFoundException)

原因: ValidateUser 不是标准的 SCSAI AML Item 操作,需要用 Userget 操作代替:

// ❌ 错误写法
const aml = `<Item type="User" action="ValidateUser">...</Item>`;

// ✅ 正确写法:直接查 User
const aml = `<AML>
  <Item type="User" action="get">
    <login_name>root</login_name>
  </Item>
</AML>`;
const res = await SCSAI.sendAML(aml);

错误2:密码 MD5 哈希大小写问题

// ❌ 错误:SCSAI 要求大写
const hash = crypto.createHash('md5').update(pwd).digest('hex');
// 结果:a1b2c3d4...

// ✅ 正确
const hash = crypto.createHash('md5').update(pwd).digest('hex').toUpperCase();
// 结果:A1B2C3D4...

SCSAI-client.js 第67行已完成此修复。

错误3:XML 中有特殊字符未转义

// ❌ 错误:密码中有 & < > " ' 会破坏 XML
const aml = `<name>${v.name}</name>`;  // 如果 v.name 含 & 会报错

// ✅ 正确:用 _escapeXml() 处理
const safeName = SCSAI._escapeXml(v.name);
const aml = `<name>${safeName}</name>`;

错误4:AML 标签未正确闭合

// ❌ 错误
const aml = `<AML><Item type="Part" action="get"></AML>`;
// 缺少 </Item>

// ✅ 正确
const aml = `<AML><Item type="Part" action="get"></Item></AML>`;

八、完整示例:给 Vendor 添加 contact_email 并写入数据

const { SCSAIClient } = require('./server/utils/SCSAI-client');
const SCSAI = new SCSAIClient({
    serverUrl: 'https://ylxt.chat/scplm',
    database: 'SCPLM',
    username: 'root',
    password: 'gyc123456;',
    timeout: 30000
});

async function main() {
    // 1. 查现有 Vendor
    console.log('=== Step1: 查询现有 Vendor ===');
    let res = await SCSAI.queryItems('Vendor', {
        select: 'id,name,contact_email',
        maxRecords: 5
    });
    console.log('现有 Vendor:', JSON.stringify(res.items, null, 2));

    // 2. 创建新 Vendor(带 contact_email)
    console.log('\n=== Step2: 创建新 Vendor ===');
    res = await SCSAI.createItem('Vendor', {
        name: '演示供应商有限公司',
        vendor_number: 'V-2026-DEMO',
        contact_email: 'tuan_zhang@sina.com',
        contact_name: '演示联系人',
        type: 'manufacturer',
        status: 'approved',
        overall_rating: '88',
        country: '中国',
        province: '北京',
        city: '北京'
    });
    console.log('创建结果:', JSON.stringify(res, null, 2));

    if (res.success) {
        const newId = res.items[0].id;

        // 3. 修改刚创建的 Vendor
        console.log('\n=== Step3: 修改 Vendor ===');
        res = await SCSAI.updateItem('Vendor', newId, {
            overall_rating: '95',
            contact_email: 'tuan_zhang@sina.com'
        });
        console.log('修改结果:', JSON.stringify(res, null, 2));

        // 4. 删除测试数据
        console.log('\n=== Step4: 删除测试 Vendor ===');
        res = await SCSAI.deleteItem('Vendor', newId);
        console.log('删除结果:', JSON.stringify(res, null, 2));
    }
}

main().catch(e => console.error('错误:', e.message));

九、常用 ItemType 速查表

| ItemType | 关键字段 | 关系 |

|-----------|-----------|------|

| Part | item_number, name, cost, unit | → Part BOM, → Part AML |

| Vendor | name, vendor_number, contact_email, overall_rating | — |

| Manufacturer Part | item_number, name, unit_price, manufacturer | ← Part AML |

| Part BOM (关系) | source_id(父Part), related_id(子Part), quantity | — |

| Part AML (关系) | source_id(Part), related_id(Manufacturer Part) | — |

| ECR | item_number, title, status, priority | — |

| Change Request | item_number, title, state | — |


十、注意事项总结

  1. 密码末尾有分号gyc123456;(分号是密码的一部分)
  2. MD5 哈希必须大写:已修复在 SCSAI-client.js 第67行
  3. AML 必须闭合所有标签 必须有 必须有
  4. 引用字段要指定 typeID
  5. select 里展开引用select="source_id(keyed_name,item_number)"
  6. SCSAI 连接测试:先 queryItems('Part', { maxRecords:1 }) 验证连通性
← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁