左帮右臂 — 技术设计文档(优化方案)
版本: V1.0
日期: 2026-06-24
对应需求: spec-优化方案.md
范围: P0 + P1 需求的完整实现设计,P2 仅写方向
原则: 与现有代码架构一致,不重构已有模块,增量式开发
1. 实现模型
1.1 上下文视图
┌─────────────────────────────────────────────────────────────────────┐
│ 三端客户端 │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Vue3网页端│ │ 飞书Bot+卡片 │ │ UniApp小程序 │ │
│ └────┬─────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ └───────────────┼─────────────────┘ │
│ ▼ │
│ /api/pipeline/execute (统一入口) │
│ /api/asr/recognize (语音识别) │
│ /api/miniapp/* (小程序专用) │
│ /api/feishu/* (飞书专用) │
├─────────────────────────────────────────────────────────────────────┤
│ server.js (handleRequest) │
│ ┌──────────┬──────────┬──────────┬──────────────────────────────┐ │
│ │ 路由层 │ 服务层 │ 核心层 │ 数字员工层 │ │
│ │ routes/ │ services/│ core/ │ digital-staff/ │ │
│ └──────────┴──────────┴──────────┴──────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────────┐│
│ │ 数据层: db-adapter (SQLite/MySQL) │ SCSAI PLM (AML) ││
│ │ AI层: SmartLLMRouter │ 外部: 讯飞/1688/飞书/微信 ││
│ └─────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────┘
外部系统交互
| 外部系统 | 交互方式 | 本项目模块 | 需求关联 |
|---------|---------|-----------|---------|
| 讯飞 iFlytek | HTTPS REST API | server/services/asr-service.js | 5.1 语音决策链路 |
| 飞书开放平台 | HTTPS + Webhook + 卡片回调 | server/feishu-bot.js, server/feishu-service.js | 5.3 飞书集成 |
| 微信开放平台 | HTTPS (jscode2session) | server/routes/auth.js (新增小程序登录) | 5.2 小程序统一 |
| 1688 开放平台 | HTTPS OAuth + API | server/services/alibaba-1688-service.js | 5.4 采购流程 |
| SCSAI Agent | AML HTTP API | server/utils/SCSAI-client.js | 全局 |
| IMAP 邮件服务器 | IMAP 协议 | server/services/email-listener.js | 5.8 邮件即指令 |
1.2 服务/组件总体架构
┌─────────────────────────────────────────────────────────────────────┐
│ 新增/修改模块总览 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 模块A: 语音决策链路 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ asr-service.js (已有,增强) → intent-engine.js (已有) │ │
│ │ conversation-engine.js (已有,增强) → feishu-bot.js (增强) │ │
│ │ VoiceInput.vue (重写) → 小程序ai-chat页面 (增强) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 模块B: 小程序三端统一 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ miniapp-auth.js (新增) → miniapp.js API (增强) │ │
│ │ VoiceInput.vue (重写) → 各页面数据对接 (修改) │ │
│ │ notification-sync.js (新增) → unified-messages.js (增强) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 模块C: 飞书集成完善 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ feishu-pending-store.js (新增) → feishu-bot.js (增强) │ │
│ │ feishu-crypto.js (新增) → feishu-service.js (增强) │ │
│ │ feishu-approval.js (新增) → feishu-service.js (增强) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 模块D: 采购流程端到端 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ purchase-order-service.js (新增) → procurement.js (增强) │ │
│ │ alibaba-1688-service.js (增强) → llm-quotation-service.js│ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 模块E: BOM管理增强 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ bom-import-service.js (新增) → relationship-resolver.js │ │
│ │ BomAssistant.vue (增强) → BomTreeGraph.vue (新增) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 模块F: 数字员工自动化协作 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ collaboration-scheduler.js (新增) → task-board.js (增强) │ │
│ │ collaboration-rules.yaml (新增) → staff-manager.js (增强) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 模块G: 关系感知引擎 (V1.1) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ relationship-resolver.js (增强) → relationship-capability │ │
│ │ relationship-checklist.js (增强) → BomAssistant.vue (增强)│ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 模块H: 多租户安全加固 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ tenant-middleware.js (新增) → auth.js (增强) │ │
│ │ tenant-db.js (增强) → SCSAI-client.js (增强) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 模块I: 微信发布服务统一 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ wechat-publish.js (修改) → content-api.js (修改) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 模块J: 邮件即指令 (V1.2方向) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ email-command-parser.js (新增) → email-listener.js (增强) │ │
│ │ email-commands.yaml (新增) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
1.3 实现设计文档
1.3.1 模块A:语音决策链路(P0)
#### 现有架构分析
| 现有模块 | 文件路径 | 现状 | 缺口 |
|---------|---------|------|------|
| ASR服务 | server/services/asr-service.js | 已实现讯飞+Echo双后端,/api/asr/recognize 已在 server.js 行1534注册 | 功能完整,无需修改 |
| 意图路由 | server/core/intent-engine.js | 已实现30+条意图规则,L1/L2/L3三级识别 | 功能完整,需确认采购意图规则覆盖 |
| 对话引擎 | server/digital-staff/conversation-engine.js | 已实现sendMessage+动作意图检测 | 缺少从ASR文本到意图路由的衔接 |
| 飞书审批 | server/feishu-bot.js | 已实现pendingActions Map+文本确认 | pendingActions未持久化(见模块C) |
| 小程序语音 | bossagents-miniapp/src/components/VoiceInput.vue | 仅有UI壳,无录音/上传/识别逻辑 | 需完整重写 |
#### 实现方案
R1: 小程序语音输入接入ASR
重写 VoiceInput.vue,实现完整录音→上传→识别流程:
VoiceInput.vue (重写)
├── onStart() → uni.getRecorderManager().start({ format: 'pcm', sampleRate: 16000 })
├── onStop() → recorderManager.stop() → 获取临时文件路径
├── onUpload()→ uni.uploadFile({ url: '/api/asr/recognize', filePath, name: 'audio' })
└── onResult()→ emit('result', text) → 父组件填入聊天输入框
集成点:
- 后端
/api/asr/recognize已在server.js行1534-1605注册,支持 multipart/form-data 和二进制上传 - ASR降级:
asr-service.js已实现 Echo 模式降级(行179-198),当讯飞不可用时自动回退
R2: 语音文本意图路由
在 conversation-engine.js 的 sendMessage() 方法中增加ASR来源标记,当 source=asr 时优先走 IntentEngine:
sendMessage(sessionId, userMessage, options)
├── if (options?.source === 'asr') → 先调 IntentEngine.recognize(message)
│ ├── 识别到 procurement → 路由到 DS-PROC-001
│ ├── 识别到 ecr → 路由到 DS-ECR-001
│ └── 识别失败 → 路由到 DS-SYS-001(默认引导)
└── else → 走现有 _detectActionIntent 逻辑
集成点:
IntentEngine.recognize()在server/core/intent-engine.js行291-351- 已有采购相关意图规则(BUILTIN_INTENT_RULES 中
procurement_*系列) - 默认员工 DS-SYS-001 已在 STAFF_SYSTEM_PROMPTS 中定义
R3: 飞书语音审批执行
在 feishu-bot.js 的卡片构建函数中,当 pendingActions.size > 0 时添加"🎤 语音审批"按钮:
buildXxxCard()
├── if (pendingActions.size > 0) → 追加"🎤 语音审批"按钮
└── else → 不追加(禁止项 R4)
卡片回调处理:
handleCardAction(action)
├── action === 'voice_approve' → consumePendingAction(pendingId) → 执行业务操作
└── action === 'approve/reject' → 走现有逻辑
集成点:
pendingActionsMap 在feishu-bot.js行323定义consumePendingAction()在行359定义- 卡片回调通过飞书事件订阅推送到
feishu-bot.js
#### 文件变更清单
| 操作 | 文件路径 | 变更说明 |
|------|---------|---------|
| 重写 | bossagents-miniapp/src/components/VoiceInput.vue | 实现录音→上传→识别完整流程 |
| 修改 | server/digital-staff/conversation-engine.js | sendMessage 增加 source=asr 分支,优先走 IntentEngine |
| 修改 | server/feishu-bot.js | 卡片构建函数增加语音审批按钮,回调处理增加 voice_approve 动作 |
| 修改 | bossagents-miniapp/src/pages/ai-chat/index.vue | 集成 VoiceInput 组件,处理识别结果 |
1.3.2 模块B:小程序三端统一(P0+P1)
#### 现有架构分析
| 现有模块 | 文件路径 | 现状 | 缺口 |
|---------|---------|------|------|
| 小程序登录 | bossagents-miniapp/src/pages/login/index.vue | UI已实现,调用 miniappApi.login(code) | 后端 /api/miniapp/login 未实现微信 jscode2session |
| 小程序API | bossagents-miniapp/src/api/miniapp.js | 已定义 login/getDashboard 等接口 | 后端部分API返回mock数据 |
| 用户Store | bossagents-miniapp/src/store/index.js | 已实现 useUserStore/useSystemStore/useNotificationStore | 通知Store未对接真实后端 |
| 后端认证 | server/middleware/auth.js | JWT签发+验证已完整 | 缺少微信 openid → JWT 的签发流程 |
#### 实现方案
R1: 微信登录完整实现
新增 server/routes/miniapp-auth.js,实现微信登录流程:
POST /api/miniapp/login { code }
├── 1. 调用微信 jscode2session: GET https://api.weixin.qq.com/sns/jscode2session
│ ├── 参数: appid=WECHAT_APP_ID, secret=WECHAT_APP_SECRET, js_code=code, grant_type=authorization_code
│ └── 返回: { openid, session_key }
├── 2. 降级: 若 WECHAT_APP_ID 未配置 → openid = 'dev_' + code (开发模式)
├── 3. 查找/创建用户: SELECT * FROM user WHERE wx_openid = openid
│ ├── 不存在 → INSERT INTO user (wx_openid, login_name, role) VALUES (openid, 'wx_'+openid.slice(0,8), 'employee')
│ └── 已存在 → 返回 user record
├── 4. 签发JWT: signToken({ user_id, enterprise_id: user.enterprise_id || 'default', role })
└── 5. 返回: { success: true, token, user }
集成点:
signToken()在server/middleware/auth.js行5-7tenant-db.js的user表(行定义在server/services/tenant-db.js)- 需在
user表新增wx_openid TEXT列(幂等 ALTER TABLE) - 环境变量:
WECHAT_APP_ID,WECHAT_APP_SECRET(统一命名,废弃MINIPROGRAM_APPID)
R2: 小程序语音输入完整实现
已在模块A中设计(VoiceInput.vue 重写)。
R3: 小程序页面数据对接
修改小程序各页面,将硬编码mock数据替换为API调用:
| 页面 | 文件 | 对接API | 当前状态 |
|------|------|---------|---------|
| 工作台 | pages/workbench/index.vue | miniappApi.getDashboard() → GET /api/miniapp/dashboard | 需后端实现 |
| AI对话 | pages/ai-chat/index.vue | digitalStaffApi.chat() → POST /api/digital-staff/chat | 已实现 |
| 变更列表 | pages/workbench/change-list.vue | changeApi.getList() → GET /api/change/list | 已实现 |
| 任务 | pages/task/index.vue | digitalStaffApi.getTasks() → GET /api/digital-staff/tasks | 已实现 |
后端新增 /api/miniapp/dashboard 路由(在 server/routes/miniapp-auth.js 中):
GET /api/miniapp/dashboard
├── productCount → SELECT COUNT(*) FROM sciot_templates WHERE item_type_name LIKE 'Part%'
├── changeCount → SELECT COUNT(*) FROM staff_tasks WHERE task_type = 'ecr_review'
├── ruleCount → SELECT COUNT(*) FROM sciot_rules_v2
└── staffCount → SELECT COUNT(*) FROM digital_staff WHERE enabled = 1
R4: 三端消息同步
新增 server/services/notification-sync.js,统一消息推送:
notification-sync.js
├── push(userId, message, channels)
│ ├── channels.feishu → feishuService.sendMessageToUser(openId, message)
│ ├── channels.miniapp → 写入 notifications 表 + 微信订阅消息
│ └── channels.web → unifiedMessages.addMessage()
├── getNotifications(userId, page, pageSize) → SELECT * FROM notifications WHERE user_id = ?
└── markRead(userId, notificationId) → UPDATE notifications SET read = 1
新增 notifications 数据库表:
CREATE TABLE IF NOT EXISTS notifications (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
title TEXT DEFAULT '',
content TEXT DEFAULT '',
type TEXT DEFAULT 'info', -- info/warning/action/approval
source TEXT DEFAULT 'system', -- system/feishu/miniapp/web
business_type TEXT DEFAULT '', -- ecr/bom/procurement/vendor
business_id TEXT DEFAULT '',
read INTEGER DEFAULT 0,
created_at TEXT,
FOREIGN KEY (user_id) REFERENCES user(id)
);
CREATE INDEX IF NOT EXISTS idx_notifications_user ON notifications(user_id);
CREATE INDEX IF NOT EXISTS idx_notifications_read ON notifications(user_id, read);
集成点:
feishuService.sendMessageToUser()在server/feishu-service.js行312-348unifiedMessages.addMessage()在server/services/unified-messages.js- 微信订阅消息:
uni.requestSubscribeMessage()(小程序端)
#### 文件变更清单
| 操作 | 文件路径 | 变更说明 |
|------|---------|---------|
| 新增 | server/routes/miniapp-auth.js | 微信登录 + dashboard + 通知API |
| 修改 | server.js | handleRequest 注册 /api/miniapp/* 路由 |
| 修改 | server/services/tenant-db.js | user表新增 wx_openid 列 |
| 新增 | server/services/notification-sync.js | 三端消息同步服务 |
| 修改 | bossagents-miniapp/src/pages/workbench/index.vue | 替换mock为API调用 |
| 修改 | bossagents-miniapp/src/store/index.js | useNotificationStore 对接真实API |
| 修改 | bossagents-miniapp/src/api/miniapp.js | 新增 getNotifications/markRead |
1.3.3 模块C:飞书集成完善(P0+P1)
#### 现有架构分析
| 现有模块 | 文件路径 | 现状 | 缺口 |
|---------|---------|------|------|
| pendingActions | server/feishu-bot.js 行316-380 | 内存Map,10分钟TTL,定时清理 | 未持久化,重启丢失 |
| 飞书服务 | server/feishu-service.js | 已实现审批API(createApproval/getApprovalStatus/handleApprovalCallback) | 事件订阅加密解密未实现 |
| 飞书Bot | server/feishu-bot.js | 已实现卡片构建+文本确认 | 审批流集成未实现 |
#### 实现方案
R1: pendingActions持久化
新增 server/services/feishu-pending-store.js,将 pendingActions 从内存Map迁移到SQLite:
feishu-pending-store.js
├── ensureTable() → CREATE TABLE feishu_pending_actions (见数据模型4.2)
├── set(id, data) → INSERT OR REPLACE INTO feishu_pending_actions
├── get(id) → SELECT * FROM feishu_pending_actions WHERE id = ?
├── consume(id) → get + DELETE → 返回数据
├── findByUser(userId) → SELECT * WHERE feishu_user_id = ? AND consumed_at IS NULL
├── recoverOnStartup() → SELECT * WHERE consumed_at IS NULL AND expires_at > now
│ → 恢复到内存Map(兼容现有 feishu-bot.js 的 pendingActions 引用)
└── cleanup() → DELETE WHERE consumed_at IS NOT NULL OR expires_at < now (每60秒)
迁移策略(兼容性优先):
feishu-bot.js中的pendingActionsMap 保留,作为一级缓存setPendingAction()同时写入 Map + SQLiteconsumePendingAction()先从 Map 取,Map 未命中再查 SQLite- 服务启动时
recoverOnStartup()恢复未过期的 pendingAction 到 Map
集成点:
feishu-bot.js行323:const pendingActions = new Map()→ 改为双层存储feishu-bot.js行352:setPendingAction()→ 增加SQLite写入feishu-bot.js行359:consumePendingAction()→ 增加SQLite查询+删除db-adapter.js的createDatabase()创建数据库实例
R2: 飞书事件订阅加密解密
新增 server/services/feishu-crypto.js:
feishu-crypto.js
├── decryptEvent(encryptedData, key) → AES-256-CBC 解密
│ ├── key = Base64Decode(EncryptKey)
│ ├── iv = Base64Decode(encryptedData).slice(0, 16)
│ ├── data = Base64Decode(encryptedData).slice(16)
│ └── 返回: JSON.parse(decrypted)
├── verifyToken(payload, verificationToken) → 验证 Verification Token
└── handleChallenge(challenge) → 返回 { challenge } 响应
在 server.js 的飞书事件回调路由中集成:
POST /api/feishu/event (新增路由)
├── 1. 若 body.encrypt → feishuCrypto.decryptEvent(body.encrypt, FEISHU_ENCRYPT_KEY)
├── 2. 若 body.challenge → 返回 { challenge: body.challenge }
├── 3. feishuCrypto.verifyToken(body, FEISHU_VERIFICATION_TOKEN)
└── 4. 分发事件到 feishu-bot.js 处理
集成点:
- 环境变量:
FEISHU_ENCRYPT_KEY,FEISHU_VERIFICATION_TOKEN server.js需新增/api/feishu/event路由注册
R3: 飞书审批流集成
利用已有的 feishu-service.js 审批API,在业务操作中调用:
业务操作需要审批时:
├── 1. feishuService.createApproval(approvalCode, { applicant, form })
│ → 创建飞书审批实例
├── 2. 审批人在飞书审批中心操作
├── 3. 飞书回调 → POST /api/feishu/approval/callback
│ → feishuService.handleApprovalCallback(callbackData)
├── 4. 审批通过 → 执行业务操作(ECR状态变更等)
└── 5. 审批拒绝 → 通知发起人
降级策略:若 createApproval() 失败 → 降级为卡片消息确认模式(现有逻辑)
集成点:
feishuService.createApproval()在行230-247feishuService.handleApprovalCallback()在行270-301- 需在
config.yaml中配置feishu.approval_code
#### 文件变更清单
| 操作 | 文件路径 | 变更说明 |
|------|---------|---------|
| 新增 | server/services/feishu-pending-store.js | pendingActions SQLite持久化 |
| 修改 | server/feishu-bot.js | setPendingAction/consumePendingAction 接入持久化层 |
| 新增 | server/services/feishu-crypto.js | 飞书事件加密解密 |
| 修改 | server.js | 新增 /api/feishu/event 和 /api/feishu/approval/callback 路由 |
| 修改 | server/feishu-service.js | 审批流集成(增强 createApproval 调用链路) |
1.3.4 模块D:采购流程端到端(P0+P1)
#### 现有架构分析
| 现有模块 | 文件路径 | 现状 | 缺口 |
|---------|---------|------|------|
| 采购路由 | server/routes/procurement.js | @deprecated,前端已走DS-PROC-001 | 无采购订单(PO)管理 |
| 1688服务 | server/services/alibaba-1688-service.js | 已实现4级降级寻源 | 降级时静默Mock,无明确提示 |
| 报价解析 | server/services/llm-quotation-service.js | 已实现LLM解析+比价 | 未关联到采购任务 |
| 邮件监听 | server/services/email-listener.js | 已实现IMAP监听 | IMAP地址硬编码 |
#### 实现方案
R1: 采购订单创建与跟踪
新增 server/services/purchase-order-service.js:
purchase-order-service.js
├── ensureTable() → CREATE TABLE purchase_orders (见数据模型4.2)
├── createPO(data) → INSERT INTO purchase_orders
│ ├── poId 自动生成: PO-{YYYYMMDD}-{seq4}
│ ├── totalAmount 自动计算自 items 汇总
│ └── status = 'pending_approval'
├── approvePO(poId, approvedBy) → UPDATE status='approved', approved_by, approved_at
├── confirmPO(poId) → UPDATE status='confirmed' (供应商确认后)
├── completePO(poId) → UPDATE status='completed'
├── getPO(poId) → SELECT * FROM purchase_orders WHERE po_id = ?
├── queryPOs(filters) → SELECT * WHERE ... ORDER BY created_at DESC
└── cancelPO(poId, reason) → UPDATE status='cancelled'
与数字员工集成(DS-PROC-001 采购助手):
采购助手完成询价 → 创建PO(pending_approval) → 飞书/小程序审批卡片
→ 老板审批通过 → approvePO() → 发送采购订单邮件给供应商
→ 供应商确认 → confirmPO() → 跟踪交付 → completePO()
集成点:
staff-manager.js的staff_tasks表关联 POfeishu-bot.js的卡片构建函数增加采购审批卡片email-service.js发送采购订单邮件
R2: 1688降级体验优化
修改 alibaba-1688-service.js 的 searchSourcing() 方法(行151-228):
searchSourcing(keyword)
├── Level 1: 1688真实API
│ ├── 成功 → 返回结果,标注"来源: 1688开放平台"
│ └── 失败 → 记录降级原因,继续下一级
├── Level 2: SmartLLMRouter LLM寻源
│ ├── 成功 → 返回结果,标注"⚠️ AI推荐仅供参考"
│ └── 失败 → 继续
├── Level 3: 本地数据库查询
│ ├── 成功 → 返回结果,标注"来源: 本地供应商库"
│ └── 失败 → 继续
└── Level 4: 返回明确提示
└── "暂无供应商信息,建议手动添加供应商后重新询价"
关键变更:删除现有的 Mock 兜底(行228附近),替换为明确提示。
集成点:
SmartLLMRouter.call()在server/digital-staff/smart-llm-router.js行486-598- 降级原因需通过
response.degraded = true; response.degradeReason = '...'返回
R3: 报价邮件自动解析增强
修改 email-listener.js 的 newEmail 事件处理,增加与采购任务的关联:
email-listener.js (增强)
├── this.emit('newEmail', emailData)
└── 新增: 自动触发报价解析
├── llmParseQuotation(emailData) → 解析结构化报价
├── 若解析成功 → 关联到 staff_tasks 中的采购任务
│ ├── UPDATE staff_tasks SET output_data = quotation, status = 'completed'
│ └── WHERE task_type = 'procurement' AND status = 'in_progress'
└── 若 non_quotation_email → 忽略
集成点:
llmParseQuotation()在server/services/llm-quotation-service.js行92-171staff-manager.js的updateTask()更新任务状态
#### 文件变更清单
| 操作 | 文件路径 | 变更说明 |
|------|---------|---------|
| 新增 | server/services/purchase-order-service.js | 采购订单CRUD+状态流转 |
| 新增 | server/routes/purchase-order.js | 采购订单API路由 |
| 修改 | server.js | handleRequest 注册 /api/purchase-order/* 路由 |
| 修改 | server/services/alibaba-1688-service.js | searchSourcing 删除Mock兜底,增加明确降级提示 |
| 修改 | server/services/email-listener.js | newEmail事件增加报价解析+任务关联 |
| 修改 | server/routes/procurement.js | 集成 purchase-order-service |
1.3.5 模块E:BOM管理增强(P0+P1)
#### 现有架构分析
| 现有模块 | 文件路径 | 现状 | 缺口 |
|---------|---------|------|------|
| BOM API | server.js 行1668-1831 | 已实现 /api/bom/tree 查询 | 无Excel导入 |
| BOM前端 | src/views/BomAssistant.vue | 已实现BOM管理界面 | 无图形化树展示 |
| 关系解析 | server/core/relationship-resolver.js | 已实现resolveExistence+discoverRelations+buildLinkPlan | 未与BOM导入流程集成 |
#### 实现方案
R1: BOM Excel导入
新增 server/services/bom-import-service.js:
bom-import-service.js
├── parseExcel(buffer) → 使用 xlsx 库解析
│ ├── 读取第一个Sheet
│ └── 返回: { headers: [...], rows: [[...], ...] }
├── mapColumns(headers, bomFields) → AI列映射识别
│ ├── 调用 SmartLLMRouter.call() 识别列名到BOM标准字段映射
│ ├── 标准字段: item_number, name, quantity, material, description
│ └── 返回: { mapping: { colIndex: fieldName }, confidence }
├── buildBomTree(rows, mapping) → 构建BOM树结构
│ ├── 支持多层级(通过 level/indent 列或 parent 列识别层级)
│ ├── 循环依赖检测(DFS遍历检测环)
│ └── 返回: { tree: BomNode[], warnings: [...] }
└── importBom(excelBuffer, options) → 完整导入流程
├── parseExcel → mapColumns → buildBomTree
├── 对每个零件调 relationshipResolver.resolveExistence() 检测已存在对象
└── 返回: { tree, matchResults, linkPlan }
新增API路由:
POST /api/bom/import/upload (multipart/form-data)
├── 接收Excel文件
├── bomImportService.importBom(buffer)
└── 返回: { tree, matchResults, linkPlan }
POST /api/bom/import/confirm
├── 用户确认列映射和导入
├── 执行 linkPlan(创建/关联对象)
└── 返回: { created: N, linked: M, warnings: [...] }
集成点:
SmartLLMRouter.call()在server/digital-staff/smart-llm-router.jsrelationshipResolver.resolveExistence()在server/core/relationship-resolver.js行137-233relationshipResolver.buildLinkPlan()在行371-467server.js已有/api/bom/路由前缀(行1832)
R2: BOM多层级图形化展示
新增前端组件 src/components/bom/BomTreeGraph.vue:
BomTreeGraph.vue
├── 使用 SVG 渲染树形图
├── 节点: 零件信息卡片(名称/编号/数量/匹配状态)
├── 边: 父子关系线
├── 交互: 展开/收起、缩放、拖拽、点击查看详情
└── 状态标记: ✅已关联 / ⚠️待确认 / 🔴循环依赖
在 BomAssistant.vue 中集成:
<BomTreeGraph :tree="bomTree" @node-click="showPartDetail" />
R3: BOM与工业对象库自动匹配
已在R1中设计(importBom 流程中的 resolveExistence 调用)。
三级检测逻辑(已有,无需修改):
- SCSAI item_number 精确查
- SCSAI name 精确查
- SCSAI name 模糊查(相似度≥0.4)
- 私有库查询
匹配结果标注:
- 匹配到 →
status: 'linked',SCSAIId: '...' - 未匹配 →
status: 'pending',suggestion: '待确认'
#### 文件变更清单
| 操作 | 文件路径 | 变更说明 |
|------|---------|---------|
| 新增 | server/services/bom-import-service.js | Excel解析+AI列映射+BOM树构建 |
| 新增 | server/routes/bom-import.js | BOM导入API路由 |
| 新增 | src/components/bom/BomTreeGraph.vue | BOM图形化树组件 |
| 修改 | server.js | handleRequest 注册 /api/bom/import/* 路由 |
| 修改 | src/views/BomAssistant.vue | 集成BomTreeGraph组件和导入功能 |
1.3.6 模块F:数字员工自动化协作(P1)
#### 现有架构分析
| 现有模块 | 文件路径 | 现状 | 缺口 |
|---------|---------|------|------|
| 任务看板 | server/digital-staff/task-board.js | 已有 completeTask(taskId, result, collaborationNext) 支持协作链 | 协作规则硬编码,无配置驱动 |
| 员工管理 | server/digital-staff/staff-manager.js | staff_tasks 已有 collaboration_chain 列 | 无协作调度器 |
| 调度器 | server/boss-scheduler/ | 已有 feishu-router | 无协作规则引擎 |
#### 实现方案
R1: 员工间自动协作编排
新增 server/digital-staff/collaboration-scheduler.js:
collaboration-scheduler.js
├── loadRules() → 从 collaboration-rules.yaml 加载规则
├── validateRules() → DAG校验(检测循环依赖)
├── onTaskCompleted(task) → 任务完成时触发
│ ├── 查找匹配的协作规则: rules.filter(r => r.sourceStaffId === task.assignedTo)
│ ├── 检查触发条件: r.triggerCondition === 'task_status=completed'
│ └── 创建下一任务: createTask({ assignedTo: r.targetStaffId, ... })
├── onTaskFailed(task) → 任务失败时触发
│ ├── 查找失败规则
│ └── 暂停协作链 + 通知发起人
└── getCollaborationChain(taskId) → 查询完整协作链路
└── 从 staff_tasks.collaboration_chain JSON 解析
集成点:
task-board.js的completeTask()行193-220 已支持collaborationNext参数staff-manager.js的createTask()行327-380staff-manager.js的staff_tasks.collaboration_chain列(行114)
R2: 协作规则配置驱动
新增 server/digital-staff/collaboration-rules.yaml:
# 数字员工协作规则
# sourceStaffId → targetStaffId: 当源员工完成任务后自动触发目标员工
rules:
- sourceStaffId: DS-PROC-001 # 采购助手
targetStaffId: DS-COST-001 # 成本优化师
triggerCondition: task_status=completed
triggerEvent: task_completed
delaySeconds: 0
enabled: true
- sourceStaffId: DS-COST-001 # 成本优化师
targetStaffId: DS-VEN-001 # 供应商管家
triggerCondition: task_status=completed
triggerEvent: task_completed
delaySeconds: 0
enabled: true
- sourceStaffId: DS-ECR-001 # ECR审核员
targetStaffId: DS-DATA-001 # 数据书记员
triggerCondition: task_status=completed
triggerEvent: task_completed
delaySeconds: 5
enabled: true
规则热加载:
collaboration-scheduler.js
├── _watchTimer = setInterval(loadRules, 30000) // 30秒检查一次
└── 文件修改时间变化 → 重新加载 + validateRules()
R3: 协作链可视化(P2方向)
在 src/views/DigitalStaff.vue 的任务看板区域增加协作链路图:
- 使用简单的流程图组件(SVG/Canvas)
- 显示: 采购询价(✓) → 成本分析(进行中) → 供应商评估(待执行)
- 每个节点可点击查看任务详情
#### 文件变更清单
| 操作 | 文件路径 | 变更说明 |
|------|---------|---------|
| 新增 | server/digital-staff/collaboration-scheduler.js | 协作调度器 |
| 新增 | server/digital-staff/collaboration-rules.yaml | 协作规则配置 |
| 修改 | server/digital-staff/task-board.js | completeTask 触发 collaboration-scheduler |
| 修改 | server/routes/digital-staff-routes.js | 新增协作链查询API |
1.3.7 模块G:关系感知引擎(V1.1,P0+P1)
#### 现有架构分析
| 现有模块 | 文件路径 | 现状 | 缺口 |
|---------|---------|------|------|
| 关系解析器 | server/core/relationship-resolver.js | 已实现 resolveExistence/discoverRelations/buildLinkPlan/executePlan | 未在BOM/ECO/产品创建流程中自动调用 |
| 关系能力 | server/core/relationship-capability.js | 已实现 identifyRelations/createRelation/removeRelation/queryRelations | 功能完整 |
| 关系检查 | server/core/relationship-checklist.js | 已实现 preCheck/postValidate | postValidate 未在创建流程后自动调用 |
#### 实现方案
R1: BOM自动关联
在 bom-import-service.js 的 importBom() 流程中集成(已在模块E中设计):
importBom(excelBuffer, options)
├── ... (解析+列映射+树构建)
├── 对每个零件:
│ ├── relationshipResolver.resolveExistence('Part', partData)
│ │ ├── 已存在 → 标记 reuse, 关联已有对象
│ │ └── 不存在 → 标记 create, 创建新对象
│ └── 记录关联操作日志
└── relationshipResolver.buildLinkPlan('Part', parts)
→ 生成关联执行计划
R2: ECO自动关联
在ECO创建流程中(server/routes/change.js 或 CapabilityDispatcher 路由)插入关系发现:
创建ECO时:
├── 1. 正常创建ECO对象
├── 2. relationshipCapability.identifyRelations('ECO', ecoData)
│ ├── 识别关联的BOM(通过 affected_items 字段)
│ ├── 识别关联的Part(通过 change_subject 字段)
│ └── 识别关联的文档(通过 document_refs 字段)
├── 3. 自动创建关系: ECO→BOM, ECO→Part, ECO→Document
└── 4. relationshipChecklist.postValidate(ecoId, 'ECO')
→ 返回完整性评分 + 建议
集成点:
relationshipCapability.identifyRelations()在server/core/relationship-capability.js行50-67relationshipChecklist.postValidate()在server/core/relationship-checklist.js行216-253- 需在
server/routes/change.js的创建路由中增加关系发现调用
R3: 产品自动关联
类似ECO,在产品创建流程中插入关系发现:
创建产品时:
├── 1. 正常创建Product对象
├── 2. relationshipResolver.discoverRelations('Product', [productData])
│ ├── 发现关联的BOM(通过 product_name 字段匹配)
│ └── 发现关联的文档(通过 document_refs 字段)
├── 3. relationshipResolver.buildLinkPlan('Product', [productData])
└── 4. relationshipResolver.executePlan(...)
R4: 关系完整性评分
增强 relationship-checklist.js 的 postValidate() 返回值:
postValidate(itemId, itemType)
├── 现有逻辑: 检查 REQUIRED_RELATIONS 中必须存在的关系
├── 新增: 计算完整性评分
│ ├── score = (已建立关系数 / 必需关系数) * 100
│ └── missingRelations = 必需但未建立的关系列表
└── 返回: { score, missingRelations, suggestions }
├── score=100 → "✅ 完整性评分 100%,所有必需关系已建立"
├── score=60 → "⚠️ 完整性评分 60%,建议补充:供应商关联、质量文档"
└── score=0 → "🔴 孤立对象,建议手动关联"
集成点:
REQUIRED_RELATIONS在relationship-checklist.js行64-78 定义CHECKLISTS在行19-58 定义
#### 文件变更清单
| 操作 | 文件路径 | 变更说明 |
|------|---------|---------|
| 修改 | server/services/bom-import-service.js | 集成 resolveExistence + buildLinkPlan |
| 修改 | server/routes/change.js | ECO创建后调用 identifyRelations + postValidate |
| 修改 | server/core/relationship-checklist.js | postValidate 增加完整性评分计算 |
| 修改 | src/views/BomAssistant.vue | 展示完整性评分和关联建议 |
1.3.8 模块H:多租户安全加固(P0)
#### 现有架构分析
| 现有模块 | 文件路径 | 现状 | 缺口 |
|---------|---------|------|------|
| 认证中间件 | server/middleware/auth.js | 已实现 softAuth 注入 enterpriseId | 未强制注入到SCSAI查询 |
| 租户DB | server/services/tenant-db.js | 已有 enterprises + user 表 | 无配额管理 |
| SCSAI客户端 | server/utils/SCSAI-client.js | 通用AML查询 | 无 enterprise_id 自动过滤 |
#### 实现方案
R1: 租户中间件自动注入
新增 server/middleware/tenant-middleware.js:
tenant-middleware.js
├── tenantInject(req, res, next)
│ ├── 从 req.enterpriseId (softAuth已注入) 获取租户ID
│ ├── 若无 → enterprise_id = 'default' (公共租户)
│ ├── 注入到 req.tenantContext = { enterpriseId, role }
│ └── next()
└── SCSAIQueryFilter(amlQuery, enterpriseId)
├── 在 AML <Item> 中注入 <enterprise_id>enterpriseId</enterprise_id>
└── 返回修改后的 AML
在 server.js 的 handleRequest 中,将 softAuth 替换为 softAuth + tenantInject 组合:
// 行1419-1435 区域
if (pathname.startsWith('/api/')) {
softAuth(req, res, () => {
tenantInject(req, res, () => {
// 继续路由处理
});
});
}
集成点:
softAuth在server/middleware/auth.js行52-68- SCSAI AML查询在
server/utils/SCSAI-client.js - 需在 SCSAIClient 的查询方法中增加 enterprise_id 过滤参数
R2: 租户数据隔离验证
在 tenant-middleware.js 中增加数据隔离校验:
tenantDataGuard(req, res, next)
├── 对写操作(POST/PUT/DELETE):
│ ├── 从请求体提取目标对象的 enterprise_id
│ ├── 若与 req.enterpriseId 不一致 → 403 Forbidden
│ └── 记录越权访问审计日志
└── 对读操作(GET):
└── 已由 SCSAIQueryFilter 自动过滤
审计日志:
audit_logs 表新增记录:
{ action: 'tenant_access_denied', user_id, enterprise_id, target_enterprise_id, resource, timestamp }
集成点:
audit-log.js在server/services/audit-log.jstenant-db.js的audit_logs表
R3: 租户配额限制(P2方向)
新增 tenant_quotas 表(见数据模型4.2),在创建数据前检查配额。
#### 文件变更清单
| 操作 | 文件路径 | 变更说明 |
|------|---------|---------|
| 新增 | server/middleware/tenant-middleware.js | 租户注入+数据隔离中间件 |
| 修改 | server.js | handleRequest 中 softAuth 后增加 tenantInject |
| 修改 | server/utils/SCSAI-client.js | 查询方法增加 enterprise_id 过滤参数 |
| 修改 | server/services/tenant-db.js | 新增 tenant_quotas 表 |
1.3.9 模块I:微信发布服务统一(P0+P1)
#### 现有架构分析
| 现有模块 | 文件路径 | 现状 | 缺口 |
|---------|---------|------|------|
| 微信发布 | server/services/wechat-publish.js | 使用 MINIPROGRAM_APPID/MINIPROGRAM_SECRET | 需统一为 WECHAT_APP_ID/WECHAT_APP_SECRET |
| 内容API | server/routes/content-api.js | 调用 wechat-publish | 需同步修改环境变量引用 |
#### 实现方案
R1: 环境变量统一
修改 server/services/wechat-publish.js:
// 行32-33 修改:
const appid = process.env.WECHAT_APP_ID || process.env.MINIPROGRAM_APPID;
const secret = process.env.WECHAT_APP_SECRET || process.env.MINIPROGRAM_SECRET;
// 新增启动检查:
if (process.env.MINIPROGRAM_APPID && !process.env.WECHAT_APP_ID) {
console.warn('[WeChat] ⚠️ MINIPROGRAM_APPID 已废弃,请迁移到 WECHAT_APP_ID');
}
if (process.env.WECHAT_APP_ID) {
console.log('[WeChat] ✅ 微信配置已统一 (WECHAT_APP_ID)');
}
兼容策略:优先读 WECHAT_APP_ID,回退到 MINIPROGRAM_APPID,启动时打印迁移提示。
R2: 发布失败自动重试
修改 wechat-publish.js 的 publishArticle() 方法:
publishArticle(title, content, options)
├── _retryPublish(draftMediaId, retryCount = 0)
│ ├── 调用 publishDraft(mediaId)
│ ├── 成功 → 返回结果
│ ├── 失败 && retryCount < 3 → 等待5秒 → _retryPublish(mediaId, retryCount + 1)
│ └── 失败 && retryCount >= 3 → 标记"发布失败" + 通知用户
└── 返回: { success, publish_id, retry_count }
R3: 已发布文章管理(P2方向)
新增 published_articles 表,记录 publish_id + publish_time,支持查询和管理。
#### 文件变更清单
| 操作 | 文件路径 | 变更说明 |
|------|---------|---------|
| 修改 | server/services/wechat-publish.js | 环境变量统一 + 重试逻辑 |
| 修改 | server/routes/content-api.js | 同步环境变量引用 |
| 修改 | .env.example | 新增 WECHAT_APP_ID/WECHAT_APP_SECRET 说明 |
1.3.10 模块J:邮件即指令(V1.2方向,P0+P1)
#### 现有架构分析
| 现有模块 | 文件路径 | 现状 | 缺口 |
|---------|---------|------|------|
| 邮件监听 | server/services/email-listener.js | IMAP连接硬编码 imap.sina.com | 需配置化 |
| 报价解析 | server/services/llm-quotation-service.js | 仅解析采购报价 | 需通用命令解析 |
#### 实现方案
R1: 通用邮件命令解析(P1方向)
新增 server/services/email-command-parser.js:
email-command-parser.js
├── loadTemplates() → 从 email-commands.yaml 加载命令模板
├── parseCommand(emailData) → 解析邮件为业务命令
│ ├── 遍历模板,匹配 subjectPattern / bodyPattern
│ ├── 提取参数: params = extractParams(emailData, template.params)
│ └── 返回: { action, params, template } 或 null
├── executeCommand(command) → 执行业务操作
│ ├── ecr_approve → 调用 ECR 状态变更
│ ├── procurement_confirm → 调用采购确认
│ └── ... 其他命令
└── watchTemplates() → 30秒检查一次YAML文件变化
R2: 邮件命令模板配置(P1方向)
新增 server/config/email-commands.yaml:
# 邮件命令模板
commands:
- name: ecr_approve
subjectPattern: "/审批通过|approved/i"
bodyPattern: null
action: ecr.approve
params:
ecr_id: "/ECR-\\d{4}-\\d{3}/"
priority: 1
enabled: true
- name: procurement_confirm
subjectPattern: "/报价|quotation/i"
bodyPattern: "/价格|price/i"
action: procurement.confirm
params:
vendor: "/from:\\s*(.+)/"
priority: 2
enabled: true
R3: 邮件监听IMAP配置化(P0)
修改 server/services/email-listener.js:
// 行22-31 修改:
this.client = new ImapFlow({
host: this.config.imapHost || process.env.EMAIL_IMAP_HOST || 'imap.sina.com',
port: this.config.imapPort || parseInt(process.env.EMAIL_IMAP_PORT) || 993,
secure: true,
auth: {
user: this.config.user,
pass: this.config.pass
},
logger: false
});
新增重连计数和告警:
reconnectCount = 0
MAX_RECONNECT = 5
scheduleReconnect()
├── reconnectCount++
├── if (reconnectCount >= MAX_RECONNECT)
│ ├── 停止重连
│ └── 发送飞书告警: "邮件监听服务已停止"
└── else → 30秒后重连
集成点:
config.yaml新增email.imap.host和email.imap.portfeishuService.sendMessageToUser()发送告警
#### 文件变更清单
| 操作 | 文件路径 | 变更说明 |
|------|---------|---------|
| 新增 | server/services/email-command-parser.js | 通用邮件命令解析器 |
| 新增 | server/config/email-commands.yaml | 邮件命令模板配置 |
| 修改 | server/services/email-listener.js | IMAP配置化 + 重连计数告警 |
| 修改 | config.yaml | 新增 email.imap 配置节 |
2. 接口设计
2.1 总体设计
API设计原则
- 三端统一: 所有API通过
/api/pipeline/execute统一入口,source字段区分来源(web/feishu/miniapp/scheduler) - RESTful风格: 资源型API使用标准HTTP方法,动作型API使用POST
- 统一响应格式:
{ success: boolean, data?: any, error?: string, traceId?: string } - JWT认证: 所有API走 softAuth(不阻断),写操作走 authMiddleware(强制认证)
- 路由注册: 所有新增API必须在
server.js的handleRequest中注册
路由注册模式
// server.js handleRequest 中新增路由的标准模式:
if (pathname.startsWith('/api/xxx/')) {
const xxxRoutes = require('./server/routes/xxx');
collectBody(req).then(bodyStr => {
xxxRoutes.handleXxxRoute(req, res, pathname, query, bodyStr);
}).catch(catchHandler(req, res, 'xxx'));
return;
}
2.2 接口清单
2.2.1 语音决策链路 API
| 方法 | 路径 | 参数 | 返回值 | 优先级 | 备注 |
|------|------|------|--------|--------|------|
| POST | /api/asr/recognize | multipart: audio文件 | { success, text, provider } | P0 | 已实现 |
| POST | /api/digital-staff/chat | { staffId, message, source: 'asr' } | { reply, actions } | P0 | 增强source参数 |
| POST | /api/feishu/voice-approve | { pendingId, action } | { success, result } | P0 | 新增 |
2.2.2 小程序统一 API
| 方法 | 路径 | 参数 | 返回值 | 优先级 | 备注 |
|---|---|---|---|---|---|
| POST | /api/miniapp/login | { code } | { success, token, user } | P0 | 新增 |
| GET | /api/miniapp/dashboard | - | { productCount, changeCount, ruleCount, staffCount } | P1 | 新增 |
| GET | /api/miniapp/user-info | - | { user } | P0 | 新增 |
| POST | /api/miniapp/bind-user | { username, password } | { success, token, user } | P0 | 新增 |
| GET | /api/miniapp/notifications | page, pageSize | { list, total, unreadCount } | P1 | 新增 |
| PUT | /api/miniapp/notifications/:id/read | - | { success } | P1 | 新增 |
| POST | /api/miniapp/subscribe | { tmplIds } | { success } | P1 | 新增 |
2.2.3 飞书集成 API
| 方法 | 路径 | 参数 | 返回值 | 优先级 | 备注 |
|---|---|---|---|---|---|
| POST | /api/feishu/event | 飞书事件回调body | { challenge } 或空 | P1 | 新增 |
| POST | /api/feishu/approval/callback | 飞书审批回调body | { success } | P1 | 新增 |
| GET | /api/feishu/pending-actions | userId | { list: PendingAction[] } | P0 | 新增 |
2.2.4 采购订单 API
| 方法 | 路径 | 参数 | 返回值 | 优先级 | 备注 |
|---|---|---|---|---|---|
| POST | /api/purchase-order/create | { supplierId, items, deliveryDate } | { success, poId } | P0 | 新增 |
| GET | /api/purchase-order/:poId | - | { po } | P0 | 新增 |
| GET | /api/purchase-order/list | status, page, pageSize | { list, total } | P0 | 新增 |
| POST | /api/purchase-order/:poId/approve | { approvedBy } | { success } | P0 | 新增 |
| POST | /api/purchase-order/:poId/confirm | - | { success } | P0 | 新增 |
| POST | /api/purchase-order/:poId/complete | - | { success } | P0 | 新增 |
| POST | /api/purchase-order/:poId/cancel | { reason } | { success } | P0 | 新增 |
2.2.5 BOM导入 API
| 方法 | 路径 | 参数 | 返回值 | 优先级 | 备注 |
|---|---|---|---|---|---|
| POST | /api/bom/import/upload | multipart: Excel文件 | { tree, matchResults, linkPlan } | P0 | 新增 |
| POST | /api/bom/import/confirm | { mapping, linkPlan } | { created, linked, warnings } | P0 | 新增 |
| POST | /api/bom/import/map-columns | { headers } | { mapping, confidence } | P0 | 新增 |
2.2.6 数字员工协作 API
| 方法 | 路径 | 参数 | 返回值 | 优先级 | 备注 |
|---|---|---|---|---|---|
| GET | /api/digital-staff/collaboration/rules | - | { rules } | P1 | 新增 |
| POST | /api/digital-staff/collaboration/rules | { rule } | { success } | P1 | 新增 |
| GET | /api/digital-stuff/collaboration/chain/:taskId | - | { chain } | P1 | 新增 |
2.2.7 关系感知 API
| 方法 | 路径 | 参数 | 返回值 | 优先级 | 备注 |
|---|---|---|---|---|---|
| POST | /api/relationship/resolve-existence | { itemType, itemData } | { exists, matchType, SCSAIId } | P0 | 已有 |
| POST | /api/relationship/discover | { itemType, items } | { relations, graph } | P0 | 已有 |
| GET | /api/relationship/score/:itemId | itemType | { score, missingRelations, suggestions } | P1 | 新增 |
2.2.8 多租户 API
| 方法 | 路径 | 参数 | 返回值 | 优先级 | 备注 |
|---|---|---|---|---|---|
| GET | /api/tenant/quota | - | { quotas, usage } | P2 | 新增 |
| GET | /api/tenant/audit-logs | page, pageSize | { list, total } | P0 | 新增 |
3. 数据模型
3.1 设计目标
- 兼容现有: 所有新表通过
db-adapter.js的createDatabase()创建,支持 SQLite/MySQL 双后端 - 幂等建表: 使用
CREATE TABLE IF NOT EXISTS+ALTER TABLE ADD COLUMN(忽略重复列错误) - 统一ID格式: 业务ID使用
前缀-日期-序号格式(如PO-20260624-0001),技术ID使用 UUID - 时间字段: 统一使用 ISO 8601 字符串格式(
new Date().toISOString())
3.2 模型实现
3.2.1 purchase_orders — 采购订单表(新增)
CREATE TABLE IF NOT EXISTS purchase_orders (
po_id TEXT PRIMARY KEY, -- PO-{YYYYMMDD}-{seq4}
supplier_id TEXT NOT NULL, -- 供应商ID
supplier_name TEXT DEFAULT '', -- 供应商名称(冗余)
items TEXT DEFAULT '[]', -- JSON数组: [{partNumber, name, quantity, unitPrice, currency}]
status TEXT DEFAULT 'pending_approval', -- pending_approval/approved/confirmed/shipped/completed/cancelled
total_amount REAL DEFAULT 0, -- 自动计算自items汇总
currency TEXT DEFAULT 'CNY',
approved_by TEXT DEFAULT '', -- 审批人ID
approved_at TEXT DEFAULT '', -- 审批时间
delivery_date TEXT DEFAULT '', -- 预计交付日期
notes TEXT DEFAULT '',
enterprise_id TEXT DEFAULT 'default', -- 多租户隔离
created_by TEXT DEFAULT '',
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_po_status ON purchase_orders(status);
CREATE INDEX IF NOT EXISTS idx_po_supplier ON purchase_orders(supplier_id);
CREATE INDEX IF NOT EXISTS idx_po_enterprise ON purchase_orders(enterprise_id);
3.2.2 feishu_pending_actions — 飞书挂起操作表(新增)
CREATE TABLE IF NOT EXISTS feishu_pending_actions (
id TEXT PRIMARY KEY, -- UUID
action TEXT NOT NULL, -- approve/reject/confirm/cancel/voice_approve
business_type TEXT DEFAULT '', -- ecr/bom/procurement/vendor
business_id TEXT DEFAULT '', -- 业务对象ID
user_id TEXT DEFAULT '', -- 发起人ID
feishu_user_id TEXT DEFAULT '', -- 飞书用户open_id
card_message_id TEXT DEFAULT '', -- 飞书卡片消息ID
payload TEXT DEFAULT '{}', -- JSON操作参数
created_at TEXT DEFAULT (datetime('now')),
expires_at TEXT NOT NULL, -- created_at + 10分钟
consumed_at TEXT DEFAULT '', -- 消费时间
enterprise_id TEXT DEFAULT 'default'
);
CREATE INDEX IF NOT EXISTS idx_fpa_user ON feishu_pending_actions(feishu_user_id);
CREATE INDEX IF NOT EXISTS idx_fpa_expires ON feishu_pending_actions(expires_at);
CREATE INDEX IF NOT EXISTS idx_fpa_consumed ON feishu_pending_actions(consumed_at);
3.2.3 collaboration_rules — 协作规则表(新增)
注:协作规则主要通过 collaboration-rules.yaml 配置驱动,此表用于运行时缓存和API查询。
CREATE TABLE IF NOT EXISTS collaboration_rules (
id TEXT PRIMARY KEY,
source_staff_id TEXT NOT NULL, -- DS-PROC-001
target_staff_id TEXT NOT NULL, -- DS-COST-001
trigger_condition TEXT DEFAULT 'task_status=completed',
trigger_event TEXT DEFAULT 'task_completed', -- task_completed/task_failed/task_escalated
delay_seconds INTEGER DEFAULT 0,
enabled INTEGER DEFAULT 1,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_cr_source ON collaboration_rules(source_staff_id);
3.2.4 notifications — 通知表(新增)
CREATE TABLE IF NOT EXISTS notifications (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
title TEXT DEFAULT '',
content TEXT DEFAULT '',
type TEXT DEFAULT 'info', -- info/warning/action/approval
source TEXT DEFAULT 'system', -- system/feishu/miniapp/web
business_type TEXT DEFAULT '', -- ecr/bom/procurement/vendor
business_id TEXT DEFAULT '',
read INTEGER DEFAULT 0,
enterprise_id TEXT DEFAULT 'default',
created_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_notif_user ON notifications(user_id);
CREATE INDEX IF NOT EXISTS idx_notif_read ON notifications(user_id, read);
3.2.5 user表扩展(修改)
-- 新增列(幂等)
ALTER TABLE user ADD COLUMN wx_openid TEXT DEFAULT '';
ALTER TABLE user ADD COLUMN wx_session_key TEXT DEFAULT '';
CREATE INDEX IF NOT EXISTS idx_user_wx_openid ON user(wx_openid);
3.2.6 tenant_quotas — 租户配额表(P2方向)
CREATE TABLE IF NOT EXISTS tenant_quotas (
enterprise_id TEXT PRIMARY KEY,
max_parts INTEGER DEFAULT 10000,
max_boms INTEGER DEFAULT 1000,
max_users INTEGER DEFAULT 50,
max_staff_tasks INTEGER DEFAULT 5000,
current_parts INTEGER DEFAULT 0,
current_boms INTEGER DEFAULT 0,
updated_at TEXT DEFAULT (datetime('now'))
);
3.2.7 email_command_templates — 邮件命令模板表(P1方向)
注:主要通过 email-commands.yaml 配置驱动,此表用于管理界面编辑。
CREATE TABLE IF NOT EXISTS email_command_templates (
id TEXT PRIMARY KEY,
name TEXT NOT NULL, -- ecr_approve
subject_pattern TEXT DEFAULT '', -- 正则
body_pattern TEXT DEFAULT '', -- 正则(可选)
action TEXT NOT NULL, -- ecr.approve
params TEXT DEFAULT '{}', -- JSON参数模板
priority INTEGER DEFAULT 10,
enabled INTEGER DEFAULT 1,
created_at TEXT DEFAULT (datetime('now'))
);
4. 前端组件设计
4.1 小程序端
VoiceInput.vue(重写)
Props: 无
Emits: result(text), error(msg), start, end
State: isRecording, audioPath
Methods:
├── onStart() → uni.getRecorderManager().start({ format:'pcm', sampleRate:16000 })
├── onStop() → recorderManager.stop() → onUpload()
├── onUpload() → uni.uploadFile({ url, filePath, name:'audio', header:{Authorization} })
└── onResult(res) → emit('result', res.text)
BomTreeGraph.vue(新增,网页端)
Props: tree(BomNode[]), matchResults(Map)
Emits: node-click(node), expand-toggle(node)
State: zoom, panX, panY, expandedNodes(Set)
渲染:
├── SVG树形图,节点=零件卡片,边=父子关系
├── 节点状态: ✅已关联(绿) / ⚠️待确认(黄) / 🔴孤立(红)
├── 交互: 鼠标滚轮缩放、拖拽平移、点击展开/收起
└── 点击节点 → emit('node-click') → 父组件显示详情面板
4.2 网页端
BomAssistant.vue(增强)
新增区域:
├── Excel导入区: <input type="file" @change="onFileUpload" accept=".xlsx,.xls,.csv" />
├── 列映射确认弹窗: 显示AI识别的列映射,支持手动调整
├── BomTreeGraph: <BomTreeGraph :tree="bomTree" @node-click="showPartDetail" />
└── 完整性评分: 显示评分 + 缺失关系建议
DigitalStaff.vue(增强)
新增区域:
├── 协作规则管理: 列表+编辑(从YAML加载)
├── 协作链可视化: 流程图展示任务链路
└── 采购订单管理: PO列表+状态流转
5. 风险点与替代方案
5.1 风险点
| 风险 | 影响 | 概率 | 缓解措施 |
|------|------|------|---------|
| 讯飞ASR API不稳定 | 语音识别功能不可用 | 中 | 已有Echo模式降级;可增加阿里云ASR作为第二后端 |
| 飞书审批API需企业认证 | 审批流集成无法测试 | 高 | 降级为卡片消息确认模式(已实现) |
| 微信小程序审核周期长 | 小程序发布延迟 | 中 | 先用体验版/开发版测试,审核期间网页端先行 |
| xlsx库体积较大 | 前端打包体积增大 | 低 | 仅后端使用xlsx解析,前端只上传文件 |
| pendingActions持久化性能 | 高频读写影响SQLite | 低 | 内存Map做一级缓存,SQLite做二级持久化 |
| 多租户enterprise_id遗漏 | 数据隔离不完整 | 中 | 中间件自动注入 + 审计日志 + 定期巡检 |
5.2 替代方案
| 场景 | 主方案 | 替代方案 |
|---|---|---|
| 语音识别 | 讯飞iFlytek REST API | 阿里云智能语音/百度语音/浏览器Web Speech API |
| BOM图形化 | 自研SVG树组件 | 使用 G6/AntV X6 图可视化库 |
| 协作规则引擎 | 自研YAML配置+调度器 | 使用 Bull/BullMQ 任务队列 |
| 消息同步 | 自研notification-sync | 使用 WebSocket 实时推送 |
| 邮件命令解析 | YAML模板+正则匹配 | 纯LLM意图识别(成本更高但更灵活) |
6. 实现优先级与里程碑
6.1 P0 里程碑(V1.0核心,约21.5天)
| 阶段 | 需求 | 工时 | 依赖 |
|---|---|---|---|
| 第一周 | 5.1 语音决策链路 (R1+R2+R3) | 7天 | ASR服务已就绪 |
| 第一周 | 5.2 微信登录 (R1) | 2天 | 无 |
| 第一周 | 5.3 pendingActions持久化 (R1) | 1天 | 无 |
| 第二周 | 5.4 采购订单创建与跟踪 (R1) | 3天 | 无 |
| 第二周 | 5.5 BOM Excel导入 (R1+R3) | 5天 | relationship-resolver已就绪 |
| 第二周 | 5.9 租户中间件 (R1+R2) | 5天 | auth.js已就绪 |
| 第三周 | 5.10 微信环境变量统一 (R1) | 0.5天 | 无 |
| 第三周 | 5.8 IMAP配置化 (R3) | 1天 | 无 |
6.2 P1 里程碑(V1.0增强,约24天)
| 阶段 | 需求 | 工时 | 依赖 |
|---|---|---|---|
| 第三周 | 5.2 小程序数据对接+消息同步 (R3+R4) | 6天 | P0 API已就绪 |
| 第三周 | 5.3 飞书加密解密+审批流 (R2+R3) | 5天 | 飞书企业认证 |
| 第四周 | 5.4 1688降级+报价增强 (R2+R3) | 3天 | P0采购订单 |
| 第四周 | 5.5 BOM图形化展示 (R2) | 3天 | P0 BOM导入 |
| 第四周 | 5.6 数字员工协作 (R1+R2) | 5天 | task-board已就绪 |
| 第五周 | 5.7 关系感知引擎 (R1-R4) | 10天 | relationship-*已就绪 |
| 第五周 | 5.8 邮件命令解析 (R1+R2) | 5天 | email-listener已就绪 |
| 第五周 | 5.10 发布重试 (R2) | 1天 | P0环境变量统一 |
6.3 P2 方向(V1.1+)
| 需求 | 方向 |
|---|---|
| 5.6 协作链可视化 | 网页端流程图组件 |
| 5.9 租户配额限制 | tenant_quotas表+创建前检查 |
| 5.10 已发布文章管理 | published_articles表+管理界面 |
7. 与现有代码的集成点汇总
| 集成点 | 文件路径 | 行号/方法 | 说明 |
|---|---|---|---|
| ASR路由 | server.js | 行1534-1605 | /api/asr/recognize 已注册 |
| Pipeline入口 | server.js | 行2060-2085 | /api/pipeline/execute 已注册 |
| BOM路由 | server.js | 行1668-1832 | /api/bom/ 前缀已注册 |
| 数字员工路由 | server.js | 行2016-2026 | /api/digital-staff/ 前缀 |
| softAuth注入 | server.js | 行1419-1435 | softAuth+tenantInject组合 |
| SmartLLMRouter | server/digital-staff/smart-llm-router.js | 行486 call() | LLM调用唯一入口 |
| CapabilityDispatcher | server/core/capability-dispatcher.js | 行37 execute() | 能力调度唯一入口 |
| IntentEngine | server/core/intent-engine.js | 行291 recognize() | 意图识别入口 |
| ConversationEngine | server/digital-staff/conversation-engine.js | 行116 sendMessage() | 对话引擎入口 |
| TaskBoard | server/digital-staff/task-board.js | 行193 completeTask() | 任务完成+协作链触发 |
| StaffManager | server/digital-staff/staff-manager.js | 行327 createTask() | 任务创建 |
| pendingActions | server/feishu-bot.js | 行323 Map + 行352 set + 行359 consume | 挂起操作管理 |
| FeishuService | server/feishu-service.js | 行230 createApproval() | 飞书审批API |
| RelationshipResolver | server/core/relationship-resolver.js | 行137 resolveExistence() | 对象存在性检测 |
| RelationshipCapability | server/core/relationship-capability.js | 行50 identifyRelations() | 关系识别 |
| RelationshipChecklist | server/core/relationship-checklist.js | 行216 postValidate() | 完整性验证 |
| ASRService | server/services/asr-service.js | 行235 recognize() | 语音识别入口 |
| Alibaba1688Service | server/services/alibaba-1688-service.js | 行151 searchSourcing() | 供应商寻源 |
| EmailListenerService | server/services/email-listener.js | 行18 start() | 邮件监听 |
| LLMQuotationService | server/services/llm-quotation-service.js | 行92 llmParseQuotation() | 报价解析 |
| WechatPublish | server/services/wechat-publish.js | 行32 MINIPROGRAM_APPID | 环境变量引用 |
| TenantDB | server/services/tenant-db.js | user表 | 用户数据 |
| AuthMiddleware | server/middleware/auth.js | 行52 softAuth() | JWT认证 |
| DBAdapter | server/db-adapter.js | 行130 createDatabase() | 数据库创建 |
| 小程序API | bossagents-miniapp/src/api/miniapp.js | miniappApi | 小程序API封装 |
| 小程序Store | bossagents-miniapp/src/store/index.js | useUserStore | 用户状态管理 |
| VoiceInput | bossagents-miniapp/src/components/VoiceInput.vue | 组件 | 语音输入(需重写) |
| i18n | frontend/i18n.js | t() | 国际化翻译 |
BossAgents