左帮右臂 — 技术设计文档(优化方案)

左帮右臂 — 技术设计文档(优化方案)

版本: 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.jssendMessage() 方法中增加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' → 走现有逻辑

集成点:

  • pendingActions Map 在 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-7
  • tenant-db.jsuser 表(行定义在 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-348
  • unifiedMessages.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 中的 pendingActions Map 保留,作为一级缓存
  • setPendingAction() 同时写入 Map + SQLite
  • consumePendingAction() 先从 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.jscreateDatabase() 创建数据库实例

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-247
  • feishuService.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.jsstaff_tasks 表关联 PO
  • feishu-bot.js 的卡片构建函数增加采购审批卡片
  • email-service.js 发送采购订单邮件

R2: 1688降级体验优化

修改 alibaba-1688-service.jssearchSourcing() 方法(行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.jsnewEmail 事件处理,增加与采购任务的关联:

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-171
  • staff-manager.jsupdateTask() 更新任务状态

#### 文件变更清单

| 操作 | 文件路径 | 变更说明 |

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

| 新增 | 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.js
  • relationshipResolver.resolveExistence()server/core/relationship-resolver.js 行137-233
  • relationshipResolver.buildLinkPlan() 在行371-467
  • server.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 调用)。

三级检测逻辑(已有,无需修改):

  1. SCSAI item_number 精确查
  2. SCSAI name 精确查
  3. SCSAI name 模糊查(相似度≥0.4)
  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.jscompleteTask() 行193-220 已支持 collaborationNext 参数
  • staff-manager.jscreateTask() 行327-380
  • staff-manager.jsstaff_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.jsimportBom() 流程中集成(已在模块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-67
  • relationshipChecklist.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.jspostValidate() 返回值:

postValidate(itemId, itemType)
  ├── 现有逻辑: 检查 REQUIRED_RELATIONS 中必须存在的关系
  ├── 新增: 计算完整性评分
  │   ├── score = (已建立关系数 / 必需关系数) * 100
  │   └── missingRelations = 必需但未建立的关系列表
  └── 返回: { score, missingRelations, suggestions }
      ├── score=100 → "✅ 完整性评分 100%,所有必需关系已建立"
      ├── score=60  → "⚠️ 完整性评分 60%,建议补充:供应商关联、质量文档"
      └── score=0   → "🔴 孤立对象,建议手动关联"

集成点:

  • REQUIRED_RELATIONSrelationship-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.jshandleRequest 中,将 softAuth 替换为 softAuth + tenantInject 组合:

// 行1419-1435 区域
if (pathname.startsWith('/api/')) {
    softAuth(req, res, () => {
        tenantInject(req, res, () => {
            // 继续路由处理
        });
    });
}

集成点:

  • softAuthserver/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.jsserver/services/audit-log.js
  • tenant-db.jsaudit_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.jspublishArticle() 方法:

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.hostemail.imap.port
  • feishuService.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设计原则

  1. 三端统一: 所有API通过 /api/pipeline/execute 统一入口,source 字段区分来源(web/feishu/miniapp/scheduler)
  2. RESTful风格: 资源型API使用标准HTTP方法,动作型API使用POST
  3. 统一响应格式: { success: boolean, data?: any, error?: string, traceId?: string }
  4. JWT认证: 所有API走 softAuth(不阻断),写操作走 authMiddleware(强制认证)
  5. 路由注册: 所有新增API必须在 server.jshandleRequest 中注册

路由注册模式

// 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/notificationspage, 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-actionsuserId{ 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/liststatus, 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/uploadmultipart: 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/:itemIditemType{ score, missingRelations, suggestions }P1新增

2.2.8 多租户 API

方法路径参数返回值优先级备注
GET/api/tenant/quota-{ quotas, usage }P2新增
GET/api/tenant/audit-logspage, pageSize{ list, total }P0新增

3. 数据模型

3.1 设计目标

  1. 兼容现有: 所有新表通过 db-adapter.jscreateDatabase() 创建,支持 SQLite/MySQL 双后端
  2. 幂等建表: 使用 CREATE TABLE IF NOT EXISTS + ALTER TABLE ADD COLUMN(忽略重复列错误)
  3. 统一ID格式: 业务ID使用 前缀-日期-序号 格式(如 PO-20260624-0001),技术ID使用 UUID
  4. 时间字段: 统一使用 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-1435softAuth+tenantInject组合
SmartLLMRouterserver/digital-staff/smart-llm-router.js行486 call()LLM调用唯一入口
CapabilityDispatcherserver/core/capability-dispatcher.js行37 execute()能力调度唯一入口
IntentEngineserver/core/intent-engine.js行291 recognize()意图识别入口
ConversationEngineserver/digital-staff/conversation-engine.js行116 sendMessage()对话引擎入口
TaskBoardserver/digital-staff/task-board.js行193 completeTask()任务完成+协作链触发
StaffManagerserver/digital-staff/staff-manager.js行327 createTask()任务创建
pendingActionsserver/feishu-bot.js行323 Map + 行352 set + 行359 consume挂起操作管理
FeishuServiceserver/feishu-service.js行230 createApproval()飞书审批API
RelationshipResolverserver/core/relationship-resolver.js行137 resolveExistence()对象存在性检测
RelationshipCapabilityserver/core/relationship-capability.js行50 identifyRelations()关系识别
RelationshipChecklistserver/core/relationship-checklist.js行216 postValidate()完整性验证
ASRServiceserver/services/asr-service.js行235 recognize()语音识别入口
Alibaba1688Serviceserver/services/alibaba-1688-service.js行151 searchSourcing()供应商寻源
EmailListenerServiceserver/services/email-listener.js行18 start()邮件监听
LLMQuotationServiceserver/services/llm-quotation-service.js行92 llmParseQuotation()报价解析
WechatPublishserver/services/wechat-publish.js行32 MINIPROGRAM_APPID环境变量引用
TenantDBserver/services/tenant-db.jsuser表用户数据
AuthMiddlewareserver/middleware/auth.js行52 softAuth()JWT认证
DBAdapterserver/db-adapter.js行130 createDatabase()数据库创建
小程序APIbossagents-miniapp/src/api/miniapp.jsminiappApi小程序API封装
小程序Storebossagents-miniapp/src/store/index.jsuseUserStore用户状态管理
VoiceInputbossagents-miniapp/src/components/VoiceInput.vue组件语音输入(需重写)
i18nfrontend/i18n.jst()国际化翻译
← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁