SCIOT 对象创建 — 字段处理实现文档

SCIOT 对象创建 — 字段处理实现文档

基于 SCIOT-AML-Basic-Settings-Reference.md + 代码实现 + 数据库模板配置

最后更新: 2026-06-03


目录

  1. 字段分类框架
  2. 系统字段清单
  3. 编号字段(Sequence)处理
  4. 数据类型清洗规则
  5. 关系对象处理
  6. 各类型模板配置
  7. 前端代码字段处理流程
  8. 脚本自动生成规则
  9. 常见问题与陷阱

1. 字段分类框架

每个业务对象类型的字段分为三类:

| 分类 | 含义 | 数据来源 | 验证规则 |

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

| llm_fields | LLM 可以生成的字段 | LLM 根据用户描述推断 | 必须经过白名单过滤 + 数据类型清洗 |

| auto_fields | 系统自动填充的字段 | Sequence / 默认值 / SCSAI server 回调 | 不参与 LLM 生成,但前端会补充默认值 |

| system_fields | 系统元字段 | SCSAI 自动管理 | 完全从前端逻辑排除 |

分类算法(batch-import-templates.js classifyFields)

优先级从高到低:

  1. 系统字段 → auto(SYSTEM_FIELDS 硬编码列表)
  2. **keyed 且 *_number → auto(自动编号,如 item_number
  3. keyed 但非 *_number → llm(用户提供,如 name
  4. readonly=1 → auto
  5. item/foreign/sequence 数据类型 → auto(如 wbs_iddefault_currency
  6. 特殊模式** → auto(_id, percent_, has_change_pending, hc_copied_*
  7. 其余字段 → llm

对应代码位置

  • 分类算法: scripts/batch-import-templates.js:172-229
  • 前端白名单: src/views/StaffCapabilities.vue:1603-1613
  • auto 字段补充默认值: src/views/StaffCapabilities.vue:1616-1638

2. 系统字段清单

以下字段永远属于 auto_fields,不由 LLM 生成:

SCSAI 元字段

id, config_id, created_by_id, created_on, modified_by_id, modified_on
permission_id, keyed_name, current_state, state
major_rev, minor_rev, generation, new_version
is_current, is_released, locked_by_id, team_id
managed_by_id, owned_by_id
classification, css, not_lockable
from_project_id, from_template

编号字段(从 is_keyed 自动识别)

item_number           — Part, Document, CAD, ECR, ECN, PR, Manufacturer Part, Product
project_number        — Project
login_name            — User
pop_po_no             — Purchase Order
pop_invoice_no        — Bill Received
sop_order_no          — Sales Order
sop_invoice_no        — Tax Invoice, Commercial Invoice
stk_code              — Stock
...(所有以 _number 结尾的 keyed 字段)

特殊字段

// 前端硬编码系统字段(src/views/StaffCapabilities.vue:1194-1201)
const systemFields = [
  'id','config_id','created_by_id','created_on','modified_by_id','modified_on',
  'permission_id','keyed_name','current_state','state',
  'major_rev','minor_rev','generation','new_version',
  'is_current','is_released','locked_by_id','team_id',
  'classification','css','not_lockable',
  'managed_by_id','owned_by_id','llm_configuration','from_project_id','from_template',
  // 计算字段(只读,不能写入)
  'rollup_percent_compl','rollup_cost','rollup_hours','effort','duration',
  'wbs_number','wbs_short_name'
]

3. 编号字段(Sequence)处理

3.1 SCSAI Sequence 配置

参考 SCIOT-AML-Basic-Settings-Reference.md §3.6:

| 序列名称 | 类型 | prefix | initial_value | step | pad_to | suffix |

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

| Default Part | Part | - | 100000 | 1 | - | -001 |

| Default Document | Document | - | 100000 | 1 | - | - |

| CAD Document | CAD | CAD- | 0 | 1 | 8 | - |

| ECR | ECR | - | 1 | 1 | - | - |

| ECN | ECN | - | 1 | 1 | - | - |

| PR | Problem Report | - | 1 | 1 | - | - |

| Project Number | Project | - | 1 | 1 | - | - |

3.2 前端 Sequence 获取逻辑

位置: src/views/StaffCapabilities.vue:1506-1545

1. 对每个 keyedField:
   a. 从 generation_rules.sequence_field 取配置的 Sequence 名
   b. 无配置时从字段名推断(item_number → "{ItemType} Number")
   c. GET Sequence → 读取 current_value
   d. current_value + 1 → EDIT Sequence
   e. 3 次重试(GET+EDIT 是独立操作,需乐观锁)
2. 成功 → 用 Sequence 值覆盖 LLM 值
3. 失败但 LLM 提供了值 → 保留 LLM 值
4. 失败且字段必填 → 生成 AUTO-{timestamp} 保底值
5. 失败且字段非必填 → 删除该字段

3.3 无 Sequence 配置时的处理

  • configuredSeqField 只在 generation_rules.sequence_name 存在时才匹配 keyed_field
  • 如果无 sequence_namename 等用户提供的 keyed 字段不会被误判为 Sequence 字段
  • 字段值直接保留 LLM/用户提供的值(不会被删除)

4. 数据类型清洗规则

位置: src/utils/rule-validator.js:filterAndSanitize

| SCSAI 类型 | 清洗规则 | 无效值处理 |

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

| string / text / ml_string | 保留原值 | - |

| integer | parseInt() | → 0 |

| decimal | parseFloat() | 非数值 → 0 |

| float | parseFloat() | 非数值 → 0 |

| boolean | Yes/No/true/false/1/0 | → '1' 或 '0' |

| date | 保留 ISO 格式 | 保留原值 |

| list | 保留字符串(值与可选值列表匹配最佳) | 保留原值 |

| color list | 同上 | 同上 |

| item / foreign | 特殊处理(见 item_properties) | 移出 properties |

| sequence | 特殊处理 | 移出 properties |

对应代码

// src/utils/rule-validator.js:185-225
function sanitizeProperties(props, propDefs) {
  for (const [key, value] of Object.entries(props)) {
    const def = propDefs.find(p => p.name === key)
    if (!def) continue
    switch (def.data_type) {
      case 'integer':
        sanitized[key] = parseInt(value, 10) || 0
        break
      case 'decimal': case 'float':
        const num = parseFloat(value)
        sanitized[key] = isNaN(num) ? 0 : num
        break
      case 'boolean':
        if (['yes','y','true','1',1,true].includes(value)) sanitized[key] = '1'
        else sanitized[key] = '0'
        break
      default:
        sanitized[key] = value
    }
  }
}

5. 关系对象处理

5.1 关系格式标准化

LLM 可能返回三种格式:

// 格式 A(标准数组)
{"relationships": [{"relationship_type": "Part BOM", "related_items": [...]}]}

// 格式 B(对象键名)
{"relationships": {"Part BOM": {"related_items": [...]}}}

// 格式 C(related_id 包装)
{"relationships": [{"relationship_type": "Part BOM", "related_id": {"id": "..."}}]}

代码统一在 StaffCapabilities.vue:1976-1991 标准化为格式 A。

5.2 关系类型名解析

LLM 可能使用完整的关系显示名(如 "ECR Affected Item → Affected Item (Affected Items)"),

代码提取 前的名称与 relTypes 匹配。

5.3 related_item_type 覆盖

LLM 经常把 related_item_type 写成关系名(如 "Part BOM"),

代码从 relTypes 查找到正确的目标类型(如 "Part")并覆盖。

5.4 子对象字段处理

对于关系中的每个子对象:

  1. WBS Element → 预创建后通过 ID 引用(不能 inline 创建)
  2. 所有类型 → 基于 subTypeTemplates 的 schema:
  • 移除目标类型不存在的字段
  • 为必填 keyed 字段生成保底值(AUTO-{ts}-{rand}
  • 补充 hidden 字段的默认值

6. 各类型模板配置

6.1 Part (零件)

配置项
keyed_fielditem_number
sequence_fielditem_number
sequence_namePart Number
llm_fieldsname, description, cost, make_buy, unit, weight, weight_basis, cost_basis, related_projects, indexed_on (10 个)
auto_fieldsitem_number, major_rev, classification, state, superseeded_date, external_, thumbnail, variant_, has_change_pending, hc_copied_from, allow_team_change_logic (12 个)

6.2 Document (文档)

配置项
keyed_fielditem_number
sequence_fielditem_number
sequence_nameDocument Number
llm_fieldsname, description, is_template, related_projects, authoring_tool_version, drawing_size, scale, specification_type (8 个)
auto_fieldsitem_number, major_rev, has_files, has_files_icon, classification, state, superseeded_date, has_change_pending, allow_team_change_logic, external_*, from_template, thumbnail (14 个)

6.3 ECR (工程变更请求)

配置项
keyed_fielditem_number
sequence_fielditem_number
sequence_nameECR Number
llm_fieldstitle, description, basis, proposed_solution, fast_track, release_date, priority, change_type, requested_by, source, change_admin, technical_review, problem_status, solution, routing, implementation_timing, implementation_priority, ecr_comments (18 个)
auto_fieldsitem_number, state, low_nonrecurring_cost, nonrecurring_cost, recurring_cost, recurring_cost_direction (6 个)

6.4 Project (项目)

配置项
keyed_fieldproject_number
sequence_fieldproject_number
sequence_nameProject Number
default_propertiesscheduling_type=Forward, scheduling_mode=1, project_update_mode=1, update_method=Actual
llm_fieldsname, description, goals, scheduling_type, comments, owned_by_id (6 个)
auto_fieldsproject_number, date_, state, status_, percent_compl_*, wbs_id, owned_by_id, scheduling_method, update_method, scheduling_mode, project_update_mode, from_project_id, from_template, llm_configuration, rollup_percent_compl (33 个)

6.5 Vendor (供应商)

| 配置项 | 值 |

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

| keyed_field | name |

| llm_fields | name, description, contact_name, main_phone, main_fax, address, city, address_state, zip_code, country, web_site (11 个) |

| auto_fields | state, default_currency (2 个) |

注意:Vendor 的 name 同时是 keyed_field 和 llm_field。因为 title 不是 *_number,脚本不会把它归为 auto。

6.6 Contact (联系人)

配置项
llm_fieldsfirst_name, last_name, title, company, main_phone, email, cell_num, fax_num, address_1, address_2, city, zip_code, country, notes, job_role (15 个)
auto_fieldsstate_location (1 个)

6.7 Manufacturer Part (制造商零件)

配置项
keyed_fielditem_number
sequence_fielditem_number
sequence_nameManufacturer Part Number
llm_fieldsname, description, manufacturer, unit_price, unit (5 个)
auto_fieldsitem_number, state, has_files (3 个)

6.8 CAD (CAD文档)

配置项
keyed_fielditem_number
sequence_fielditem_number
sequence_nameCAD Document
llm_fieldsdescription, name, is_standard, allow_team_change_logic, authoring_tool_version, external_owner, external_type, related_projects, thumbnail, x_max, x_min, y_max, y_min, z_max, z_min, superseeded_date (17 个)
auto_fieldsexternal_id, from_template, has_change_pending, monolithic_model_file, native_file, shattered_model_file, view_file, viewable_file, item_number, classification, created_by_id, created_on, current_state, generation, locked_by_id, major_rev, managed_by_id, modified_by_id, modified_on, owned_by_id, state (21 个)

6.9 Product (产品)

配置项
keyed_fielditem_number
sequence_fielditem_number
sequence_nameProduct Number
llm_fieldsdescription, item_number, name (3 个)
auto_fields(无)

6.10 Manufacturer (制造商)

配置项
keyed_fieldname
llm_fieldsname, description, email, account_no, account_no_icon, address, address_state, city, contact_name, country, field, has_files, has_files_icon, main_fax, main_phone, remarks, web_site, zip_code (18 个)
auto_fieldsitem_folder_template_id, top_item_folder_id, state (3 个)

6.11 Customer (客户)

配置项
llm_fieldsaddress, address_state, city, contact_name, country, description, email, is_credit, main_fax, main_phone, web_site, zip_code, name (13 个)
auto_fieldsdefault_currency (1 个)

6.12 WBS Element (WBS 节点)

配置项
llm_fieldscpi, spi, earned_value, planned_value, rollup_work_est, rollup_actual_work, rollup_work_est_curr, deliv_required, is_top, name, prev_item, proj_num, rpn, wbs_index (14 个)
auto_fieldsrollup_date_sched_due, rollup_date_sched_start, rollup_duration, rollup_percent_compl, rollup_status (5 个)

6.13 Activity2 (项目活动)

配置项
llm_fieldsactual_work, cpi, date_, deliv_required, Deliverable, description, earned_value, expected_duration, is_critical, is_required, lead_role, message, name, orig_duration, planned_value, prev_item, proj_index, proj_num, rollup_, signoff_required, spi, work_est, work_est_curr, x, y (37 个)
auto_fieldsdate_activated, date_due_original, date_ef, date_es, date_lf, date_ls, is_milestone, percent_compl, status, managed_by_id, owned_by_id (11 个)

7. 前端代码字段处理流程

完整流程(按执行顺序):

1. 获取 Schema(/api/aml/unified/schema/:itemType)
   ├─ properties: 所有字段定义(含 data_type, is_keyed, is_required, is_hidden, default_value)
   ├─ llmFields: LLM 可生成字段
   ├─ autoFields: 系统自动填充字段
   ├─ rules: 验证规则
   └─ template: 模板配置(generation_rules, keyed_field)

2. 构建 Prompt → 发送给 LLM
   ├─ 只包含 llmFields 中的字段
   ├─ 包含字段名称、类型、可选值(list 值)
   └─ 包含 relationship_types

3. 解析 LLM 响应
   ├─ 提取 JSON payload
   ├─ 标准化 relationships 格式
   └─ 构建 mainValues + relationships

4. 编号字段处理(keyedFields 循环)
   ├─ 有 Sequence 配置 → 获取 Sequence 值
   ├─ 无 Sequence 但 LLM 有值 → 保留 LLM 值
   ├─ 无 Sequence 且字段必填 → 生成 AUTO 保底
   └─ 无 Sequence 且字段非必填 → 跳过

5. 字段过滤 + 数据类型清洗(filterAndSanitize)
   ├─ 只保留 validPropNames 中的字段
   ├─ 清洗 integer/decimal/float/boolean
   └─ 移除 null/undefined/空字符串

6. 补充 auto 字段默认值
   ├─ 有 default_value 且 LLM 未生成 → 补充
   └─ generation_rules.default_properties → 补充

7. 安全网:必填 keyed 字段缺失 → 生成 AUTO 保底

8. 处理 item_properties(Item 类型字段)
   └─ 需要预创建的嵌套 Item(如 wbs_id)

9. 关系处理(每个子对象)
   ├─ WBS Element → 预创建 + ID 引用
   ├─ 移除无关字段(基于子类型 schema)
   ├─ 必填 keyed 字段 → AUTO 保底
   └─ hidden 字段 → 补充默认值

10. 规则验证(rules)
    └─ required / pattern / min / max

11. 构建 AML → 提交 SCSAI

12. AI 自动纠错重试(最多 3 次)
    └─ 解析错误 → 发给 LLM 修正 → 重试

8. 脚本自动生成规则

scripts/batch-import-templates.js 自动处理 16 个核心业务类型:

Part, Product, Document, ECR, ECN,
Manufacturer Part, Manufacturer, Vendor, Customer, CAD,
Change Controlled Item, Project, Activity2,
WBS Element, Deliverable, Program

生成步骤

1. 从 SCIOT/SCIOT/{module}/Import/ItemType/{name}.xml 提取属性
2. classifyFields() → 按优先级分类 llm / auto
3. buildGenerationRules() → 检测 keyed *_number 生成 sequence 配置
4. extractLifecycleStartState() → 从 Life Cycle Map XML 提取初始状态
5. 写入 sciot_templates 表(UPDATE 或 INSERT)

防止覆盖

脚本 UPDATE 时覆盖 llm_fieldsauto_fieldsgeneration_ruleskeyed_field

手工修改 sciot_import.db 后如果重新运行脚本会覆盖。解决方案:

  • 已实现: 脚本的 classifyFieldsbuildGenerationRules 已修正,自动生成正确的值
  • 备份: sciot_import.db.backup_20260603 包含手工调整后的完整数据
  • 通过 API 保存: 前端有 /api/aml/sciot/update-template-fields 端点可以持久化

9. 常见问题与陷阱

9.1 name 字段被删除

原因: name 是 keyed 字段(is_keyed=1),旧脚本归类为 auto_fields。在代码中进入 Sequence 处理分支。

由于无 Sequence 配置,进入 else 分支被删除。

修复要点:

  • 脚本: 只把 *_number 的 keyed 字段归为 auto(batch-import-templates.js:191-194
  • 代码: configuredSeqFieldsequence_name 时不匹配 keyed_field(StaffCapabilities.vue:1493
  • 代码: 无 Sequence 的 keyed 字段保留 LLM 值(StaffCapabilities.vue:1583-1585

9.2 item_number 为 NULL(sub-item Part)

原因: 子 Part 是 inline 创建(通过 Part BOM 关系),代码没有为其生成 item_number

修复: 子对象处理循环中,基于 subTypeTemplates 为所有必填 keyed 字段生成保底值。

9.3 cost: "High" 导致 PropertyValueFormatException

原因: cost 是 decimal 类型,LLM 生成字符串 "High"。

修复: sanitizeProperties 对 decimal/float 做 parseFloat + isNaN 检查,非数值 → 0。

9.4 ID: undefined

原因: parseSCSAIResponseresult.Item 设为数组,但代码访问 result.Item.id

修复: 将 result.Item 改为单对象(items[0]),同时保留 result.items 数组。

9.5 LLM 关系格式不一致

原因: LLM 可能返回数组、对象、或 related_id 包装的格式。

修复: 关系标准化器处理所有三种格式(StaffCapabilities.vue:1976-1991)。

9.6 LLM 把 related_item_type 写成关系名

原因: LLM 不理解 related_item_typerelationship_type 的区别。

修复: 代码从 relTypes 查找关系配置,用正确的目标类型覆盖 LLM 的值。


附录

A. 数据库备份

sciot_import.db → sciot_import.db.backup_20260603 (22.8MB)

B. 相关文件清单

| 文件 | 用途 |

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

| src/views/StaffCapabilities.vue | 主创建流程(字段处理、关系处理、Sequence) |

| src/utils/rule-validator.js | 数据类型清洗、规则验证 |

| src/utils/SCSAI.js | SCSAI API 请求、XML 解析 |

| src/utils/AmlBuilder.js | AML 生成 |

| src/utils/PromptBuilder.js | LLM Prompt 构建 |

| scripts/batch-import-templates.js | 模板批量导入 |

| server/routes/aml.js | 后端 API(模板查询/更新) |

| server/routes/unified-aml.js | 统一 Schema API |

| server/core/unified-schema.js | Schema Builder |

| server/data/sciot_import.db | SQLite 数据库(模板 + 属性 + 关系) |

C. 参考文档

  • docs/SCIOT-AML-Basic-Settings-Reference.md — SCSAI 基础设置完整参考
← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁