一文搞定 AML 操作方法:从查询到创建的完整指南

一文搞定 AML 操作方法:从查询到创建的完整指南

在企业级 PLM 系统中,AML(SCSAI Markup Language)是实现自动化和集成操作的核心工具。无论你是刚接触 SCSAI 平台的新手,还是希望提升操作效率的开发者,掌握 AML 的标准化写法都能让你事半功倍。本文将从基础格式讲起,配合实际模板代码,帮你快速上手 AML 的增删改查操作。

一、AML 基础:先看懂骨架

AML 本质是一种基于 XML 的声明式语言,通过定义 节点来指定操作对象和动作。标准格式如下:

<AML>
  <Item type="[对象类型]" action="[操作类型]" [属性]>
    <!-- 对象属性 -->
  </Item>
</AML>

关键字段说明:

  • type:要操作的对象类型,如 ECRPartVendor
  • action:操作类型,支持以下四种:

| 操作 | 说明 | 典型场景 |

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

| get | 查询 | 获取对象列表或单个对象详情 |

| add | 创建 | 新增一条 ECR、Part 等 |

| edit | 编辑 | 修改对象的部分属性 |

| delete | 删除 | 根据 ID 删除对象 |

所有 AML 指令都需要包裹在 根节点中,一个请求可包含��个 操作。

二、实战模板:四类操作代码详解

接下来我们按操作类型拆解实际代码,所有模板均来自项目中的 /app/lib/aml/ 目录。你将看到如何用最少的代码实现常用业务逻辑。

2.1 查询操作(get)

查询是最频繁的操作。通常我们会封装成一个函数,接受过滤参数并返回完整的 AML 字符串。

文件位置:/app/lib/aml/queries.ts

export const queryTemplates = {
  // 查询所有 ECR,可选按状态过滤
  ecrList: (status?: string) => `
    <AML>
      <Item type="ECR" action="get" select="id,change_number,title,description,status,created_by,created_on">
        ${status ? `<status>${status}</status>` : ''}
      </Item>
    </AML>
  `,

  // 根据 ID 查询单个 ECR
  ecrById: (id: string) => `
    <AML>
      <Item type="ECR" action="get" id="${id}" select="id,change_number,title,description,status,created_by,created_on">
      </Item>
    </AML>
  `,

  // 查询 Part 列表,可按部件号过滤
  partList: (partNumber?: string) => `
    <AML>
      <Item type="Part" action="get" select="id,part_number,name,description,unit_cost,weight">
        ${partNumber ? `<part_number>${partNumber}</part_number>` : ''}
      </Item>
    </AML>
  `,

  // 查询所有供应商
  vendorList: () => `
    <AML>
      <Item type="Vendor" action="get" select="id,name,contact,phone,email,address">
      </Item>
    </AML>
  `,

  // 查询 BOM 清单,可按父零件 ID 过滤
  bomList: (partId?: string) => `
    <AML>
      <Item type="BOM" action="get" select="id,part_id,item_id,quantity,unit">
        ${partId ? `<part_id>${partId}</part_id>` : ''}
      </Item>
    </AML>
  `,
};

要点: select 属性指定返回的字段,可有效减少传输数据量。条件字段直接作为子标签传入。

2.2 创建操作(add)

创建新对象时,需要提供所有必填字段。注意用 包裹可能包含特殊字符的文本内容,避免 XML 解析错误。

文件位置:/app/lib/aml/creates.ts

export const createTemplates = {
  // 创建 ECR:必填项 change_number、title、description,默认状态为 new
  ecr: (data: { changeNumber: string; title: string; description: string }) => `
    <AML>
      <Item type="ECR" action="add">
        <change_number>${data.changeNumber}</change_number>
        <title><![CDATA[${data.title}]]></title>
        <description><![CDATA[${data.description}]]></description>
        <status>new</status>
      </Item>
    </AML>
  `,

  // 创建 Part:必填 part_number、name;可选描述、单价、重量
  part: (data: { partNumber: string; name: string; description?: string; unitCost?: number; weight?: number }) => `
    <AML>
      <Item type="Part" action="add">
        <part_number>${data.partNumber}</part_number>
        <name><![CDATA[${data.name}]]></name>
        ${data.description ? `<description><![CDATA[${data.description}]]></description>` : ''}
        ${data.unitCost ? `<unit_cost>${data.unitCost}</unit_cost>` : ''}
        ${data.weight ? `<weight>${data.weight}</weight>` : ''}
      </Item>
    </AML>
  `,

  // 创建供应商:必填 name;可选联系人、电话、邮箱、地址
  vendor: (data: { name: string; contact?: string; phone?: string; email?: string; address?: string }) => `
    <AML>
      <Item type="Vendor" action="add">
        <name><![CDATA[${data.name}]]></name>
        ${data.contact ? `<contact><![CDATA[${data.contact}]]></contact>` : ''}
        ${data.phone ? `<phone>${data.phone}</phone>` : ''}
        ${data.email ? `<email>${data.email}</email>` : ''}
        ${data.address ? `<address><![CDATA[${data.address}]]></address>` : ''}
      </Item>
    </AML>
  `,

  // 创建 BOM 行:必填 part_id(父零件)、item_id(子零件)、quantity;可选单位
  bom: (data: { partId: string; itemId: string; quantity: number; unit?: string }) => `
    <AML>
      <Item type="BOM" action="add">
        <part_id>${data.partId}</part_id>
        <item_id>${data.itemId}</item_id>
        <quantity>${data.quantity}</quantity>
        ${data.unit ? `<unit>${data.unit}</unit>` : ''}
      </Item>
    </AML>
  `,
};

注意: 创建时系统会自动生成 id,因此不需要在 AML 中指定。

2.3 编辑操作(edit)

编辑时通过 id 定位要修改的对象,只传需要变更的字段即可。

文件位置:/app/lib/aml/edits.ts

export const editTemplates = {
  // 更新 ECR:可改状态和描述
  ecr: (id: string, data: { status?: string; description?: string }) => `
    <AML>
      <Item type="ECR" action="edit" id="${id}">
        ${data.status ? `<status>${data.status}</status>` : ''}
        ${data.description ? `<description><![CDATA[${data.description}]]></description>` : ''}
      </Item>
    </AML>
  `,

  // 更新 Part:可改名称、描述、单价、重量
  part: (id: string, data: { name?: string; description?: string; unitCost?: number; weight?: number }) => `
    <AML>
      <Item type="Part" action="edit" id="${id}">
        ${data.name ? `<name><![CDATA[${data.name}]]></name>` : ''}
        ${data.description ? `<description><![CDATA[${data.description}]]></description>` : ''}
        ${data.unitCost ? `<unit_cost>${data.unitCost}</unit_cost>` : ''}
        ${data.weight ? `<weight>${data.weight}</weight>` : ''}
      </Item>
    </AML>
  `,

  // 更新供应商:可改名称、联系人、电话、邮箱、地址
  vendor: (id: string, data: { name?: string; contact?: string; phone?: string; email?: string; address?: string }) => `
    <AML>
      <Item type="Vendor" action="edit" id="${id}">
        ${data.name ? `<name><![CDATA[${data.name}]]></name>` : ''}
        ${data.contact ? `<contact><![CDATA[${data.contact}]]></contact>` : ''}
        ${data.phone ? `<phone>${data.phone}</phone>` : ''}
        ${data.email ? `<email>${data.email}</email>` : ''}
        ${data.address ? `<address><![CDATA[${data.address}]]></address>` : ''}
      </Item>
    </AML>
  `,
};

2.4 删除操作(delete)

删除最简单,只需指定 action="delete" 和对象 id

文件位置:/app/lib/aml/deletes.ts

export const deleteTemplates = {
  ecr: (id: string) => `
    <AML>
      <Item type="ECR" action="delete" id="${id}">
      </Item>
    </AML>
  `,
  part: (id: string) => `
    <AML>
      <Item type="Part" action="delete" id="${id}">
      </Item>
    </AML>
  `,
  vendor: (id: string) => `
    <AML>
      <Item type="Vendor" action="delete" id="${id}">
      </Item>
    </AML>
  `,
};

三、封装调用:让代码更优雅

在实际项目中,我们通常不会在业务代码中直接拼接 AML 字符串,而是通过统一的工具函数来执行并处理结果。例如下面的 executeAmlWithFallback 函数(位于 /app/lib/SCSAI/fallback.ts)支持主备地址切换,提升系统可用性。

import { executeAmlWithFallback } from '../SCSAI/fallback';
import { queryTemplates, createTemplates, editTemplates, deleteTemplates } from '../aml';

// 查询示例:获取所有状态为 "in_review" 的 ECR
const ecrQuery = queryTemplates.ecrList('in_review');
const ecrResult = await executeAmlWithFallback(ecrQuery);

// 创建示例:新增一个 Part
const partCreate = createTemplates.part({
  partNumber: 'P001',
  name: '电阻-10KΩ',
  description: 'SMD 0805 10KΩ ±1%',
  unitCost: 0.02,
});
const partResult = await executeAmlWithFallback(partCreate);

// 编辑示例:修改供应商手机号
const vendorEdit = editTemplates.vendor('12345', { phone: '18601921816' });
await executeAmlWithFallback(vendorEdit);

// 删除示例:删除一个 ECR
const ecrDelete = deleteTemplates.ecr('67890');
await executeAmlWithFallback(ecrDelete);

四、最佳实践总结

  1. 统一模板管理:将所有 AML 字符串放在独立的 .ts 文件中,按操作类型分模块,便于维护和复用。
  2. 使用 CDATA:任何包含特殊字符(如 <>&)的文本字段,务必用 包裹,否则会导致 XML 解析失败。
  3. 选择必要字段:查询时通过 select 指定返回列,避免一次拉取过多数据。
  4. ���误处理:调用 executeAmlWithFallback 后,需检查返回结果中的错误码或异常信息,确保操作成功。
  5. 参数化防注入:使用模板字符串动态传参时,确保参数是可信来源或经过转义,防止 AML 注入攻击(虽然 SCSAI 服务端已做处理,但前端仍应保持警惕)。

掌握以上模板和封装思路,你就能轻松实现 SCSAI 系统的自动化操作。无论是日常数据维护,还是集成开发,AML 都是你不可或缺的利器。希望这篇指南能帮你少走弯路,快速上手!

如需获取完整代码,欢迎在公众号后台回复“AML”获取项目示例。

← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁