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
- Semicolon at the end of the password: gyc123456; (the semicolon is part of the password)
- MD5 hash must be uppercase: Fixed in SCSAI-client.js line 67
- AML must close all tags: Must have , must have
- Reference fields must specify type: ID
- Expand references in select: select="source_id(keyed_name,item_number)"
- SCSAI connection test: First, queryItems('Part', { maxRecords:1 }) to verify connectivity
BossAgents