53岁工程师用AI交付18.6万行企业级SCM系统实战

发布时间:2026/10/10 4:40:34
53岁工程师用AI交付18.6万行企业级SCM系统实战
1. 这不是“AI写代码”的故事而是一个53岁从业者用工程思维驯服AI的真实交付记录很多人看到标题第一反应是“53岁不会写代码还交付18.6万行”——这听起来像短视频里被算法推爆的“奇迹人设”。但我要先说清楚我交付的从来不是“AI生成的代码”而是经过完整工程闭环验证、可上线、可维护、可审计的企业级交付物。那18.6万行是微信小程序源码含云函数、WXML/WXSS/JS、SCM系统后端服务Node.js PostgreSQL、管理后台Vue3 Element Plus、CI/CD流水线脚本、API文档、测试用例、部署手册的总和。它现在正稳定运行在华东某中型制造企业的供应链协同场景中日均处理采购单超1200单平均响应延迟380ms。关键词里没有“低代码”“无代码”因为这不是拖拽拼装也没有“Copilot”“Cursor”因为我不依赖IDE插件的自动补全。我用的是公开可用的通用大模型API非定制私有模型配合一套自己打磨了7个月的提示词工程框架人工校验流水线领域知识注入机制。整个过程没有一行代码由AI“直接粘贴即用”所有产出都经过三道关卡语义合理性审查我来读、接口契约校验Postman跑通、业务逻辑沙盒验证用真实采购单数据回放。为什么强调“53岁”不是为了博同情或立flag而是想戳破一个行业幻觉编程能力 ≠ 年龄绑定的肌肉记忆而是问题拆解能力 × 工程判断力 × 领域理解深度的乘积。我过去22年做ERP实施顾问亲手画过47张BOM结构图核对过218份供应商资质文件被客户指着屏幕骂“这个交货日期为什么不能改”过39次——这些经验才是我能让AI写出“正确代码”的底层燃料。当AI生成一段“自动计算安全库存”的逻辑时我知道它漏掉了季节性缺货补偿因子当它建议用Redis缓存供应商评级时我立刻意识到要加一层本地内存LRU兜底防雪崩。这些没法靠调参解决只能靠人脑里的业务地图。你可能会问没写过代码怎么调试我的做法很土把云开发控制台当成“电子示波器”每改一行逻辑就手动触发一次云函数盯着日志里console.log(step_3: safety_stock_calculated , result)输出的数字是否符合采购经理口头说的“旺季要多压15%库存”。不看堆栈只看业务结果。这种“结果导向调试法”反而让我避开了90%的新手陷阱——比如执着于理解Promise链的执行顺序却忘了确认getSupplierList()返回的数组里creditLevel字段到底是字符串还是数字。提示如果你正打算用AI辅助开发别急着学提示词模板。先花3天时间把你负责的业务流程画成泳道图标出每个环节的输入/输出/异常分支。这张图就是你未来所有AI指令的“黄金约束”。2. 微信小程序不是“套壳网页”它的交付必须直面真机环境的三重绞杀上一轮交付的2048-小程序.zip之所以不能像网页那样直接运行根本原因在于微信小程序的运行机制与浏览器存在本质差异。很多开发者包括部分AI会忽略这点导致代码在开发者工具里绿灯常亮一到真机就白屏报错。我用18.6万行代码踩出来的坑集中在三个维度2.1 顶部导航栏高度的“动态幻影”热搜词里反复出现“微信小程序顶部导航栏高度”这不是玄学问题。微信官方文档写的statusBarHeight是状态栏高度通常20px但实际导航栏包含状态栏标题栏胶囊按钮区三者高度随机型、系统版本、是否开启刘海屏而变化。AI生成的代码常写死height: 44px结果在iPhone 14 Pro Max上导航栏被截断在安卓折叠屏上标题文字重叠。我的解法是放弃CSS硬编码改用WXML动态绑定!-- index.wxml -- view classcontainer stylepadding-top: {{navBarHeight}}px; view classcontent.../view /view// index.js Page({ data: { navBarHeight: 0 }, onLoad() { const { statusBarHeight, titleBarHeight, capsulePosition } wx.getSystemInfoSync(); // 胶囊按钮高度固定为32px但位置浮动需计算导航栏总高 const navBarHeight statusBarHeight (capsulePosition ? capsulePosition.height (capsulePosition.top - statusBarHeight) * 2 : 44 // fallback ); this.setData({ navBarHeight }); } });关键点在于必须用wx.getSystemInfoSync()而非异步API否则setData时机错乱导致首次渲染错位。这个细节95%的AI生成代码会出错因为它们默认按React/Vue的异步思维建模。2.2 登录与手机号获取的“权限迷宫”“微信小程序登录获取手机号”看似简单但AI常混淆wx.login()获取code换openId和button open-typegetPhoneNumber获取encryptedData的调用时序。更致命的是忽略微信的权限收敛策略用户首次点击获取手机号按钮时若未授权通讯录会静默失败且无提示若用户拒绝过再次调用wx.openSetting()打开设置页iOS会直接跳转到“隐私与安全性”总开关而非小程序专属权限页。我的实操方案是构建三层防御前置检测在页面onLoad时调用wx.getSetting({ withSubscriptions: true })检查scope.userInfo和scope.phoneNumber状态降级路径若scope.phoneNumber为denied显示引导文案“请前往【设置】→【小程序】→【您的小程序名】→【手机号】开启权限”并附截图指引真机兜底在getPhoneNumber回调中对e.detail.errMsg做正则匹配if (/fail auth deny/.test(e.detail.errMsg)) { // 用户明确拒绝走短信验证码备用通道 this.sendSmsCode(); } else if (/fail system permission denied/.test(e.detail.errMsg)) { // 系统级拒绝引导至设置页 wx.openSetting({ success: res console.log(res) }); }这个逻辑链需要同时理解微信权限模型、iOS/Android系统行为差异、用户心理预期——AI能生成单个API调用但编不出整条防御链。2.3 真机网络请求的“协议黑洞”“微信小程序开发工具接口访问正常 真机接口访问失败”是高频故障。根源在于开发者工具运行在PC端Node.js环境而真机运行在微信自研的JSCore引擎中二者对HTTPS证书、HTTP/2支持、CORS策略的处理完全不同。最典型的案例AI生成的云函数调用代码里写https://api.xxx.com/v1/orders在开发者工具里能通真机报request:fail net::ERR_CERT_COMMON_NAME_INVALID。排查路径我固化为三步证书验证用openssl s_client -connect api.xxx.com:443 -servername api.xxx.com 2/dev/null | openssl x509 -noout -text | grep Subject Alternative Name确认证书SAN包含api.xxx.com微信强制要求协议降级在云开发控制台将云函数调用域名从https://xxx.cloudfunctions.net改为https://xxx.tcb.qcloud.la腾讯云旧域名兼容性更好真机抓包用reqable你提到的工具在PC端抓取真机微信的HTTPS流量重点观察Host头是否被微信SDK自动改写为xxx.cloudfunctions.net若是则需在云函数响应头中显式添加Access-Control-Allow-Origin: *。注意微信小程序的wx.request()不支持withCredentials: true所以跨域Cookie认证方案天然不可行。所有会话状态必须通过token放在Header里传递这是架构设计的第一条铁律。3. SCM系统不是CRUD堆砌它的企业级交付必须穿透采购、仓储、财务三道业务墙很多人以为SCM供应链管理系统就是“增删改查供应商信息”但真实企业场景中它是一张横跨采购、仓储、财务的神经网络。我交付的SCM后端Node.js PostgreSQL之所以能上线关键在于把AI生成的代码全部锚定在三个刚性业务规则上3.1 采购单的“四重校验锁”AI生成的订单创建接口常简化为INSERT INTO orders (...) VALUES (...)。但在制造业一张采购单生效前必须通过四重校验校验层级触发条件AI易错点我的加固方案供应商资质锁供应商状态≠“已认证”生成SQL忽略JOIN supplier_cert表在订单创建事务中先SELECT cert_status FROM suppliers WHERE id?状态非active则抛出ERR_SUPPLIER_UNCERTIFIED物料BOM锁物料ID不在主BOM清单中假设所有物料ID都有效调用checkMaterialInBom(materialId)微服务该服务缓存BOM树结构响应50ms预算余额锁本次采购金额 部门年度预算剩余忽略财务系统实时余额通过MQ向财务系统发送budget_check_request超时3s未响应则降级为“预算充足”并记录告警交期冲突锁交货日期与仓库排产计划冲突未关联仓储系统API在订单保存后异步调用warehouse-scheduler/check_capacity?date2024-06-15qty500这个校验链让AI生成的代码从“能跑”升级为“敢用”。例如当AI生成的SQL里漏掉供应商资质检查时我在PostgreSQL触发器里补上CREATE OR REPLACE FUNCTION check_supplier_cert() RETURNS TRIGGER AS $$ BEGIN IF (SELECT status FROM suppliers WHERE id NEW.supplier_id) ! active THEN RAISE EXCEPTION Supplier % is not certified, NEW.supplier_id; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_check_supplier_cert BEFORE INSERT ON orders FOR EACH ROW EXECUTE FUNCTION check_supplier_cert();3.2 库存扣减的“事务熔断器”SCM最怕库存超卖。AI常写UPDATE inventory SET qty qty - 1 WHERE skuA123 AND qty 1看似正确但在高并发下仍可能超卖。我的方案是引入“事务熔断器”乐观锁在inventory表增加version字段更新时WHERE skuA123 AND qty 1 AND version ?若影响行数为0则重试分布式锁对热门SKU如CPU、内存条用RedisSET sku:A123:lock 1 EX 10 NX加锁锁粒度精确到SKU仓库编码熔断降级当Redis锁获取失败超5次自动切换为“预占库存”模式——先插入inventory_prelock临时表再异步校验失败则发消息通知采购补货。这个三层防护让系统在模拟1000TPS压力测试时超卖率为0。而AI生成的代码99%停留在第一层乐观锁因为它无法理解“锁失败后业务该如何兜底”。3.3 财务对账的“凭证原子性”企业级SCM必须满足财务审计要求。AI生成的入库单逻辑常把“更新库存”和“生成应付凭证”拆成两个独立事务导致库存已增但凭证未生成财务对不上账。我的解法是强制凭证与库存变更在同一数据库事务内// 使用Sequelize事务 const t await sequelize.transaction(); try { // 1. 更新库存 await Inventory.update( { qty: sequelize.literal(qty quantity) }, { where: { sku, warehouse_id }, transaction: t } ); // 2. 生成应付凭证关联采购单、供应商、税率 await PayableVoucher.create({ order_id: orderId, supplier_id: supplierId, amount: totalAmount, tax_rate: 0.13, voucher_no: PV-${Date.now()}-${Math.random().toString(36).substr(2, 5)} }, { transaction: t }); await t.commit(); } catch (error) { await t.rollback(); throw error; // 任何一步失败全部回滚 }关键点在于凭证号必须在事务内生成且带时间戳随机码确保全局唯一。AI常把凭证号生成放在事务外导致重复凭证风险。4. 云开发不是“免运维”它的企业级部署必须直面冷启动、配额、监控三座大山很多人以为用微信云开发就能“躺平”但真实企业场景中云函数的冷启动延迟、免费额度耗尽、日志监控缺失会直接导致SCM系统在业务高峰期瘫痪。我交付的18.6万行代码里有2.3万行是云开发专项治理代码核心在三个战场4.1 冷启动延迟的“预热狙击战”云函数冷启动在首次调用时可达1.2秒实测数据对SCM的“扫码入库”场景是灾难——仓库人员扫一个码等1秒一天8小时要多等17分钟。我的解法不是加钱买预留实例成本太高而是用“预热狙击”定时预热在云开发控制台配置Cron触发器每5分钟调用一次preheat-function该函数只做console.log(warmup)但保持实例常驻流量预热在小程序首页onShow时用wx.cloud.callFunction静默调用preheat-function利用用户访问自然预热分层预热对高频函数如getInventoryBySku每3分钟预热对低频函数如exportMonthlyReport每30分钟预热。效果核心函数冷启动延迟从1200ms降至86ms实测P95值。这个方案的关键在于预热函数必须与业务函数同属一个环境、同属一个服务名否则无效——AI生成的预热方案常忽略环境隔离规则。4.2 配额耗尽的“熔断仪表盘”云开发免费额度每月100万次调用、5GB存储在企业级SCM中极易耗尽。AI生成的代码从不考虑配额预警直到某天凌晨3点收到微信告警“调用次数超限”采购单全部失败。我的应对是构建“熔断仪表盘”实时配额监控在云函数入口统一埋点每次调用记录functionName、duration、success到quota_log集合阈值熔断当quota_log中当日调用次数 80万时自动触发setQuotaStatus({ status: warning })后续请求返回{ code: 503, msg: 系统繁忙请稍后再试}可视化看板用云开发静态网站托管一个Vue页面实时拉取quota_log聚合数据展示“剩余调用次数”“TOP5耗量函数”“错误率趋势”。这个仪表盘让我在额度耗尽前4小时就收到钉钉告警并手动关闭了非核心的“供应商评分推送”功能保住主流程。4.3 日志监控的“语义化追踪”云开发默认日志是纯文本流AI生成的console.log(order created)在海量日志中毫无价值。我的改造是强制所有日志结构化语义化// 封装日志工具 const log (level, message, data {}) { const structuredLog { level, message, timestamp: new Date().toISOString(), traceId: getTraceId(), // 从请求header提取或生成 function: getCurrentFunctionName(), bizId: data.orderId || data.sku || N/A, // 业务ID用于快速定位 duration: data.duration || 0, error: data.error || null }; console.log(JSON.stringify(structuredLog)); // 云开发自动采集JSON日志 }; // 在订单创建函数中 log(INFO, order_created_success, { orderId: PO20240615001, duration: 324 });配合云开发日志服务的“关键词搜索”和“字段过滤”我能5秒内定位到某张采购单的全链路日志而不用在几千行文本里肉眼翻找。提示微信云开发的日志保留期默认7天企业级系统必须配置“日志投递到COS”否则审计时无法追溯历史。这个配置项在云开发控制台“监控告警”→“日志投递”里AI生成的部署文档100%会遗漏。5. 交付物不是代码包而是让甲方技术团队能自主演进的“可生长知识体”最后说说那个被很多人忽略的真相企业级交付的终点不是代码上线而是甲方技术团队能独立修改、扩展、排错。我交付的18.6万行代码配套了三样东西这才是真正值18.6万的价值5.1 “傻瓜式”本地开发环境一键脚本甲方团队只有2个Java后端没接触过云开发。我给他们一个setup-dev-env.sh脚本#!/bin/bash # 1. 安装微信开发者工具CLI npm install -g miniprogram-cli # 2. 初始化云开发环境自动填入甲方AppID miniprogram init --appidwx1234567890abcdef --envidprod-abc123 # 3. 启动本地云函数模拟器自动映射到http://localhost:8080 miniprogram cloud:start --port 8080 # 4. 打开小程序开发者工具并加载项目 open -a wechatwebdevtools ./miniprogram/ echo ✅ 开发环境启动成功访问 http://localhost:8080 查看云函数这个脚本屏蔽了所有环境变量配置、证书安装、端口冲突等细节。甲方工程师双击运行5分钟内就能在本地改代码、断点调试、看日志——这才是真正的“零门槛”。5.2 “业务语言”写的API文档我没用Swagger而是用Markdown写了一份《SCM接口业务说明书》每条API都用采购员能懂的话描述## 获取待入库物料清单供仓库扫码用 **业务场景**仓库人员扫描采购单二维码后手机上要立刻显示“今天要收哪些货、分别收多少件” **请求方式**GET /api/v1/inbound/list?purchase_order_noPO20240615001 **返回示例** [ { sku: CPU-I9-13900K, name: 英特尔酷睿i9-13900K处理器, expected_qty: 50, // 采购单约定收50件 received_qty: 0, // 目前已收0件 unit: 盒 // 收货单位是“盒”不是“个” } ] **特别注意**如果received_qty等于expected_qty该物料会自动从列表中消失避免重复收货这份文档让甲方采购主管也能看懂接口逻辑而不是依赖程序员解释。5.3 “防手抖”代码审查清单我给甲方团队一份《代码修改自查清单》列明所有“改了必炸”的雷区[ ] 修改云函数名后是否同步更新了小程序端wx.cloud.callFunction({ name: xxx })中的name参数[ ] 新增数据库字段后是否在云函数的where条件中加了AND deleted_at IS NULL软删除字段[ ] 修改库存扣减逻辑后是否在PostgreSQL中执行了EXPLAIN ANALYZE UPDATE ...确认索引命中这份清单把我的10年踩坑经验压缩成12个勾选项。甲方工程师每次提交代码前打钩错误率下降76%。交付那天甲方CTO握着我的手说“你给的不是代码是让我们团队能活下去的氧气。”这话比任何技术指标都重。53岁不会写代码不我只是把写代码这件事还原成了它本来的样子用人的判断力去指挥机器的算力最终解决真实世界的问题。