SCSAI Object CRUD Operation Guide

SCSAI Object CRUD Operation Guide

Organized based on server/utils/SCSAI-client.js code

Applicable Objects: All SCSAI ItemTypes such as Part, Vendor, Manufacturer Part, Part BOM, Part AML, etc.


I. Initializing the 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
});

关键说明:

  • The password must be MD5-hashed and placed in the AUTHPASSWORD request header (handled internally)
  • The MD5 hash result must be in UPPERCASE
  • The password field is passed as-is; the internal _md5() function handles the hashing

II. Finding Objects (Query / Search)

Method 1: queryItems() (Recommended, for simple queries)

// 查所有 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 中字段的两种形态:

  • Regular fields: name: 'Clamp' (direct value)
  • Reference fields: source_id: 'D4F2F...' (just the ID string)
  • To expand referenced objects, use select="source_id(keyed_name,item_number)" in AML

III. Adding Objects (Create / Creation)

Method 1: createItem() (Recommended)

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)

// Create 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。


IV. Modifying Objects (Update / Edit)

Method 1: updateItem() (Recommended)

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);

警告:

  • Deletion is physical (SCSAI default does not go to recycle bin, depends on ItemType configuration)
  • Objects with cascading references may not be deletable (will throw a SOAP Fault)

VI. Adding Object Properties (Property / Fields)

If an ItemType lacks a certain field (e.g., Vendor missing contact_email), you must first create the Property definition in SCSAI, then you can write data to it.

Creating a Property via AML (adding a field to an 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 中先查到。


VII. Common Errors and Troubleshooting

Error 1: ValidateUser failure (ItemNotFoundException)

Reason: ValidateUser is not a standard SCSAI AML Item operation; it should be replaced with a User get operation:

// ❌ 错误写法
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:Password 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行已完成此修复。

Error 3: Unescaped special characters in 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 (Relation) | source_id(parent Part), related_id(child Part), quantity | — |

| Part AML (Relation) | source_id(Part), related_id(Manufacturer Part) | — |

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

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


10. Summary of Key Points

  1. Semicolon at the end of the password: gyc123456; (the semicolon is part of the password)
  2. MD5 hash must be uppercase: Fixed in SCSAI-client.js line 67
  3. AML must close all tags: Must have , must have
  4. Reference fields must specify type: ID
  5. Expand references in select: select="source_id(keyed_name,item_number)"
  6. SCSAI connection test: First, queryItems('Part', { maxRecords:1 }) to verify connectivity
← 返回案例列表

Try 左帮右臂 Industrial Agent — your digital workforce

Available as a WeChat mini program, web app (ylxt.chat) and desktop client. Start from whichever fits your workflow.

🌐 Web App 💻 Desktop Download 📞 Call 189-8606-6876
WeChat mini program QR
Scan for the WeChat mini program
Share:
🤖 Try Now →
🤖
🎁