左帮右臂 — 编码任务清单(优化方案)
版本: V1.0
日期: 2026-06-24
对应文档: spec-优化方案.md / design-优化方案.md
范围: P0 + P1 任务详细拆解,P2 仅写方向
粒度: 每个任务 0.5-2 天
依赖关系总览
P0 任务依赖图(→ 表示依赖):
T01 ──→ T02 ──→ T03
T04 ──────────────┐
T05 ──────────────┤ (可并行)
T06 ──────────────┤
T07 ──→ T08 ──→ T09
T10 ──────────────┤
T11 ──→ T12 ──→ T13
T14 ──────────────┘
T15
P1 任务依赖图:
T16 ──→ T17
T18 ──→ T19
T20 ──→ T21
T22 ──→ T23
T24 ──→ T25
T26 ──→ T27
T28 ──→ T29
T30 ──→ T31
T32
P0 任务(V1.0 核心,约 21.5 天)
T01. 小程序 VoiceInput.vue 重写 — 录音→上传→识别
- 优先级: P0
- 预估工时: 1.5 天
- 依赖: 无
- 涉及文件:
bossagents-miniapp/src/components/VoiceInput.vue(重写)- 编码步骤:
- 重写
VoiceInput.vue,删除现有空壳代码 - 实现
onStart()— 调用uni.getRecorderManager().start({ format: 'pcm', sampleRate: 16000 }) - 实现
onStop()— 调用recorderManager.stop(),监听onStop回调获取临时文件路径 - 实现
onUpload()— 调用uni.uploadFile({ url: '/api/asr/recognize', filePath, name: 'audio', header: { Authorization: token } }) - 实现
onResult(res)— 解析上传返回的{ success, text },emit('result', text) - 实现
onError(err)—emit('error', msg),显示 toast 提示 - 添加录音状态 UI(按住说话按钮、录音中动画、识别中 loading)
- 添加权限检查:
uni.authorize({ scope: 'scope.record' })
- 验证方法:
- 在小程序 ai-chat 页面引入 VoiceInput,按住说话后松手,确认上传到
/api/asr/recognize并返回识别文本 - ASR 不可用时确认降级到 Echo 模式并显示提示
- 无录音权限时确认弹出授权提示
- 可并行: 是(与 T04/T05/T06 无依赖)
T02. 语音文本意图路由 — ConversationEngine 增强
- 优先级: P0
- 预估工时: 1 天
- 依赖: T01(VoiceInput 需先完成,才能端到端测试)
- 涉及文件:
server/digital-staff/conversation-engine.js(修改)- 编码步骤:
- 在
sendMessage(sessionId, userMessage, options)方法中增加options?.source === 'asr'分支判断 - 当
source === 'asr'时,优先调用IntentEngine.recognize(message)进行意图识别 - 根据识别结果路由到对应数字员工:
procurement→ DS-PROC-001,ecr→ DS-ECR-001 等 - 意图识别失败时路由到 DS-SYS-001(默认引导员工),返回引导性回复
- 保留现有
_detectActionIntent逻辑作为非 ASR 来源的默认路径 - 在
options中增加source字段透传到日志,便于追踪语音链路
- 验证方法:
- 发送
POST /api/digital-staff/chat { staffId, message: "采购100套电机", source: "asr" } - 确认路由到 DS-PROC-001 并返回采购决策卡片
- 发送无法识别的文本,确认路由到 DS-SYS-001 并返回引导回复
- 可并行: 否(依赖 T01)
T03. 飞书语音审批按钮与回调
- 优先级: P0
- 预估工时: 1 天
- 依赖: T02(意图路由需先就绪)
- 涉及文件:
server/feishu-bot.js(修改)- 编码步骤:
- 在飞书卡片构建函数(
buildXxxCard系列)中,当pendingActions.size > 0时追加"🎤 语音审批"按钮 - 当
pendingActions.size === 0时不追加(禁止项) - 在
handleCardAction(action)中增加action === 'voice_approve'分支 voice_approve动作:调用consumePendingAction(pendingId)取回挂起操作 → 执行业务操作(ECR 通过/BOM 发布/采购下单)→ 返回审批结果卡片- 在
server.js的handleRequest中注册POST /api/feishu/voice-approve路由(如果需要独立端点)
- 验证方法:
- 创建一个带 pendingAction 的飞书卡片,确认出现"🎤 语音审批"按钮
- 点击按钮后确认 consumePendingAction 被调用并执行业务操作
- pendingActions 为空时确认卡片不包含语音审批按钮
- 可并行: 否(依赖 T02)
T04. 微信登录后端实现 — miniapp-auth.js
- 优先级: P0
- 预估工时: 1.5 天
- 依赖: 无
- 涉及文件:
server/routes/miniapp-auth.js(新增)server/services/tenant-db.js(修改 — user 表新增 wx_openid 列)server.js(修改 — 注册/api/miniapp/*路由)- 编码步骤:
- 新增
server/routes/miniapp-auth.js,导出handleMiniappRoute(req, res, pathname, query, bodyStr)方法 - 实现
POST /api/miniapp/login:
- 从 body 解析
code - 调用微信
jscode2session:GET https://api.weixin.qq.com/sns/jscode2session?appid=WECHAT_APP_ID&secret=WECHAT_APP_SECRET&js_code=code&grant_type=authorization_code - 降级:若
WECHAT_APP_ID未配置 →openid = 'dev_' + code,日志记录警告 - 查找/创建用户:
SELECT * FROM user WHERE wx_openid = openid,不存在则 INSERT - 签发 JWT:调用
auth.js的signToken({ user_id, enterprise_id, role }) - 返回
{ success: true, token, user }
- 实现
GET /api/miniapp/user-info:从 JWT 解析用户信息返回 - 实现
POST /api/miniapp/bind-user:绑定微信 openid 到已有账号 - 修改
server/services/tenant-db.js:在createDatabase()中新增ALTER TABLE user ADD COLUMN wx_openid TEXT DEFAULT ''(幂等) - 修改
server.js:在handleRequest中注册/api/miniapp/路由前缀,指向miniapp-auth.handleMiniappRoute - 环境变量统一:使用
WECHAT_APP_ID/WECHAT_APP_SECRET,废弃MINIPROGRAM_APPID
- 验证方法:
- 配置
WECHAT_APP_ID后,小程序调用uni.login()获取 code →POST /api/miniapp/login→ 返回 JWT - 未配置时确认降级到
dev_模式并日志警告 - 确认 user 表新增
wx_openid列 - 确认
server.js中路由注册生效 - 可并行: 是(与 T01/T05/T06 无依赖)
T05. pendingActions 持久化 — feishu-pending-store.js
- 优先级: P0
- 预估工时: 1 天
- 依赖: 无
- 涉及文件:
server/services/feishu-pending-store.js(新增)server/feishu-bot.js(修改)- 编码步骤:
- 新增
server/services/feishu-pending-store.js,导出类FeishuPendingStore - 实现
ensureTable()—CREATE TABLE IF NOT EXISTS feishu_pending_actions(按设计文档 3.2.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)— 查询未消费的 pendingAction - 实现
recoverOnStartup()—SELECT * WHERE consumed_at IS NULL AND expires_at > now,恢复到内存 Map - 实现
cleanup()—DELETE WHERE consumed_at IS NOT NULL OR expires_at < now,每 60 秒执行 - 修改
server/feishu-bot.js:
- 行 323
pendingActions = new Map()保留作为一级缓存 setPendingAction()增加同时写入 SQLiteconsumePendingAction()增加 Map 未命中时查 SQLite- 服务启动时调用
recoverOnStartup()恢复未过期的 pendingAction
- 在
server.js启动流程中初始化FeishuPendingStore实例
- 验证方法:
- 创建 pendingAction → 重启服务 → 确认 pendingAction 从 SQLite 恢复到内存 Map
- 用户点击卡片按钮,确认 consumePendingAction 正常工作(Map 命中 + SQLite 兜底)
- 确认超过 10 分钟 TTL 的 pendingAction 被 cleanup 清理
- 可并行: 是(与 T01/T04/T06 无依赖)
T06. 采购订单服务 — purchase-order-service.js
- 优先级: P0
- 预估工时: 2 天
- 依赖: 无
- 涉及文件:
server/services/purchase-order-service.js(新增)server/routes/purchase-order.js(新增)server.js(修改 — 注册路由)- 编码步骤:
- 新增
server/services/purchase-order-service.js,导出类PurchaseOrderService - 实现
ensureTable()—CREATE TABLE IF NOT EXISTS purchase_orders(按设计文档 3.2.1 建表) - 实现
createPO(data):
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)— 支持按 status/supplier_id/enterprise_id 过滤,分页 - 实现
cancelPO(poId, reason)—UPDATE status='cancelled' - 新增
server/routes/purchase-order.js,导出路由处理函数 - 实现 API 路由:
POST /api/purchase-order/createGET /api/purchase-order/:poIdGET /api/purchase-order/listPOST /api/purchase-order/:poId/approvePOST /api/purchase-order/:poId/confirmPOST /api/purchase-order/:poId/completePOST /api/purchase-order/:poId/cancel
- 修改
server.js:在handleRequest中注册/api/purchase-order/路由前缀
- 验证方法:
- 调用
POST /api/purchase-order/create创建 PO,确认 poId 格式正确、totalAmount 自动计算 - 调用 approve/confirm/complete 确认状态流转正确
- 调用 list 接口确认分页和过滤正常
- 确认
server.js路由注册生效 - 可并行: 是(与 T01/T04/T05 无依赖)
T07. BOM Excel 导入服务 — bom-import-service.js
- 优先级: P0
- 预估工时: 2 天
- 依赖: 无
- 涉及文件:
server/services/bom-import-service.js(新增)server/routes/bom-import.js(新增)server.js(修改 — 注册路由)- 编码步骤:
- 新增
server/services/bom-import-service.js,导出类BomImportService - 安装
xlsx依赖:pnpm add xlsx - 实现
parseExcel(buffer)— 使用 xlsx 库解析,返回{ headers, rows } - 实现
mapColumns(headers, bomFields)— 调用SmartLLMRouter.call()识别列名到 BOM 标准字段映射
- 标准字段:
item_number, name, quantity, material, description - 返回
{ mapping: { colIndex: fieldName }, confidence }
- 实现
buildBomTree(rows, mapping)— 构建多层级 BOM 树结构
- 支持通过
level/indent列或parent列识别层级 - 循环依赖检测:DFS 遍历检测环,发现环则拒绝导入
- 实现
importBom(excelBuffer, options)— 完整导入流程:parseExcel → mapColumns → buildBomTree - 新增
server/routes/bom-import.js,导出路由处理函数 - 实现 API 路由:
POST /api/bom/import/upload— 接收 multipart/form-data Excel 文件POST /api/bom/import/confirm— 用户确认列映射和导入POST /api/bom/import/map-columns— 仅列映射识别
- 修改
server.js:在handleRequest中注册/api/bom/import/路由
- 验证方法:
- 上传包含 100 行 BOM 数据的 Excel 文件,确认解析正确
- 上传列名非标准的 Excel(如"物料编号"而非"item_number"),确认 AI 列映射识别正确
- 上传包含循环依赖的 BOM 数据,确认检测到环并拒绝导入
- 确认 1000 行 Excel 导入在 30 秒内完成
- 可并行: 是(与 T01/T04/T05/T06 无依赖)
T08. BOM 与工业对象库自动匹配
- 优先级: P0
- 预估工时: 1 天
- 依赖: T07(bom-import-service 需先就绪)
- 涉及文件:
server/services/bom-import-service.js(修改)- 编码步骤:
- 在
importBom()流程的buildBomTree之后,对每个零件调用relationshipResolver.resolveExistence('Part', partData) - 三级检测结果处理:
- 已存在 → 标记
status: 'linked',SCSAIId,关联已有对象 - 不存在 → 标记
status: 'pending',suggestion: '待确认'
- 调用
relationshipResolver.buildLinkPlan('Part', parts)生成关联执行计划 - 在
importBom返回值中增加matchResults和linkPlan字段 - 在
confirm路由中执行 linkPlan(创建/关联对象)
- 验证方法:
- 导入包含"电机-A"的 BOM,若 SCSAI 中已存在,确认标记为"已关联"
- 导入全新零件,确认标记为"待确认"
- 确认 matchResults 和 linkPlan 正确返回
- 确认 100 个对象的批量匹配在 10 秒内完成
- 可并行: 否(依赖 T07)
T09. 租户中间件 — tenant-middleware.js
- 优先级: P0
- 预估工时: 2 天
- 依赖: 无
- 涉及文件:
server/middleware/tenant-middleware.js(新增)server.js(修改 — softAuth 后增加 tenantInject)server/utils/SCSAI-client.js(修改 — 增加 enterprise_id 过滤)- 编码步骤:
- 新增
server/middleware/tenant-middleware.js,导出tenantInject和tenantDataGuard方法 - 实现
tenantInject(req, res, next):
- 从
req.enterpriseId(softAuth 已注入)获取租户 ID - 若无 →
enterprise_id = 'default'(公共租户) - 注入
req.tenantContext = { enterpriseId, role }
- 实现
SCSAIQueryFilter(amlQuery, enterpriseId):
- 在 AML
中注入enterpriseId
- 实现
tenantDataGuard(req, res, next):
- 对写操作(POST/PUT/DELETE):从请求体提取目标对象的 enterprise_id,若与
req.enterpriseId不一致 → 403 Forbidden - 记录越权访问审计日志到
audit_logs表
- 修改
server.js:在handleRequest中,将softAuth后增加tenantInject调用
softAuth(req, res, () => {
tenantInject(req, res, () => {
// 继续路由处理
});
});
- 修改
server/utils/SCSAI-client.js:查询方法增加enterprise_id过滤参数,自动注入到 AML 查询
- 验证方法:
- 租户 A 的用户查询 Part 列表,确认 AML 查询自动添加
过滤ent_A - 租户 A 的用户尝试访问 enterprise_id=ent_B 的 Part,确认返回 403
- JWT 中无 enterprise_id 时确认使用
default公共租户 - 确认越权访问记录到审计日志
- 可并行: 是(与 T01/T04/T05/T06/T07 无依赖)
T10. 租户数据隔离验证增强
- 优先级: P0
- 预估工时: 1 天
- 依赖: T09(tenant-middleware 需先就绪)
- 涉及文件:
server/middleware/tenant-middleware.js(修改)server/services/tenant-db.js(修改 — 新增 audit_logs 增强)- 编码步骤:
- 增强
tenantDataGuard的审计日志功能:
- 新增
audit_logs表字段:action, user_id, enterprise_id, target_enterprise_id, resource, timestamp
- 在
tenant-db.js中确保audit_logs表存在 - 对所有写操作路由增加
tenantDataGuard中间件调用 - 在关键业务路由(BOM/ECR/采购订单)中验证 enterprise_id 隔离
- 增加租户隔离的定期巡检脚本(可选,检查是否有遗漏 enterprise_id 的查询)
- 验证方法:
- 模拟跨租户访问,确认 403 返回和审计日志记录
- 检查所有写操作路由是否都经过 tenantDataGuard
- 确认 audit_logs 表正确记录越权访问
- 可并行: 否(依赖 T09)
T11. 微信发布环境变量统一
- 优先级: P0
- 预估工时: 0.5 天
- 依赖: 无
- 涉及文件:
server/services/wechat-publish.js(修改)server/routes/content-api.js(修改).env.example(修改 — 新增说明)- 编码步骤:
- 修改
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;
- 新增启动检查:若使用
MINIPROGRAM_APPID且未配置WECHAT_APP_ID→ 打印废弃警告 - 若配置了
WECHAT_APP_ID→ 打印"微信配置已统一" - 同步修改
content-api.js中的环境变量引用 - 更新
.env.example:新增WECHAT_APP_ID/WECHAT_APP_SECRET说明,标注MINIPROGRAM_*已废弃
- 验证方法:
- 配置
WECHAT_APP_ID启动,确认日志打印"微信配置已统一" - 仅配置
MINIPROGRAM_APPID启动,确认打印废弃警告但功能正常 - 确认
content-api.js同步使用新变量 - 可并行: 是(与所有 P0 任务无依赖)
T12. 邮件监听 IMAP 配置化
- 优先级: P0
- 预估工时: 0.5 天
- 依赖: 无
- 涉及文件:
server/services/email-listener.js(修改)config.yaml(修改 — 新增 email.imap 配置节)- 编码步骤:
- 修改
email-listener.js行 22-31 的 IMAP 连接配置:
host: 从this.config.imapHost→process.env.EMAIL_IMAP_HOST→ 默认imap.sina.comport: 从this.config.imapPort→process.env.EMAIL_IMAP_PORT→ 默认993
- 新增重连计数器:
reconnectCount = 0,MAX_RECONNECT = 5 - 修改
scheduleReconnect():
reconnectCount++- 若
reconnectCount >= MAX_RECONNECT→ 停止重连 + 发送飞书告警"邮件监听服务已停止" - 否则 → 30 秒后重连
- 连接成功时重置
reconnectCount = 0 - 修改
config.yaml:新增email.imap.host和email.imap.port配置项
- 验证方法:
- 在
config.yaml配置email.imap.host: imap.qq.com,确认 EmailListener 连接到 imap.qq.com - 未配置时确认使用默认 imap.sina.com
- 模拟连续 5 次连接失败,确认停止重连并发送飞书告警
- 可并行: 是(与所有 P0 任务无依赖)
T13. 小程序 ai-chat 页面集成 VoiceInput
- 优先级: P0
- 预估工时: 0.5 天
- 依赖: T01(VoiceInput 需先完成)、T04(登录需先就绪)
- 涉及文件:
bossagents-miniapp/src/pages/ai-chat/index.vue(修改)- 编码步骤:
- 在 ai-chat 页面引入
VoiceInput组件 - 将 VoiceInput 放置在聊天输入框旁边或下方
- 监听
@result事件,将识别文本填入聊天输入框 - 监听
@error事件,显示错误提示 - 确保语音输入和文字输入可无缝切换
- 验证方法:
- 在 ai-chat 页面按住语音按钮说话,松手后确认识别文本出现在输入框
- 确认语音输入和文字输入不冲突
- 可并行: 否(依赖 T01 + T04)
T14. 飞书 pendingActions 查询 API
- 优先级: P0
- 预估工时: 0.5 天
- 依赖: T05(pendingActions 持久化需先就绪)
- 涉及文件:
server/feishu-bot.js(修改)server.js(修改 — 注册路由)- 编码步骤:
- 在
feishu-bot.js或feishu-service.js中新增getPendingActionsByUser(userId)方法 - 在
server.js中注册GET /api/feishu/pending-actions?userId=xxx路由 - 返回当前用户未消费的 pendingAction 列表
- 验证方法:
- 创建 pendingAction 后调用
GET /api/feishu/pending-actions?userId=xxx,确认返回正确列表 - 消费后再次查询,确认列表为空
- 可并行: 否(依赖 T05)
T15. P0 数据库表初始化脚本
- 优先级: P0
- 预估工时: 0.5 天
- 依赖: 无
- 涉及文件:
server/db-adapter.js(修改 — 建表语句)- 编码步骤:
- 在
db-adapter.js的createDatabase()中新增以下建表语句(均使用CREATE TABLE IF NOT EXISTS):
purchase_orders表feishu_pending_actions表notifications表
- 新增
ALTER TABLE user ADD COLUMN wx_openid TEXT DEFAULT ''(忽略重复列错误) - 新增相关索引
- 确保建表幂等,多次执行不报错
- 验证方法:
- 删除数据库文件后启动服务,确认所有新表正确创建
- 重复启动服务,确认不报错(幂等)
- 确认索引正确创建
- 可并行: 是(与所有 P0 任务无依赖,但建议最先执行)
P1 任务(V1.0 增强,约 24 天)
T16. 小程序工作台数据对接
- 优先级: P1
- 预估工时: 1.5 天
- 依赖: T04(微信登录需先就绪)
- 涉及文件:
bossagents-miniapp/src/pages/workbench/index.vue(修改)server/routes/miniapp-auth.js(修改 — 新增 dashboard 路由)- 编码步骤:
- 在
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_v2staffCount→SELECT COUNT(*) FROM digital_staff WHERE enabled = 1
- 修改
workbench/index.vue:将硬编码 mock 数据替换为miniappApi.getDashboard()调用 - 添加加载状态和错误处理
- 确认页面显示真实产品数/变更数/规则数/员工数
- 验证方法:
- 打开小程序工作台页面,确认显示真实统计数据
- 后端无数据时确认显示 0 而非报错
- 可并行: 否(依赖 T04)
T17. 三端消息同步服务 — notification-sync.js
- 优先级: P1
- 预估工时: 2 天
- 依赖: T15(notifications 表需先就绪)
- 涉及文件:
server/services/notification-sync.js(新增)bossagents-miniapp/src/api/miniapp.js(修改 — 新增通知 API)bossagents-miniapp/src/store/index.js(修改 — useNotificationStore 对接真实 API)- 编码步骤:
- 新增
server/services/notification-sync.js,导出类NotificationSyncService - 实现
push(userId, message, channels):
channels.feishu→feishuService.sendMessageToUser(openId, message)channels.miniapp→ 写入notifications表 + 微信订阅消息channels.web→unifiedMessages.addMessage()
- 实现
getNotifications(userId, page, pageSize)— 分页查询 - 实现
markRead(userId, notificationId)— 标记已读 - 在
miniapp-auth.js中新增路由:
GET /api/miniapp/notificationsPUT /api/miniapp/notifications/:id/read
- 修改
bossagents-miniapp/src/api/miniapp.js:新增getNotifications/markRead方法 - 修改
bossagents-miniapp/src/store/index.js:useNotificationStore对接真实 API
- 验证方法:
- 网页端创建 ECR 变更 → 小程序通知列表出现新通知
- 点击通知跳转到变更详情页
- 标记已读后确认通知状态更新
- 可并行: 否(依赖 T15)
T18. 飞书事件订阅加密解密 — feishu-crypto.js
- 优先级: P1
- 预估工时: 1 天
- 依赖: 无
- 涉及文件:
server/services/feishu-crypto.js(新增)server.js(修改 — 新增/api/feishu/event路由)- 编码步骤:
- 新增
server/services/feishu-crypto.js,导出类FeishuCrypto - 实现
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路由:
- 若
body.encrypt→feishuCrypto.decryptEvent() - 若
body.challenge→ 返回{ challenge: body.challenge } feishuCrypto.verifyToken()验证- 分发事件到
feishu-bot.js处理
- 环境变量:
FEISHU_ENCRYPT_KEY,FEISHU_VERIFICATION_TOKEN
- 验证方法:
- 发送飞书验证 challenge 请求,确认正确返回 challenge 值
- 发送加密事件,确认正确解密并处理
- 签名不匹配时确认拒绝处理
- 可并行: 是(与其他 P1 任务无强依赖)
T19. 飞书审批流集成
- 优先级: P1
- 预估工时: 2 天
- 依赖: T18(飞书加密解密需先就绪)
- 涉及文件:
server/feishu-service.js(修改 — 增强 createApproval 调用链路)server.js(修改 — 新增/api/feishu/approval/callback路由)config.yaml(修改 — 新增feishu.approval_code)- 编码步骤:
- 在业务操作需要审批时调用
feishuService.createApproval(approvalCode, { applicant, form }) - 实现
POST /api/feishu/approval/callback路由:
- 接收飞书审批回调
- 调用
feishuService.handleApprovalCallback(callbackData) - 审批通过 → 执行业务操作(ECR 状态变更等)
- 审批拒绝 → 通知发起人
- 降级策略:若
createApproval()失败 → 降级为卡片消息确认模式(现有逻辑) - 在
config.yaml中配置feishu.approval_code - 在采购订单审批流程中集成飞书审批(DS-PROC-001 → 飞书审批 → approvePO)
- 验证方法:
- ECR 变更需要审批时,确认飞书审批中心出现待审批项
- 审批通过后确认 SCSAI 状态变更
- 飞书审批 API 失败时确认降级为卡片消息
- 可并行: 否(依赖 T18)
T20. 1688 降级体验优化
- 优先级: P1
- 预估工时: 0.5 天
- 依赖: 无
- 涉及文件:
server/services/alibaba-1688-service.js(修改)- 编码步骤:
- 修改
searchSourcing()方法(行 151-228):
- Level 1: 1688 真实 API → 成功标注"来源: 1688 开放平台",失败记录降级原因
- Level 2:
SmartLLMRouter.call()LLM 寻源 → 成功标注"⚠️ AI 推荐仅供参考" - Level 3: 本地数据库查询 → 成功标注"来源: 本地供应商库"
- Level 4: 返回明确提示"暂无供应商信息,建议手动添加供应商后重新询价"
- 删除现有的 Mock 兜底(行 228 附近)
- 降级原因通过
response.degraded = true; response.degradeReason = '...'返回
- 验证方法:
- 1688 API Key 未配置时,确认返回"1688 接口暂不可用,已使用 AI 智能寻源替代"
- 所有渠道不可用时,确认返回明确提示而非 Mock 数据
- 确认降级原因正确返回
- 可并行: 是(与其他 P1 任务无强依赖)
T21. 报价邮件自动解析增强
- 优先级: P1
- 预估工时: 1 天
- 依赖: T12(IMAP 配置化需先就绪)
- 涉及文件:
server/services/email-listener.js(修改)- 编码步骤:
- 修改
email-listener.js的newEmail事件处理,增加自动报价解析 - 收到邮件后调用
llmParseQuotation(emailData)解析结构化报价 - 解析成功 → 关联到
staff_tasks中的采购任务:
UPDATE staff_tasks SET output_data = quotation, status = 'completed'WHERE task_type = 'procurement' AND status = 'in_progress'
- 非报价邮件 → 忽略,不触发操作
- 添加解析失败的日志记录
- 验证方法:
- 收到报价邮件后,确认自动解析并关联到采购任务
- 任务看板更新为"已收到报价"
- 非报价邮件确认不触发操作
- 可并行: 否(依赖 T12)
T22. BOM 多层级图形化展示 — BomTreeGraph.vue
- 优先级: P1
- 预估工时: 2 天
- 依赖: T07(BOM 导入需先就绪)
- 涉及文件:
src/components/bom/BomTreeGraph.vue(新增)src/views/BomAssistant.vue(修改 — 集成 BomTreeGraph)- 编码步骤:
- 新增
src/components/bom/BomTreeGraph.vue - 使用 SVG 渲染树形图:
- 节点 = 零件信息卡片(名称/编号/数量/匹配状态)
- 边 = 父子关系线
- 节点状态标记:✅ 已关联(绿) / ⚠️ 待确认(黄) / 🔴 孤立(红)
- 交互功能:
- 展开/收起子节点
- 鼠标滚轮缩放
- 拖拽平移
- 点击节点 →
emit('node-click')→ 显示零件详情面板
- 修改
BomAssistant.vue:集成 BomTreeGraph 组件
- 添加 Excel 导入区域:
- 添加列映射确认弹窗:显示 AI 识别的列映射,支持手动调整
- 验证方法:
- 导入 BOM 后确认树形图正确渲染
- 缩放、拖拽、展开/收起交互正常
- 点击节点确认显示零件详情
- 匹配状态颜色标记正确
- 可并行: 否(依赖 T07)
T23. BOM 完整性评分展示
- 优先级: P1
- 预估工时: 0.5 天
- 依赖: T22(BomTreeGraph 需先就绪)
- 涉及文件:
src/views/BomAssistant.vue(修改 — 增加评分展示)- 编码步骤:
- 在 BomAssistant.vue 中增加完整性评分展示区域
- 调用
GET /api/relationship/score/:itemId获取评分 - 显示评分百分比 + 缺失关系建议
- 评分 100% → 绿色"✅ 完整性评分 100%"
- 评分 60% → 黄色"⚠️ 完整性评分 60%,建议补充:供应商关联、质量文档"
- 评分 0% → 红色"🔴 孤立对象,建议手动关联"
- 验证方法:
- 创建 BOM 后确认显示完整性评分
- 部分关系缺失时确认显示建议
- 孤立对象确认显示红色标记
- 可并行: 否(依赖 T22)
T24. 数字员工协作调度器 — collaboration-scheduler.js
- 优先级: P1
- 预估工时: 2 天
- 依赖: 无
- 涉及文件:
server/digital-staff/collaboration-scheduler.js(新增)server/digital-staff/collaboration-rules.yaml(新增)server/digital-staff/task-board.js(修改 — completeTask 触发协作调度)- 编码步骤:
- 新增
server/digital-staff/collaboration-scheduler.js,导出类CollaborationScheduler - 实现
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):
- 暂停协作链 + 通知发起人"XX 任务失败,协作链已暂停"
- 提供重试和跳过选项
- 实现
getCollaborationChain(taskId)— 从staff_tasks.collaboration_chainJSON 解析完整链路 - 新增
server/digital-staff/collaboration-rules.yaml:
- DS-PROC-001 → DS-COST-001
- DS-COST-001 → DS-VEN-001
- DS-ECR-001 → DS-DATA-001
- 规则热加载:
setInterval(loadRules, 30000),文件修改时间变化 → 重新加载 - 修改
task-board.js:completeTask()完成后触发collaborationScheduler.onTaskCompleted(task)
- 验证方法:
- DS-PROC-001 完成询价 → 确认自动触发 DS-COST-001 成本分析
- 成本分析完成 → 确认自动触发 DS-VEN-001 供应商评估
- 任务看板显示完整协作链
- 配置循环规则 A→B→A → 确认启动时拒绝加载
- 修改 YAML 后 30 秒内确认规则热加载
- 可并行: 是(与其他 P1 任务无强依赖)
T25. 协作规则 API 与管理
- 优先级: P1
- 预估工时: 1 天
- 依赖: T24(协作调度器需先就绪)
- 涉及文件:
server/routes/digital-staff-routes.js(修改 — 新增协作链查询 API)- 编码步骤:
- 在
digital-staff-routes.js中新增协作链查询 API:
GET /api/digital-staff/collaboration/rules— 获取协作规则列表POST /api/digital-staff/collaboration/rules— 新增/修改协作规则GET /api/digital-staff/collaboration/chain/:taskId— 查询完整协作链路
- 在
server.js中确认路由注册(已有/api/digital-staff/前缀)
- 验证方法:
- 调用
GET /api/digital-staff/collaboration/rules确认返回规则列表 - 调用
GET /api/digital-staff/collaboration/chain/:taskId确认返回协作链 - 新增规则后确认 YAML 文件更新
- 可并行: 否(依赖 T24)
T26. ECO 自动关联
- 优先级: P1
- 预估工时: 1.5 天
- 依赖: T09(租户中间件需先就绪,确保 enterprise_id 隔离)
- 涉及文件:
server/routes/change.js(修改 — ECO 创建后调用关系发现)- 编码步骤:
- 在 ECO 创建路由中,创建完成后插入关系发现逻辑:
- 调用
relationshipCapability.identifyRelations('ECO', ecoData) - 识别关联的 BOM(通过
affected_items字段) - 识别关联的 Part(通过
change_subject字段) - 识别关联的文档(通过
document_refs字段)
- 自动创建关系:ECO→BOM, ECO→Part, ECO→Document
- 调用
relationshipChecklist.postValidate(ecoId, 'ECO')返回完整性评分 + 建议 - 在创建响应中增加
relations和score字段
- 验证方法:
- 创建 ECO 变更"修改电机-A 规格" → 确认自动关联 BOM 和 Part
- 变更影响分析报告包含所有关联对象
- 完整性评分正确返回
- 可并行: 否(依赖 T09)
T27. 产品自动关联
- 优先级: P1
- 预估工时: 1 天
- 依赖: T26(ECO 关联模式可复用)
- 涉及文件:
- 对应产品创建路由 (修改)
- 编码步骤:
- 在产品创建流程中插入关系发现:
- 调用
relationshipResolver.discoverRelations('Product', [productData]) - 发现关联的 BOM(通过
product_name字段匹配) - 发现关联的文档(通过
document_refs字段)
- 调用
relationshipResolver.buildLinkPlan('Product', [productData])生成关联计划 - 调用
relationshipResolver.executePlan(...)执行关联 - 调用
relationshipChecklist.postValidate(productId, 'Product')返回完整性评分 - 在创建响应中增加
relations和score字段
- 验证方法:
- 创建产品"磷化工设备-A" → 确认自动关联 3 个 BOM 和 5 个文档
- 产品详情页显示完整关联图谱
- 完整性评分正确返回
- 可并行: 否(依赖 T26)
T28. 关系完整性评分增强
- 优先级: P1
- 预估工时: 1 天
- 依赖: 无
- 涉及文件:
server/core/relationship-checklist.js(修改)- 编码步骤:
- 增强
postValidate(itemId, itemType)返回值:
- 新增完整性评分计算:
score = (已建立关系数 / 必需关系数) * 100 - 新增
missingRelations:必需但未建立的关系列表 - 新增
suggestions:基于缺失关系的建议文本
- 返回值格式:
{ score, missingRelations, suggestions } - 评分等级:
- 100% → "✅ 完整性评分 100%,所有必需关系已建立"
- 60% → "⚠️ 完整性评分 60%,建议补充:供应商关联、质量文档"
- 0% → "🔴 孤立对象,建议手动关联"
- 新增
GET /api/relationship/score/:itemIdAPI 路由
- 验证方法:
- Part 创建完成后调用评分 API,确认返回正确的评分和建议
- 3/5 必需关系已建立 → 确认评分 60%
- 无任何关系 → 确认评分 0% + "孤立对象"标记
- 可并行: 是(与其他 P1 任务无强依赖)
T29. 通用邮件命令解析器 — email-command-parser.js
- 优先级: P1
- 预估工时: 2 天
- 依赖: T12(IMAP 配置化需先就绪)
- 涉及文件:
server/services/email-command-parser.js(新增)server/config/email-commands.yaml(新增)- 编码步骤:
- 新增
server/services/email-command-parser.js,导出类EmailCommandParser - 实现
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 文件变化 - 新增
server/config/email-commands.yaml:
ecr_approve:subjectPattern: /审批通过|approved/iprocurement_confirm:subjectPattern: /报价|quotation/i
- 在
email-listener.js的newEmail事件中集成命令解析
- 验证方法:
- 收到标题为"ECR-2026-001 审批通过"的邮件 → 确认自动执行 ECR 状态变更
- 收到不匹配任何模板的邮件 → 确认静默归档
- 修改 YAML 后确认规则热加载
- 可并行: 否(依赖 T12)
T30. 邮件命令模板配置与集成
- 优先级: P1
- 预估工时: 1 天
- 依赖: T29(命令解析器需先就绪)
- 涉及文件:
server/services/email-listener.js(修改 — 集成命令解析)server/config/email-commands.yaml(修改 — 增加更多模板)- 编码步骤:
- 在
email-listener.js的newEmail事件处理中集成emailCommandParser - 收到邮件后先尝试命令解析,解析成功则执行命令
- 命令解析失败则走原有报价解析流程
- 增加更多邮件命令模板:
bom_publish:BOM 发布确认vendor_evaluate:供应商评价
- 添加命令执行结果的飞书/小程序通知
- 验证方法:
- 收到匹配模板的邮件 → 确认自动执行对应命令
- 收到不匹配的邮件 → 确认走原有流程
- 命令执行后确认通知发送
- 可并行: 否(依赖 T29)
T31. 微信发布失败自动重试
- 优先级: P1
- 预估工时: 0.5 天
- 依赖: T11(环境变量统一需先就绪)
- 涉及文件:
server/services/wechat-publish.js(修改)- 编码步骤:
- 修改
wechat-publish.js的publishArticle()方法 - 新增
_retryPublish(draftMediaId, retryCount = 0)内部方法:
- 调用
publishDraft(mediaId) - 成功 → 返回结果
- 失败且
retryCount < 3→ 等待 5 秒 →_retryPublish(mediaId, retryCount + 1) - 失败且
retryCount >= 3→ 标记"发布失败" + 通知用户
- 返回值增加
retry_count字段
- 验证方法:
- 模拟微信 API 返回 500 错误,确认自动重试最多 3 次
- 3 次均失败后确认标记为"发布失败"并通知用户
- 重试成功后确认返回
retry_count - 可并行: 否(依赖 T11)
T32. 小程序通知页面实现
- 优先级: P1
- 预估工时: 1 天
- 依赖: T17(notification-sync 需先就绪)
- 涉及文件:
bossagents-miniapp/src/pages/notification/index.vue(新增或修改)bossagents-miniapp/src/api/miniapp.js(修改)- 编码步骤:
- 新增或修改小程序通知页面
- 调用
miniappApi.getNotifications()获取通知列表 - 实现通知列表 UI(按时间倒序,未读标记)
- 点击通知 → 跳转到对应业务详情页(ECR/BOM/采购订单)
- 实现标记已读功能:
miniappApi.markRead(id) - 实现下拉刷新和上拉加载更多
- 添加微信订阅消息:
uni.requestSubscribeMessage()
- 验证方法:
- 打开通知页面,确认显示真实通知列表
- 点击通知跳转到正确详情页
- 标记已读后确认状态更新
- 下拉刷新和上拉加载正常
- 可并行: 否(依赖 T17)
P2 方向(V1.1+,仅写方向)
| 编号 | 方向 | 说明 |
|------|------|------|
| P2-1 | 协作链可视化 | 网页端流程图组件,显示任务链路和当前执行节点 |
| P2-2 | 租户配额限制 | tenant_quotas 表 + 创建前检查 + 配额超限提示 |
| P2-3 | 已发布文章管理 | published_articles 表 + 管理界面 + 发布链接查看 |
| P2-4 | BOM 循环依赖可视化 | 在 BomTreeGraph 中高亮显示循环路径 |
| P2-5 | 阿里云 ASR 第二后端 | 增加阿里云智能语音作为讯飞降级备选 |
| P2-6 | WebSocket 实时推送 | 替代轮询实现三端消息实时同步 |
| P2-7 | 租户配额管理界面 | 管理员可配置各租户的配额上限 |
推荐执行顺序
第一周(P0 核心,可并行)
| 天数 | 并行轨道 A | 并行轨道 B | 并行轨道 C |
|---|---|---|---|
| D1 | T15 数据库表初始化 | T11 微信环境变量统一 | T12 IMAP 配置化 |
| D1-D2 | T04 微信登录后端 | T05 pendingActions 持久化 | T06 采购订单服务 |
| D2-D3 | T01 VoiceInput 重写 | T07 BOM Excel 导入 | T09 租户中间件 |
| D3-D4 | T02 意图路由增强 | T08 BOM 自动匹配 | T10 租户数据隔离 |
| D4-D5 | T03 飞书语音审批 | T13 ai-chat 集成 | T14 pendingActions API |
第二周(P1 增强,可并行)
| 天数 | 并行轨道 A | 并行轨道 B | 并行轨道 C |
|---|---|---|---|
| D6-D7 | T16 工作台数据对接 | T18 飞书加密解密 | T20 1688 降级优化 |
| D7-D8 | T17 三端消息同步 | T19 飞书审批流 | T21 报价邮件增强 |
| D8-D9 | T22 BomTreeGraph | T24 协作调度器 | T28 完整性评分 |
| D9-D10 | T23 评分展示 | T25 协作规则 API | T26 ECO 自动关联 |
| D10-D11 | T29 邮件命令解析 | T27 产品自动关联 | T31 发布重试 |
| D11-D12 | T30 邮件命令集成 | T32 小程序通知页面 | - |
关键里程碑
| 里程碑 | 完成标志 | 预计时间 |
|---|---|---|
| M1: 语音链路可用 | T01-T03 完成,小程序语音→意图路由→审批全链路跑通 | 第一周末 |
| M2: 三端登录可用 | T04 完成,小程序微信登录→JWT→API 调用全链路 | 第一周末 |
| M3: 数据安全加固 | T09-T10 完成,多租户隔离验证通过 | 第一周末 |
| M4: 采购流程闭环 | T06 完成,采购订单 CRUD+状态流转 | 第一周末 |
| M5: BOM 导入可用 | T07-T08 完成,Excel 导入→匹配→关联 | 第一周末 |
| M6: 三端协同 | T16-T17 完成,三端消息同步 | 第二周中 |
| M7: 数字员工协作 | T24-T25 完成,协作链自动触发 | 第二周中 |
| M8: 关系感知 | T26-T28 完成,ECO/产品自动关联+评分 | 第二周末 |
任务统计
| 优先级 | 任务数 | 总工时 | 可并行任务组 |
|---|---|---|---|
| P0 | 15 个 | 约 14.5 天 | 5 组可并行 |
| P1 | 17 个 | 约 19.5 天 | 4 组可并行 |
| P2 | 7 个方向 | 约 12 天 | - |
| 合计 | 32 个 + 7 方向 | 约 34 天(并行约 12 天) | - |
BossAgents