对象类管理全面优化方案
版本: v1.0 | 日期: 2026-05-06 | 状态: 待确认
一、现状诊断总结
1.1 ItemType 定义分析(24个XML文件)
| 分类 | 数量 | 类型 | 关键特征 |
|------|------|------|----------|
| 设计类 | 3 | Part, Document, CAD | 可版本化,继承自 Change Controlled Item(多态) |
| 变更管理 | 7 | ECR, ECN, PR, Simple ECO/MCO, Express DCO/ECO | 有独立工作流和生命周期 |
| 受影响项 | 2 | Affected Item/Relationship | is_dependent=1,依附于变更单 |
| 组织/参与方 | 3 | Customer, Manufacturer, Vendor | 属性结构几乎相同 |
| 采购/供应 | 1 | Manufacturer Part | 关联 Manufacturer |
| 产品 | 1 | Product | 最简单,无版本控制 |
| 仪表板 | 5 | Design To Goal 等 | 无数据结构,仅TOC导航入口 |
| 多态基类 | 2 | Change Controlled Item/Relationship | polymorphic 模式,Morphae 继承 |
核心设计模式:
- 多态继承: Part/Document/CAD 共享 CCI 数据表,通过
itemtype属性区分 - 变更追踪: Affected Item 通过 old/new 配对记录变更前后状态
- 角色分层权限: World → All Employees → CM → Component Engineering → Administrators
1.2 后端 API 分析(aml.js 2276行)
- 48个路由 分布在两个导出函数中(主路由29个 + TOC配置路由19个)
- 致命Bug:
generate-rules使用require('../database1').getDatabase()— 模块API不匹配- SCIOT 路由被错误嵌套在
else块中 aml_properties表结构在多处不一致(缺少default_value,item_type_name,is_required列)- 无 PUT 更新路由(只能新建不能修改)
- 架构问题: 2276行 if-else 链,无模块化,无错误处理中间件
1.3 前端 UI 分析(app.js)
- 已实现: 列表展示、9类子元素查看、AML编辑/转换/保存、AI助手对话
- 缺失功能:
- ❌ 创建对象类表单
- ❌ 删除对象类
- ❌ 编辑对象类属性(只能查看)
- ❌ 文件导入/导出(无上传下载组件)
- ❌ 批量操作(选择/删除/导出)
- ❌ 版本管理
- 6个后端API前端未使用: validate, compare, fix, generate, analyze, graph
1.4 SCSAI 通信层分析
| 通道 | 文件 | 环境 | 端点 | 问题 |
|---|---|---|---|---|
| ASPX直连 | SCSAI-connection.js | Node.js | AgentRequestHandler.aspx | 手写正则解析XML,80%重复代码 |
| OData | api-utils.js | Node.js | /odata/AML | 无错误处理、无超时 |
| SOAP | Soap.js + soap_object.js | 浏览器 | InnovatorServer.aspx | SyncPromise非标准,同步阻塞UI |
二、优化架构设计
2.1 总体架构
┌─────────────────────────────────────────────────────────────────┐
│ 前端 (Vue 3) │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────────────┐ │
│ │ 对象类列表 │ │ 对象类详情 │ │ AI 助手面板 │ │
│ │ (搜索/过滤/ │ │ (属性/方法/ │ │ (创建/修复/优化/比对) │ │
│ │ 批量操作) │ │ 关系/生命周期)│ │ │ │
│ └──────┬───────┘ └──────┬───────┘ └───────────┬───────────┘ │
│ │ │ │ │
│ ┌──────┴─────────────────┴──────────────────────┴───────────┐ │
│ │ REST API Client (fetch) │ │
│ └──────────────────────────┬────────────────────────────────┘ │
└─────────────────────────────┼───────────────────────────────────┘
│
┌─────────────────────────────┼───────────────────────────────────┐
│ 后端 (Node.js) │
│ ┌──────────────────────────┴────────────────────────────────┐ │
│ │ Express Router (模块化) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │
│ │ │ itemtype │ │ template │ │ import- │ │ ai- │ │ │
│ │ │ .router │ │ .router │ │ export │ │ assistant │ │ │
│ │ │ (CRUD) │ │ (AML管理)│ │ .router │ │ .router │ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌────┴────────────┴────────────┴───────────────┴───────┐ │ │
│ │ │ SCSAIClient (统一通信层) │ │ │
│ │ │ - sendAML(aml) → Promise<SCSAIResponse> │ │ │
│ │ │ - applyItem(aml) → Promise<SCSAIResponse> │ │ │
│ │ │ - validateUser(creds) → Promise<UserInfo> │ │ │
│ │ └──────────────────────┬───────────────────────────────┘ │ │
│ └─────────────────────────┼─────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────┼─────────────────────────────────┐ │
│ │ 数据层 │ │
│ │ ┌──────────┐ ┌──────────────┐ ┌────────────────────┐ │ │
│ │ │ SQLite │ │ ItemType XML │ │ SCSAI Server │ │ │
│ │ │ (本地) │ │ (定义文件) │ │ (PLM 主数据) │ │ │
│ │ └──────────┘ └──────────────┘ └────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
2.2 统一 SCSAI 通信层 (SCSAIClient)
// server/utils/SCSAI-client.js
class SCSAIClient {
constructor(config) {
this.serverUrl = config.serverUrl; // SCSAI 服务器地址
this.database = config.database; // 数据库名
this.username = config.username; // 用户名
this.password = config.password; // 密码(明文,内部哈希)
this.hashType = 'md5'; // 哈希类型: md5 | sha256
this.timeout = 30000; // 超时 30秒
}
// 核心方法:发送 AML 查询
async sendAML(amlString) {
// 1. 构建 SOAP Envelope
// 2. 添加认证头 (AUTHUSER + AUTHPASSWORD MD5)
// 3. POST 到 /server/InnovatorServer.aspx
// 4. 解析 XML 响应为标准 SCSAIResponse
// 5. 统一错误处理(HTTP错误 + SOAP Fault)
}
// ApplyItem:创建/更新/删除 SCSAI 对象
async applyItem(amlString) {
return this.sendAML(amlString);
}
// 验证用户
async validateUser() {
const hashPwd = crypto.createHash('md5').update(this.password).digest('hex');
const aml = `<Item type="User" action="ValidateUser">
<login_name>${this.username}</login_name>
<password>${hashPwd}</password>
<database>${this.database}</database>
</Item>`;
return this.sendAML(aml);
}
// 标准响应格式
// {
// success: boolean,
// items: Array<{ id, type, keyed_name, [propName]: value }>,
// fault: { code, string, message } | null,
// rawXml: string,
// count: number
// }
}
2.3 模块化路由设计
将 aml.js 2276行 if-else 链拆分为 6 个独立路由模块:
server/routes/
├── index.js # 路由注册入口
├── itemtype.router.js # 对象类 CRUD(核心)
├── template.router.js # AML 模板管理
├── import-export.router.js # 导入导出
├── ai-assistant.router.js # AI 创建/修复/优化/比对
├── toc-config.router.js # TOC 配置管理
└── rules-prompts.router.js # 规则和 Prompt 管理
2.4 数据库表结构统一
-- 对象类主表
CREATE TABLE IF NOT EXISTS item_types (
id TEXT PRIMARY KEY,
name TEXT UNIQUE NOT NULL, -- ItemType 名称
label TEXT, -- 显示名称
category TEXT, -- 分类: design/change/sourcing/organization/dashboard
source TEXT DEFAULT 'local', -- 数据源: local/SCSAI/sciot
description TEXT,
is_versionable INTEGER DEFAULT 0,
is_polymorphic INTEGER DEFAULT 0,
is_dependent INTEGER DEFAULT 0,
parent_type TEXT, -- 多态父类型
instance_data TEXT, -- SCSAI instance_data 表名
icon TEXT,
color TEXT,
sort_order INTEGER DEFAULT 0,
is_core_business INTEGER DEFAULT 0,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
-- 对象类属性表
CREATE TABLE IF NOT EXISTS item_type_properties (
id TEXT PRIMARY KEY,
item_type_name TEXT NOT NULL, -- 关联对象类名称
property_name TEXT NOT NULL,
label TEXT,
data_type TEXT DEFAULT 'string', -- string/integer/float/date/boolean/item/list/federated/text/image/decimal
stored_length INTEGER,
is_required INTEGER DEFAULT 0,
is_key INTEGER DEFAULT 0,
is_readonly INTEGER DEFAULT 0,
is_hidden INTEGER DEFAULT 0,
default_value TEXT,
data_source TEXT, -- list 数据源
foreign_type TEXT, -- item 外键指向的类型
sort_order INTEGER DEFAULT 0,
class_path TEXT, -- 分类路径(CAD的Mechanical/Electronic)
grid_events TEXT, -- JSON: Grid 事件配置
UNIQUE(item_type_name, property_name)
);
-- AML 模板表(保留现有功能)
CREATE TABLE IF NOT EXISTS aml_templates (
id TEXT PRIMARY KEY,
item_type_name TEXT NOT NULL,
name TEXT,
aml_content TEXT NOT NULL,
description TEXT,
version INTEGER DEFAULT 1,
is_active INTEGER DEFAULT 1,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
-- 操作日志表
CREATE TABLE IF NOT EXISTS operation_logs (
id TEXT PRIMARY KEY,
action TEXT NOT NULL, -- create/update/delete/import/export/ai_generate
target_type TEXT, -- 操作目标类型
target_name TEXT, -- 操作目标名称
status TEXT DEFAULT 'success', -- success/error
detail TEXT,
operator TEXT,
created_at TEXT DEFAULT (datetime('now'))
);
三、分阶段实施计划
Phase 0: 修复致命 Bug(预计 2-3 小时)
#### P0-1: 修复 generate-rules 路由
- 文件:
server/routes/aml.js第 1553 行 - 问题:
require('../database1').getDatabase()模块不存在 - 修复: 改为使用统一的
require('../database')+ 正确的表结构
#### P0-2: 修复 if-else 嵌套错误
- 文件:
server/routes/aml.js第 1649 行 - 问题: SCIOT 路由被错误嵌套在 else 块中
- 修复: 将
} else {改为独立的if语句
#### P0-3: 修复表结构不一致
- 文件:
server/routes/aml.js第 44-47 行建表语句 - 问题:
aml_properties缺少default_value,item_type_name,is_required列 - 修复: 统一表结构,添加缺失列
#### P0-4: 添加 PUT 更新路由
- 文件:
server/routes/aml.js - 问题: 无更新已有模板的路由
- 修复: 添加
PUT /api/aml/template/:id路由
Phase 1: 统一 SCSAI 通信层(预计 3-4 小时)
#### P1-1: 创建 SCSAIClient 类
- 新文件:
server/utils/SCSAI-client.js - 合并
SCSAI-connection.js和api-utils.js的功能 - 统一使用
xml2js解析 XML(淘汰手写正则) - 统一错误处理(HTTP 状态码 + SOAP Fault)
- 统一添加超时和代理支持
- 提取公共 HTTP 请求函数(消除 80% 重复代码)
#### P1-2: 迁移现有调用
- 将
aml.js中的runAml()调用替换为SCSAIClient.sendAML() - 将
SCSAI-connection.js的 CRUD 调用替换为SCSAIClient.applyItem() - 保留
SCSAI-connection.js和api-utils.js作为兼容层(标记 deprecated)
#### P1-3: 前端 SOAP 优化
- 文件:
SCSAI/core/Soap.js - 淘汰
SyncPromise,迁移到标准Promise - 消除
async: false同步阻塞
Phase 2: 重构后端路由(预计 4-5 小时)
#### P2-1: 创建模块化路由
- 将 aml.js 拆分为 6 个独立路由文件
- 使用 Express Router 标准模式
- 添加请求验证中间件
- 统一错误处理中间件
#### P2-2: 补齐 CRUD API
POST /api/itemtypes— 创建对象类(同步到 SCSAI)PUT /api/itemtypes/:name— 更新对象类定义DELETE /api/itemtypes/:name— 删除对象类(逻辑删除)GET /api/itemtypes/:name/properties— 获取属性列表POST /api/itemtypes/:name/properties— 添加属性PUT /api/itemtypes/:name/properties/:propName— 修改属性DELETE /api/itemtypes/:name/properties/:propName— 删除属性POST /api/itemtypes/batch— 批量操作
#### P2-3: 补齐导入导出 API
POST /api/itemtypes/import/xml— 从 XML 文件导入POST /api/itemtypes/import/SCSAI— 从 SCSAI 导入GET /api/itemtypes/export/xml/:name— 导出为 XML 文件GET /api/itemtypes/export/json/:name— 导出为 JSONPOST /api/itemtypes/export/batch— 批量导出
Phase 3: 重写前端对象类管理 UI(预计 6-8 小时)
#### P3-1: 对象类列表增强
- 添加「新建对象类」按钮 → 弹出创建向导
- 添加批量选择(checkbox)→ 批量删除/导出
- 添加分类筛选标签页(设计/变更/采购/组织/仪表板)
- 添加排序(按名称/类型/属性数/更新时间)
- 添加右键菜单(编辑/复制/删除/导出)
#### P3-2: 创建对象类向导
- 步骤1: 选择基类型(普通/多态/依赖)
- 步骤2: 填写基本信息(名称/标签/分类/描述)
- 步骤3: 配置属性(名称/类型/必填/默认值/数据源)
- 步骤4: 配置生命周期(选择或创建 Life Cycle Map)
- 步骤5: 配置权限(Can Add / Allowed Permission)
- 步骤6: 预览 AML → 确认创建
#### P3-3: 对象类详情编辑
- 属性 Tab: 支持添加/编辑/删除/排序属性
- 方法 Tab: 支持查看方法代码
- 关系 Tab: 支持查看和配置关系类型
- 生命周期 Tab: 可视化生命周期状态图
- 权限 Tab: 权限规则编辑
- AML Tab: 增强的 AML 编辑器(语法高亮/验证/自动补全)
#### P3-4: 导入导出 UI
- 导入: 文件上传组件(支持 .xml 多文件拖拽上传)
- 导出: 下载按钮(单个/批量导出为 XML/JSON)
- 导入预览: 上传后显示解析结果,确认后再导入
- 导入报告: 显示成功/失败/跳过的条目
#### P3-5: 激活已有但未使用的后端 API
- 验证 (validate): AML 语法验证按钮
- 比对 (compare): 两个 AML 模板差异对比
- 修复 (fix): 一键修复 AML 问题
- 分析 (analyze): 全量分析仪表盘
- 关系图 (graph): D3/Mermaid 关系图可视化
Phase 4: AI 能力落地(预计 4-6 小时)
#### P4-1: AI 创建对象类
- 基于 ItemType XML 定义训练/构建 Prompt 模板
- 用户描述需求 → AI 生成完整 AML 定义
- AI 自动推断属性类型、数据源、生命周期
- 支持从现有类型继承/复制
#### P4-2: AI 修复对象类
- 自动检测 AML 定义中的问题(缺失属性、类型不匹配等)
- AI 生成修复建议 → 用户确认 → 自动应用
- 支持批量修复
#### P4-3: AI 优化对象类
- 分析属性命名规范、数据类型选择
- 建议最佳实践(索引、默认值、分类结构)
- 一键应用优化建议
#### P4-4: AI 比对对象类
- 比对本地定义 vs SCSAI 在线定义
- 比对两个不同版本的差异
- 生成差异报告和合并建议
Phase 5: 集成测试验证(预计 2-3 小时)
- 端到端测试: 创建 → 编辑 → 导出 → 导入 → 删除
- SCSAI 通信测试: 所有 CRUD 操作验证
- AI 功能测试: 创建/修复/优化/比对各场景
- 性能测试: 24个 ItemType 全量加载 < 5秒
- 错误恢复测试: 网络断开/SCSAI 不可用/数据库锁定
四、关键设计决策
4.1 为什么不直接用 Express Router 替换自定义路由?
当前 aml.js 使用 (req, res, pathname, query, bodyStr) 自定义签名,是因为 server.js 使用的是自定义 HTTP 框架而非 Express。决策: 在路由模块内部使用 Express Router 模式组织代码,但保持与现有 server.js 的兼容接口。逐步迁移到 Express。
4.2 为什么保留本地 SQLite 而不全部走 SCSAI?
- 离线能力: SCSAI 不可用时仍可查看已缓存的对象类定义
- 性能: 本地查询远快于 SCSAI SOAP 调用
- AI 上下文: AI 助手需要快速获取对象类元数据,不适合每次都调 SCSAI
- 版本管理: 本地保存对象类定义的历史版本
4.3 为什么前端不拆分为多个 Vue 组件?
当前 app.js 是一个 6000+ 行的单文件。决策: 本次优化暂不拆分文件,而是通过清晰的函数分组和注释来改善可维护性。后续如有需要再进行组件拆分。
4.4 AI 三级降级策略
L1 (直接执行): AI 返回 tool_call + auto_execute → 自动执行操作
↓ 失败/不支持
L2 (确认执行): AI 返回操作建议 → 用户确认后执行
↓ 失败/超时
L3 (纯对话): 降级为文本对话,提供指导建议
↓ 失败/超时
L4 (本地回退): 使用本地规则引擎,基于 ItemType XML 定义进行操作
五、风险与缓解
| 风险 | 影响 | 缓解措施 |
|------|------|----------|
| SCSAI 通信层重构导致现有功能回归 | 高 | 保留旧接口作为兼容层,渐进式迁移 |
| 数据库表结构变更导致数据丢失 | 高 | 迁移脚本 + 数据备份 |
| 前端改动过大影响其他模块 | 中 | 对象类管理代码相对独立,影响范围可控 |
| AI 生成 AML 质量不稳定 | 中 | 人工确认环节 + AML 验证器 |
| 2276行 aml.js 拆分引入新 Bug | 中 | 逐模块迁移,每步验证 |
六、优先级排序
| 优先级 | 阶段 | 预计工时 | 价值 |
|--------|------|----------|------|
| P0 | 修复致命 Bug | 2-3h | 🔴 不修就不能用 |
| P1 | 统一通信层 | 3-4h | 🔴 架构基础 |
| P2 | 重构路由 + 补齐 API | 4-5h | 🟡 后端完整 |
| P3 | 重写前端 UI | 6-8h | 🟢 用户可见 |
| P4 | AI 能力 | 4-6h | 🟢 差异化价值 |
| P5 | 集成测试 | 2-3h | 🟡 质量保障 |
总预计工时: 21-29 小时
七、立即行动项(P0 修复清单)
- ✅ 修复
aml.js:1553—require('../database1')→require('../database') - ✅ 修复
aml.js:1649— 移除错误的else嵌套 - ✅ 修复
aml.js:44-47—aml_properties表添加缺失列 - ✅ 添加
PUT /api/aml/template/:id更新路由 - ✅ 修复
aml.js:276—getTemplateDetail查询default_value列
BossAgents