电子制造企业的仓库与物料管理原本完全依赖 Excel:12 张分表按供应仓、自建仓、样机、半成品、芯片等维度各自维护,合计 1200 余行数据,分散在多人电脑上。版本混乱、库存口径不一致、采购与到货状态靠口头同步、查一个物料要翻遍十几张表,成为日常运转的瓶颈。
目标是做一套内网可用的轻量级 LIMS:既要把 12 张 Excel 原表搬进系统、保留"像 Excel 一样好用"的编辑手感,又要把库存、采购、报价、文件管理与 AI 问答收进统一入口;同时不增加运维负担
系统为单页 Web 应用,侧栏 9 个板块:
- 仪表盘:登录后总览与快捷操作入口,按角色展示可用板块。
- 内容中心:文件上传、分类与站内预览(Office 文档转 PDF、表格类前端直渲染),支持全屏查看,库存主表作为唯一附件集中管理。
- 小助手(AI 问答):自然语言查询库存、物料档案、BOM 用料、采购需求、更新日志,回答一律回源到 12 张库存原表并附逐仓明细;模型不可用时自动降级为本地确定性回答。
- 报价管理 / 采购管理:采购单创建、发货确认、入库登记;按包装规格自动换算"需采购几盘/几袋"。
- 仓库管理:库存四态、出库记录,并将 12 张库存表就地内嵌(按组切换),不跳板块、复用同一套编辑引擎。
- Excel 库存表:自研在线表格引擎——冻结窗格、公式(SUM/IF/VLOOKUP)、关键字列过滤、列头单击改名、填写列(减库存)与送货列(加库存)按差值双向联动、差额与建议采购量自动计算、填写按轮次自动存档。
- 设置 / 系统管理(仅超管):用户管理、在线会话列表与强制下线。
3、业务流程、功能路径描述
登录(两级权限:超管与普通账号,凭据由服务器环境变量下发)→ 从仪表盘或侧栏进入板块 → 在仓库管理 / Excel 库存表中以单元格为单位直接编辑,改动即时计算差额与建议采购量并自动保存、按轮次留档 → 采购板块依据差额生成采购单,走"确认发货 → 已入库"状态流转并回补库存 → 成员用自然语言向小助手提问,答案自动标注来自哪张表、哪个仓位。
全部只使用 Node.js 内置能力,让 2 核 2G 的低配云主机也能长期稳定运行,且不存在依赖升级带来的维护成本:
- 后端:Node.js 原生 http 模块手写路由 + 内置 node:sqlite 直连数据库,无任何第三方框架或 ORM;认证为自签 token + 服务端会话表,支持单点踢下线、改密即让旧会话失效。
- 前端:单个 HTML 文件承载全部页面、样式与交互逻辑,内置 HyperFormula 作为公式引擎,实现类 Excel 的编辑体验。
- 数据层:12 张库存表以 JSON 结构持久化,通过列映射与解析层统一口径;物料、采购、报价、检验、批次、附件等业务数据走 SQLite 关系表。
- AI 小助手:两跳 LLM 调用(结构化动作 → 执行查询 → 自然语言润色),与业务数据解耦,并具备无模型时的本地降级路径。
- 运维:独立部署的监测服务,只读接入主系统的数据库(PRAGMA query_only=ON)、探活接口与日志,进程、目录、端口与主系统完全隔离,常驻内存仅约 15 MB。
2、我负责的模块和结果(量化)
独立完成数据库设计、后端接口、前端页面到部署运维的全栈实现,累计 49 次提交、多次线上发布。可量化结果:
- 支撑 12 张库存表 / 1232 行数据、370 条物料档案、BOM 15 套、采购单与批次台账、多个账号的日常使用;
- 前端单文件约 425 KB、后端约 78 KB,在 2G 内存机型上实测可用内存仍约 1.3 GB;
- 数据安全:每天 2 次自动备份(保留 7 天)+ 本地异地镜像(保留 14 天)+ 备份失败自动告警 + 恢复演练 10 项检查全部通过;
- AI 小助手累计 150+ 次调用、约 5.8 万 tokens,回答全部回源到 12 张原表;
- 监测平台 5 分钟一次采样,历史保留 90 天。
3、我遇到的难点、坑,和解决方案
① 库存口径打架(最大的坑):物料档案里存的是数周前从某一张表导入的"理论库存"快照,与 12 张表的实时值互相矛盾,AI 助手会照着旧数字作答。解决:确立"12 张 Excel 原表是库存唯一权威来源",专门写解析层统一各表不同的列名、按优先级识别库存列(实时库存 > 总计 > 剩余 > 库存 > 数量)、处理合并单元格的名称继承、碰到表尾"第二段表头"立即停止解析、保留负数缺口与"5 套"这类文字数量,并在所有回答入口强制走这条路径。
② 表格引擎的细节坑:冻结窗格错位、列插入锚点取错导致列序颠倒、全屏切换卡顿(用 contain: layout paint 修复)、调用未定义函数导致整表渲染中断(加 typeof 守卫兜底)。
③ 凭据泄露:AI 助手能读到更新日志里写下的管理员密码,任何已登录用户问一句就能拿到。解决:凭据全部移到服务器环境变量、