Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
1 line
24 KiB
JSON
1 line
24 KiB
JSON
{"repo": "big071/novadepot", "files": {"backend/.env.example": {"9a72c04d5988d008b7de63257ba7fa3a3d203690": {"t": 1785747093.0433364, "n": 815, "h": "7642fd5ba4677241", "c": "SPRING_PROFILES_ACTIVE=dev\nDB_HOST=localhost\nDB_PORT=3306\nDB_NAME=novadepot\nDB_USERNAME=novadepot_user\nDB_PASSWORD=CHANGE_ME_LOCAL_DB_PASSWORD\nREDIS_HOST=localhost\nREDIS_PORT=6379\nJWT_SECRET=CHANGE_ME_32_PLUS_RANDOM_CHARS_LOCAL_ONLY\nAPP_CORS_ALLOWED_ORIGINS=http://localhost:3100,http://127.0.0.1:3100,http://localhost:5173,http://127.0.0.1:5173\nAPP_UPLOAD_MAX_FILE_SIZE=10MB\nAPP_UPLOAD_MAX_REQUEST_SIZE=10MB\nAPP_MAX_REQUEST_BODY_BYTES=10485760\nAPP_AUTH_LOGIN_RATE_LIMIT_ENABLED=true\nAPP_AUTH_LOGIN_RATE_LIMIT_MAX_FAILURES=10\nAPP_AUTH_LOGIN_RATE_LIMIT_WINDOW_SECONDS=300\nAPP_AUTH_LOGIN_RATE_LIMIT_LOCK_SECONDS=300\nAI_PROVIDER=deepseek-chat\nAI_DEEPSEEK_ENABLED=false\nAI_DEEPSEEK_API_KEY=\nAI_DEEPSEEK_BASE_URL=https://api.deepseek.com\nAI_DEEPSEEK_CHAT_MODEL=deepseek-chat\nAI_DEEPSEEK_REASONER_MODEL=deepseek-reasoner\n"}, "321b7b4740555c19596bc443ffb6c091d3b253fc": {"t": 1785770364.4972477, "n": 815, "h": "7642fd5ba4677241", "c": "SPRING_PROFILES_ACTIVE=dev\nDB_HOST=localhost\nDB_PORT=3306\nDB_NAME=novadepot\nDB_USERNAME=novadepot_user\nDB_PASSWORD=CHANGE_ME_LOCAL_DB_PASSWORD\nREDIS_HOST=localhost\nREDIS_PORT=6379\nJWT_SECRET=CHANGE_ME_32_PLUS_RANDOM_CHARS_LOCAL_ONLY\nAPP_CORS_ALLOWED_ORIGINS=http://localhost:3100,http://127.0.0.1:3100,http://localhost:5173,http://127.0.0.1:5173\nAPP_UPLOAD_MAX_FILE_SIZE=10MB\nAPP_UPLOAD_MAX_REQUEST_SIZE=10MB\nAPP_MAX_REQUEST_BODY_BYTES=10485760\nAPP_AUTH_LOGIN_RATE_LIMIT_ENABLED=true\nAPP_AUTH_LOGIN_RATE_LIMIT_MAX_FAILURES=10\nAPP_AUTH_LOGIN_RATE_LIMIT_WINDOW_SECONDS=300\nAPP_AUTH_LOGIN_RATE_LIMIT_LOCK_SECONDS=300\nAI_PROVIDER=deepseek-chat\nAI_DEEPSEEK_ENABLED=false\nAI_DEEPSEEK_API_KEY=\nAI_DEEPSEEK_BASE_URL=https://api.deepseek.com\nAI_DEEPSEEK_CHAT_MODEL=deepseek-chat\nAI_DEEPSEEK_REASONER_MODEL=deepseek-reasoner\n"}, "d2b6092be8229dbd1140ce06f7ee2cdb0e80d811": {"t": 1785770365.8921857, "n": 403, "h": "65677c1419dcd7cb", "c": "SPRING_PROFILES_ACTIVE=dev\nDB_HOST=localhost\nDB_PORT=3306\nDB_NAME=novadepot\nDB_USERNAME=root\nDB_PASSWORD=root\nREDIS_HOST=localhost\nREDIS_PORT=6379\nJWT_SECRET=change_me_in_dev_please\nAI_PROVIDER=deepseek-chat\nAI_DEEPSEEK_ENABLED=false\nAI_DEEPSEEK_API_KEY=sk-your-api-key-here\nAI_DEEPSEEK_BASE_URL=https://api.deepseek.com\nAI_DEEPSEEK_CHAT_MODEL=deepseek-chat\nAI_DEEPSEEK_REASONER_MODEL=deepseek-reasoner\n"}, "263c940f83a3db013f296478d9a052b97e559955": {"t": 1785770367.475781, "n": 182, "h": "600e5c6493d1c127", "c": "SPRING_PROFILES_ACTIVE=dev\nDB_HOST=localhost\nDB_PORT=3306\nDB_NAME=novadepot\nDB_USERNAME=root\nDB_PASSWORD=root\nREDIS_HOST=localhost\nREDIS_PORT=6379\nJWT_SECRET=change_me_in_dev_please\n"}}, "roadmap/02-v1.2-deepseek-intelligence-core.md": {"9a72c04d5988d008b7de63257ba7fa3a3d203690": {"t": 1786067737.2009816, "n": 11423, "h": "30bba501ea0234d8", "c": "# v1.2 —— DeepSeek 仓库智能大脑\n\n> STATUS: PLANNED\n> 预估周期:8-12 周\n> 前置条件:v1.1 进销存闭环完成(购销数据是 AI 理解仓库的必要上下文)\n\n---\n\n## 1. 版本定位\n\n**把 DeepSeek 从\"占位符\"升级为 NovaDepot 的真正智能核心,让 AI 从\"关键词回复机器人\"变成\"懂仓库物流的数字专家\"。**\n\n### v1.0 AI 为什么\"笨\"\n\n| 问题 | 根因 |\n|------|------|\n| 只会关键词匹配 | `RuleAiProvider` 是 8 条 if-else,问法稍变就 miss |\n| 回答像模板填空 | 所有回复都是固定模板 + SQL 聚合结果拼接 |\n| 不理解上下文 | 问\"那个供应商的货到了吗\"——不知道\"那个\"指谁 |\n| 不会主动查数据 | 只能走预定义的规则查询,不能根据对话动态决定查什么 |\n| 多轮对话记忆弱 | 每轮独立处理,不记得上一轮说了什么 |\n| DeepSeek 根本没接入 | `DeepSeekChatAiProvider` 是纯占位符,返回固定字符串 |\n| 没有流式输出 | 用户等 2-8 秒看到完整回复,体验像\"系统卡了\" |\n| 不会调用工具 | AI 无法主动查询库存/订单/客服工单——只能等 RuleProvider 喂数据 |\n\n### v1.2 目标对比\n\n| 维度 | v1.0 (RuleAiProvider) | v1.2 (DeepSeek Intelligence) |\n|------|----------------------|------------------------------|\n| 理解方式 | 关键词匹配 | 自然语言语义理解 |\n| 回答来源 | 固定模板 + SQL 拼装 | LLM 推理 + 工具查询 + 知识库引用 |\n| 上下文 | 单轮无记忆 | 多轮对话上下文保持 |\n| 数据能力 | 仅库存/库存流水 2 张表 | 库存 + 采购 + 销售 + 工单 + 知识库全链路 |\n| 主动性 | 被动响应 | 可主动发现异常 + 推送预警 |\n| 输出体验 | 一次性返回全文 | 流式打字机输出 |\n| 底层引擎 | if-else 规则 | DeepSeek API(HTTP 调用) |\n\n---\n\n## 2. 核心矛盾\n\n| 矛盾 | 现状 | 目标 |\n|------|------|------|\n| AI 不懂仓库业务 | 关键词匹配,覆盖率 < 30% | DeepSeek 理解自然语言仓库问题,覆盖率 > 90% |\n| DeepSeek 从未对接 | Provider 是占位符,无 HTTP 调用 | 真实 HTTP API 集成 + 流式输出 + 降级策略 |\n| AI 不能主动查数据 | 只能走预定义 SQL 规则 | Function Calling:AI 自主决定查询哪些业务数据 |\n| 多轮对话无记忆 | 每轮独立处理 | 会话级上下文窗口 + 历史消息管理 |\n| 没有运营可视性 | 无报表/通知/预警 | 报表中心 + 通知中心 + Agent 定时巡检 |\n\n---\n\n## 3. 功能范围\n\n### 3.1 DeepSeek 真实接入 ⚠️ 核心改造\n\n> **目标**:用 DeepSeek API 替换占位符,实现真正的 LLM 推理。\n\n#### 3.1.1 HTTP 客户端集成\n\n| 能力 | 说明 |\n|------|------|\n| HTTP 调用 | 使用 Spring Boot `RestClient` 或 OkHttp 调用 DeepSeek Chat Completions API |\n| 端点 | `https://api.deepseek.com/v1/chat/completions` |\n| 认证 | Bearer Token,从 `app.ai.deepseek.api-key` 环境变量读取 |\n| 模型 | `deepseek-chat`(默认);管理员可切换 `deepseek-reasoner` |\n| 超时 | 连接超时 5s,读取超时 30s |\n| 重试 | 失败后自动重试 1 次(间隔 1s) |\n| 用量日志 | 每次调用记录 token 消耗 + 延迟,写入 `ai_usage_logs` 表 |\n\n#### 3.1.2 System Prompt 领域注入\n\n> **核心**:让 DeepSeek 知道自己在一个仓库管理系统里,理解业务上下文。\n\n```text\n## 角色\n你是 NovaDepot 仓库智能助手,服务于一个仓库管理团队(3-15 人)。\n你了解仓库管理、库存、采购、销售、客服工单等业务。\n\n## 当前上下文\n- 当前时间:{currentTime}\n- 当前用户:{userName},角色:{role}\n- 仓库:{warehouseName},SKU 总数:{totalSku},库存条目数:{totalItems}\n\n## 能力边界\n- 你可以查询系统内的库存、采购单、销售单、工单等数据\n- 你可以给出业务建议,但最终决策由人工确认\n- 如果你不确定某个数据是否存在,请使用工具函数查询\n- 所有回答基于系统数据,不凭空编造\n\n## 回答风格\n- 简洁、专业、结构化\n- 数据用表格或列表展示\n- 不确定时明确说明,不做猜测\n```\n\n#### 3.1.3 降级策略\n\n```\n用户提问\n → AiService 路由到 DeepSeekChatAiProvider\n → DeepSeek API 调用\n ├─ 成功(2s 内)→ 流式返回\n ├─ 超时(30s)→ 降级到 RuleAiProvider + 提示 \"DeepSeek 响应较慢,已切换为规则引擎\"\n ├─ 4xx 错误 → 降级到 RuleAiProvider\n ├─ 5xx 错误 → 重试 1 次 → 仍失败则降级\n └─ 网络不可达 → 降级到 RuleAiProvider\n```\n\n### 3.2 流式输出(SSE)⚠️ 核心改造\n\n> **目标**:用户发送消息后,AI 逐字输出,体验像聊天应用而非\"等结果\"。\n\n| 能力 | 说明 |\n|------|------|\n| 后端 SSE 端点 | `POST /api/v1/ai/chat/stream` 返回 `text/event-stream` |\n| 前端 EventSource | 使用 `EventSource` 或 `fetch` + `ReadableStream` 消费 SSE |\n| 打字机渲染 | 前端逐字符追加到消息气泡,不阻塞 UI |\n| 中断支持 | 用户可点击\"停止生成\"中断流式输出 |\n| 流式降级 | SSE 不可用时(如某些代理环境),降级为非流式请求 |\n\n**SSE 事件格式**:\n```\nevent: token\ndata: {\"content\": \"当前\"}\n\nevent: token \ndata: {\"content\": \"库存\"}\n\nevent: done\ndata: {\"conversationId\": 42, \"tokens\": 156}\n```\n\n### 3.3 Function Calling(工具调用)⚠️ 核心改造\n\n> **目标**:让 AI 能自主决定查询哪些业务数据,而非仅走预定义规则。\n\n#### 3.3.1 工具函数清单\n\n| 工具名 | 功能 | 输入参数 | 返回数据 |\n|--------|------|----------|----------|\n| `query_inventory` | 查询库存 | `productName?`, `warehouseId?`, `lowStock?` | 库存列表(产品/仓库/数量/可用数) |\n| `query_inbound` | 查询入库单 | `status?`, `dateFrom?`, `dateTo?`, `partnerName?` | 入库单列表 |\n| `query_outbound` | 查询出库单 | `status?`, `dateFrom?`, `dateTo?`, `partnerName?` | 出库单列表 |\n| `query_purchase` | 查询采购单 | `status?`, `dateFrom?`, `dateTo?`, `partnerName?` | 采购单列表 |\n| `query_sale` | 查询销售单 | `status?`, `dateFrom?`, `dateTo?`, `partnerName?` | 销售单列表 |\n| `query_tickets` | 查询客服工单 | `status?`, `assignee?`, `dateFrom?` | 工单列表 |\n| `query_product` | 查询产品 | `name?`, `sku?`, `category?` | 产品详情 |\n| `query_partner` | 查询往来单位 | `name?`, `type?` | 往来单位信息 |\n| `get_inventory_stats` | 库存统计概览 | `warehouseId?` | 总SKU/总数量/低库存数/滞销数 |\n| `get_daily_report` | 今日运营概览 | 无 | 今日入库/出库/新增工单/应收应付汇总 |\n\n#### 3.3.2 Function Calling 流程\n\n```\n用户:\"最近一周有哪些采购单还没到货?\"\n → DeepSeek 理解意图:查询最近7天状态为CONFIRMED/PARTIAL的采购单\n → DeepSeek 生成 function_call: query_purchase(status=\"CONFIRMED,PARTIAL_RECEIVED\", dateFrom=\"7天前\")\n → AiService 执行 query_purchase → 返回数据\n → DeepSeek 用数据生成自然语言回复:\"最近一周有3笔采购单尚未完全到货:\\n1. PO-20260420-001...\"\n```\n\n**OpenAI-compatible Function Calling 格式**(DeepSeek 兼容):\n```json\n{\n \"tools\": [\n {\n \"type\": \"function\",\n \"function\": {\n \"name\": \"query_inventory\",\n \"description\": \"查询当前库存情况,可按产品名称、仓库、是否低库存筛选\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"productName\": {\"type\": \"string\", \"description\": \"产品名称(模糊匹配)\"},\n \"warehouseId\": {\"type\": \"integer\", \"description\": \"仓库ID\"},\n \"lowStock\": {\"type\": \"boolean\", \"description\": \"是否仅查询低库存商品\"}\n }\n }\n }\n }\n ]\n}\n```\n\n### 3.4 多轮对话上下文\n\n| 能力 | 说明 |\n|------|------|\n| 会话历史 | 每个 conversation 保留最近 20 轮对话(40 条消息) |\n| 上下文窗口 | 将历史消息注入 DeepSeek 请求的 `messages` 数组 |\n| 上下文压缩 | 超过 20 轮后,对早期消息做摘要压缩(调用 DeepSeek 生成摘要) |\n| 会话切换 | 用户可新建会话、切换历史会话 |\n| 会话过期 | 24 小时无活动自动归档 |\n\n### 3.5 Agent 定时巡检 + 主动预警 ⚠️ 保留原规划\n\n> **前置**:Function Calling 已就绪,Agent 可以用同样的工具函数做巡检。\n\n| 能力 | 说明 |\n|------|------|\n| 低库存巡检 | 每小时检查所有产品库存,低于阈值自动生成预警通知 |\n| 单据超时预警 | 待审核超过 24h / 待执行超过 48h 的单据自动预警 |\n| 工单超时预警 | 待处理工单超过 4h 自动预警 |\n| 异常检测 | 库存为负 / 单次变动超过阈值 → 自动告警 |\n| 推送方式 | 站内通知中心 |\n\n**实现方式**:Spring `@Scheduled` 定时任务 → 调用 `AiService` 的工具函数查询 → 生成通知。\n\n### 3.6 报表中心\n\n| 报表 | 维度 | 说明 |\n|------|------|------|\n| 库存周转报表 | 产品/仓库/时间段 | 周转率、周转天数 |\n| 出入库日报/周报 | 时间汇总 | 入库量、出库量、净变化 |\n| 购销汇总 | 往来单位/时间段 | 采购总额、销售总额 |\n| 工单处理效率 | 客服/时间段 | 平均处理时长、关闭率 |\n\n- 图表:ECharts 柱状图/折线图/饼图\n- 支持日期范围筛选和 CSV 导出\n\n### 3.7 站内通知中心\n\n| 能力 | 说明 |\n|------|------|\n| 通知铃铛 | 页面顶部未读数量 badge |\n| 通知列表 | 全部/未读筛选、标记已读/全部已读 |\n| 通知类型 | 异常告警、超时催办、审核通知、Agent 巡检结果 |\n| 关联跳转 | 点击通知跳转到对应单据/工单页面 |\n\n### 3.8 前端优化\n\n| 优化 | 说明 |\n|------|------|\n| 骨架屏 | DataTable/图表/Dashboard 卡片首次加载用骨架屏替代 spinner |\n| ECharts 懒加载 | `defineAsyncComponent` + Vite `manualChunks` 独立拆包 |\n| API 错误中文映射 | `frontend-vue/src/utils/errorMapping.ts` 统一映射后端错误信息 |\n| 乐观更新 | 通知已读/状态切换先更新 UI 再异步确认后端 |\n| 流式渲染 | AI 对话页面接入 SSE 打字机效果 |\n\n### 3.9 打印模板\n> 从 v1.1 延续,本版本完善拣货单打印。\n\n### 3.10 审计日志清理\n\n| 能力 | 说明 |\n|------|------|\n| 保留策略 | 可配置保留天数(默认 90 天) |\n| 定时清理 | Spring `@Scheduled` 每日凌晨清理过期审计日志 |\n\n---\n\n## 4. 涉及页面\n\n| 页面 | 路由 | 操作 |\n|------|------|------|\n| AI 助手 | `ai/enterprise` | **重写**(接入流式输出 + Function Calling 结果展示) |\n| Agent 中心 | `agent/center` | 修改(增加定时巡检配置 + 预警规则管理) |\n| 通知中心 | `/notifications` | **新增** |\n| 报表中心 | `/reports` | **新增**(4 类报表 + ECharts 图表) |\n| Dashboard | `/dashboard` | 修改(预警卡片 + 通知入口 + 今日概览图表) |\n| AI Provider 配置 | `/settings/ai` | **新增**(切换 Provider、配置 API Key、查看用量) |\n| 所有单据详情页 | `/wms/*`, `/erp/*` | 修改(打印按钮) |\n\n---\n\n## 5. 涉及后端模块\n\n| 模块 | 操作 |\n|------|------|\n| `modules.ai.provider.DeepSeekChatAiProvider` | **重写**(真实 HTTP 调用 + System Prompt + 流式输出) |\n| `modules.ai.provider.DeepSeekReasonerAiProvider` | **重写**(同上,使用 deepseek-reasoner 模型) |\n| `modules.ai.service.AiService` | 修改(增加流式路由、Function Calling 编排、工具注册) |\n| `modules.ai.tools` | **新增**(10 个工具函数实现) |\n| `modules.ai.streaming` | **新增**(SSE 端点 + 流式响应管理) |\n| `modules.agent` | 修改(定时巡检调度 + 预警规则) |\n| `modules.notifications` | **新增**(站内通知 CRUD + 已读/未读) |\n| `modules.reports` | **新增**(报表聚合查询 + CSV 导出) |\n| `modules.auditlogs` | 修改(定时清理任务) |\n| `modules.settings` | 修改(AI Provider 配置 + API Key 管理) |\n\n---\n\n## 6. 涉及数据表\n\n| 表名 | 操作 | 说明 |\n|------|------|------|\n| `ai_usage_logs` | 新增 | AI 调用用量日志(provider/model/tokens/latency) |\n| `ai_tool_definitions` | 新增 | 工具函数注册表(可选,也可代码注册) |\n| `notifications` | 新增 | 站内通知 |\n| `agent_alert_rules` | 新增 | 预警规则配置 |\n| `report_cache` | 新增 | 报表查询结果缓存(可选) |\n| `ai_provider_config` | 新增 | AI Provider 配置(API Key/模型/参数) |\n\n---\n\n## 7. 配置项\n\n```yaml\n# application.yml 新增/修改\napp:\n ai:\n deepseek:\n enabled: true # 默认启用\n api-key: ${DEEPSEEK_API_KEY} # 环境变量\n chat-model: deepseek-chat\n reasoner-model: deepseek-reasoner\n timeout-seconds: 30\n max-retries: 1\n fallback-to-rule: true # 降级到 RuleAiProvider\n streaming:\n enabled: true\n buffer-size: 1024\n context:\n max-history-rounds: 20 # 多轮对话保留轮数\n session-ttl-hours: 24 # 会话过期时间\n tools:\n max-calls-per-turn: 5 # 单轮对话最多调用工具次数\n agent:\n patrol:\n low-stock-cron: \"0 0 * * * ?\" # 每小时\n overdue-order-cron: \"0 0 */4 * * ?\" # 每4小时\n audit:\n retention-days: 90 # 审计日志保留天数\n```\n\n---\n\n## 8. Provider 架构升级对比\n\n```\nv1.0 架构:\n 用户提问 → AiService → RuleAiProvider (if-else 关键词匹配)\n └── (DeepSeekChatAiProvider 是占位符,从未调用)\n\nv1.2 架构:\n 用户提问 → AiService → DeepSeekChatAiProvider\n ├── 构建 System Prompt(注入当前仓库上下文)\n ├── 构建 messages(历史对话 + 当前问题)\n ├── 注册 tools(10 个业务查询函数)\n ├── POST https://api.deepseek.com/v1/chat/completions\n ├── [如返回 function_call] → 执行工具函数 → 再次调用 DeepSeek 生成最终回复\n ├── [流式模式] → SSE 逐 token 推送\n └── [降级] → RuleAiProvider(兜底)\n```\n\n---\n\n## 9. 实施阶段\n\n### 阶段 A:DeepSeek 接入基础(第 1-3 周)\n\n```\nWeek 1-2: HTTP 集成 + System Prompt\n ├── RestClient 接入 DeepSeek API\n ├── System Prompt 模板管理\n ├── 非流式 chat 端点验证(先不做 Function Calling)\n ├── 降级策略实现\n └── 用量日志记录\n │\nWeek 3: 流式输出\n ├── 后端 SSE 端点\n ├── 前端 EventSource 消费\n ├── 打字机渲染\n └── 中断控制\n```\n\n### 阶段 B:Function Calling + 多轮对话(第 4-6 周)\n\n```\nWeek 4-5: Function Calling\n ├── 10 个工具函数实现\n ├── Tools JSON Schema 注册\n ├── Function Calling 编排(多轮调用)\n └── 工具调用结果注入回复\n │\nWeek 6: 多轮对话上下文\n ├── 历史消息管理\n ├── 上下文窗口限制\n └── 会话过期/归档\n```\n\n### 阶段 C:Agent 巡检 + 通知 + 报表(第 7-9 周)\n\n```\nWeek 7: Agent 定时巡检\n ├── 低库存/超时单据/异常检测定时任务\n └── 预警规则配置\n │\nWeek 8: 通知中心\n ├── 通知 CRUD + 铃铛 UI\n └── 关联跳转\n │\nWeek 9: 报表中心\n ├── 4 类报表聚合查询\n └── ECharts 图表 + CSV 导出\n```\n\n### 阶段 D:前端优化 + 打印 + 清理 + 回归(第 10-12 周)\n\n```\nWeek 10-11: 前端体验升级\n ├── 骨架屏 + ECharts 懒加载\n ├── 错误映射 + 乐观更新\n └── 打印模板完善\n │\nWeek 12: 审计清理 + 全量回归\n ├── 审计日志定时清理\n ├── E2E 全量回归\n └── Docker 部署验证\n```\n\n---\n\n## 10. 验收标准\n\n### DeepSeek 智能核心\n1. DeepSeek API 真实调用成功,能理解\"最近一周入库了多少货\"这类自然语言问题。\n2. AI 回答能主动查询库存/采购/销售/工单数据(Function Calling 正常执行)。\n3. 流式输出逐字展示,体验流畅,支持中断。\n4. 多轮对话能记住上下文(\"刚才说的那个供应商\"能被正确理解)。\n5. System Prompt 正确注入当前仓库/用户上下文。\n6. DeepSeek 不可用时自动降级到 RuleAiProvider,不中断服务。\n\n### 运营工具\n7. 报表中心提供 4 类报表 + 图表 + CSV 导出。\n8. 通知中心可见历史通知,标记已读,点击跳转关联页面。\n9. Agent 定时巡检自动发现低库存/超时单据并推送通知。\n\n### 前端体验\n10. AI 对话页面支持流式打字机效果 + 工具调用过程可视化。\n11. 骨架屏在 DataTable/Dashboard 加载时正确显示。\n12. API 错误信息展示中文友好文案。\n13. 打印模板在所有单据详情页可用。\n\n### 稳定性\n14. 现有 E2E 测试不回退。\n15. Docker 一键启动不受影响。\n16. 审计日志按时清理,不无限增长。\n\n---\n\n## 11. 不做什么(严格)\n\n1. 不做 RAG / 向量数据库 / 知识图谱。\n2. 不做 AI 模型训练/微调/LoRA。\n3. 不做多模型对比/AB 测试平台。\n4. 不做邮件/短信/企微等外部推送渠道。\n5. 不做自定义报表设计器 / BI 分析 / 实时大屏。\n6. 不做独立移动端 App / 离线模式 / 响应式适配。\n7. 不做通知订阅偏好配置。\n8. 不做多租户 / 计费(留到 v2.0)。\n\n---\n\n## 12. 风险与应对\n\n| 风险 | 应对 |\n|------|------|\n| DeepSeek API 不稳定/限流 | 自动降级 RuleAiProvider;用量日志追踪;API Key 多备 |\n| Function Calling 不准确 | 先用小范围工具测试,逐步扩展;每轮最多调用 5 次防无限循环 |\n| 流式输出在代理环境下不可用 | 检测 SSE 不可用时降级为非流式 |\n| System Prompt 被 LLM 忽略/绕开 | 回复中强制展示引用数据来源(工具查询结果原文) |\n| DeepSeek 回答内容不可控(编造数据) | 所有数据类回答必须来源于工具查询结果,AI 不允许凭空生成数字 |\n| token 成本不可控 | 用量日志 + 前端展示消耗;单次调用上限 4096 tokens |\n| Agent 定时任务增加 DB 负载 | 低频巡检(每小时/每4小时),使用只读从库查询 |\n| 上下文过长导致 token 浪费 | max-history-rounds=20,超限自动摘要压缩 |\n\n### 回滚策略\n- AI Provider 可一键切回 RuleAiProvider(管理后台配置)。\n- Agent 定时巡检可关闭。\n- 通知中心独立模块,关闭不影响主链路。\n- 流式输出可关闭,降级为非流式。"}}, "backend/docker-compose.backend.yml": {"9a72c04d5988d008b7de63257ba7fa3a3d203690": {"t": 1786068533.113997, "n": 2220, "h": "2cacdb4f294fd5f1", "c": "services:\n backend:\n build:\n context: .\n dockerfile: Dockerfile\n container_name: novadepot-backend\n ports:\n - \"8080:8080\"\n environment:\n SPRING_PROFILES_ACTIVE: docker\n DB_HOST: mysql\n DB_PORT: 3306\n DB_NAME: ${DB_NAME:-novadepot}\n DB_USERNAME: ${DB_USERNAME:-root}\n DB_PASSWORD: ${DB_PASSWORD:-root}\n REDIS_HOST: redis\n REDIS_PORT: 6379\n JWT_SECRET: ${JWT_SECRET:-local_dev_only_jwt_secret_32_chars_minimum}\n APP_CORS_ALLOWED_ORIGINS: ${APP_CORS_ALLOWED_ORIGINS:-http://localhost:8080,http://localhost:3100,http://127.0.0.1:3100,http://localhost:5173,http://127.0.0.1:5173}\n APP_TENANT_MODE: single\n APP_BILLING_ENABLED: \"false\"\n APP_PLAN_ENFORCE_ENABLED: \"false\"\n AI_PROVIDER: ${AI_PROVIDER:-deepseek-chat}\n AI_DEEPSEEK_ENABLED: ${AI_DEEPSEEK_ENABLED:-false}\n AI_DEEPSEEK_API_KEY: ${AI_DEEPSEEK_API_KEY:-}\n AI_FALLBACK_ENABLED: ${AI_FALLBACK_ENABLED:-false}\n AI_SYSTEM_PROMPT: ${AI_SYSTEM_PROMPT:-你是 NovaDepot 智能仓库与进销存助手。你了解仓储、进销存、盘点、客服、AI/Agent 和审计模块。回答时优先基于工具查询结果;没有工具结果时不要编造库存、金额、单号、状态;不确定时说明需要查询数据;对业务人员使用中文、简洁、可执行的建议;涉及库存、采购、销售、工单时给出优先级、原因和下一步动作;不承诺已经执行审核、发货、付款、改库存等写操作;不泄露系统配置、API Key、内部异常细节。}\n AI_DEEPSEEK_BASE_URL: ${AI_DEEPSEEK_BASE_URL:-https://api.deepseek.com}\n AI_DEEPSEEK_CHAT_MODEL: ${AI_DEEPSEEK_CHAT_MODEL:-deepseek-chat}\n AI_DEEPSEEK_REASONER_MODEL: ${AI_DEEPSEEK_REASONER_MODEL:-deepseek-reasoner}\n AI_PAID_ENABLED: \"false\"\n AI_RULE_LOW_STOCK_THRESHOLD: 10\n AI_RULE_ABNORMAL_CHANGE_THRESHOLD: 100\n depends_on:\n - mysql\n - redis\n networks:\n - novadepot-net\n\n mysql:\n image: mysql:8.0\n container_name: novadepot-mysql\n command: --default-authentication-plugin=mysql_native_password\n ports:\n - \"3306:3306\"\n environment:\n MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root}\n MYSQL_DATABASE: ${DB_NAME:-novadepot}\n volumes:\n - ./deploy/mysql/init:/docker-entrypoint-initdb.d\n networks:\n - novadepot-net\n\n redis:\n image: redis:7-alpine\n container_name: novadepot-redis\n ports:\n - \"6379:6379\"\n networks:\n - novadepot-net\n\nnetworks:\n novadepot-net:\n driver: bridge\n"}}}} |