AI Coding · 统一码文件型券展示改造
产品需求写得很直白:国际版 xxx 订单详情,商品是"统一码",兑换方式是"上传文件"——券码信息区只展示券图,红框里的数字码模块(文案、长串码、复制按钮、"待使用"状态)全部藏起来。
技术约束同样直白:改动要小,只动这一个场景,别的券类型一行别碰;代码得能测、能维护,别把 Voucher.js 再堆成意大利面。
听起来像"加个 if 的事儿"。我一开始也这么以为。
开局:我在代码里"猜"了一轮
没有接口文档的时候,人很容易用 UI 现象反推后端语义。我(以及 AI 助手)早期走的就是这条路:
orderType === 13像是统一码 ✓voucherType !== 0像是"非纯数字码"→ 当成上传文件?✗voucherValue是个 jpeg URL → 有图就是文件型?✗
全仓搜 sendCodeType、exchangeType、git 历史、Jest 缓存……有效信息密度低得可怜。backEnd 仓库还是空的,没法交叉验证。
转折点来了:你扔过来两样东西——ws 商城 orderDetails 接口文档截图(voucherList 字段枚举),再加一条真实响应 JSON。局面才从"推断"变成"对照":
- 字段
voucherList[].orderType- 枚举值
- 13
- 字段
voucherList[].voucherType- 枚举值
- 5
voucherList[].orderTypevoucherList[].voucherTypeJSON 里 orderType: 13、voucherType: 5、voucherValue 指向 jpeg——和文档严丝合缝。这次改造最关键的质量保障,就在这一张截图 + 一条 JSON 上。
改对了什么
招式 1:展示规则和 UI 解耦(SRP 那种)
判定和取码逻辑抽到 Api.js 三个纯函数:
- resolveOrderType() — 处理字段层级差异(券级 → 子单级 → 订单级)
- isUnifiedCodeFileVoucher() — 唯一的业务开关
- getVoucherDisplayCode() — 展示层取码
Voucher.js 只负责一件事:红框模块渲不渲染。好处很实在:
- 11 个单测覆盖层级解析与边界(13+5 / 13+1 / 12+5) - 以后改 UI 不用再把 orderType 判断抄第三遍 - 类组件里常见且稳妥:业务规则进无副作用模块,组件做编排
// 层级回退:?? 只对 null/undefined 生效,0 不会被误判成"缺失"
item?.orderType ?? subOrderType ?? orderData?.orderType招式 2:改动面卡得紧
没动 getStatus、退款参数 voucherCode、图片轮播、voucherType != 7 过滤。非 13+5 仍走原 renderDetail 分支;统一码非文件型券仍用 code,其他场景仍用 voucherCode(commit 48e51aa8 的老规矩保留)。
这就是"只改上传文件场景"该有的样子。
招式 3:主动避开同名字段的坑
排查过程中特意区分了几组容易看岔的字段:
- subOrderDetailsList[0].voucherType: 13 — 子单级,含义不同于券级
- orderProductDetails.exchangeType: 104 — 商品兑换配置,不是券展示类型
- voucherCreateMethond / createVoucherWay — 发码方式,文档没定义成"上传文件展示类型"
JSON 扁平嵌套下,同名不同义是集成前端最常见的 bug 来源。路径写不对,测再多也白搭。
还能更好的地方
前期探索成本偏高
根因很简单:需求里的"上传文件"是后端枚举,不能从前端 UI 反推;backEnd 仓库又空的。类似任务,文档/抓包前置能砍掉大量无效搜索。推断不是不能用,得标明"可能误伤 13+1 二维码"这种风险。
测试覆盖还有洞
Api.test.js 把判定函数盖住了,但缺:
- 组件级测试:13+5 下红框 DOM 是否真的消失
- 混合券列表:第一张非文件型、后面是文件型时的展示(renderContent 仍按第一张 voucherType===0 决定图片区,这是历史隐患)
Review 还点出一个产品边界:13+5 在 refunding/refunded 仍渲染"退款详情"按钮,和"严格只展示图片"可能不一致——待产品确认,目前算半开着的门。
文档可以再沉淀一行
voucherType 枚举 0~5 现在只散落在注释里。建议在 Api.js 或内部 wiki 补一句"来源:ws 商城 orderDetails 文档",后人改代码时少踩一次坑。
原理,不废话版
1. 业务规则绑后端契约,不绑 UI 现象
voucherValue 有 URL → 有图,不能说明"兑换方式 = 上传文件"。voucherType=5 → 文档定义"文件",才是契约。宽条件(比如 voucherType≠0)的典型后果:统一码 + 二维码(13+1)被误隐藏数字码。
2. 空字符串驱动 UI,结构分支防空壳
getVoucherDisplayCode 在 13+5 返回 '',renderCode / renderCopy 用 if (!voucherCode) return null。数据层空值驱动不渲染,比在多处重复 if (isUnifiedCodeFileVoucher) 更 DRY;renderDetail 仍对整个红框做分支,是为了避免只剩"券码"标题、下面啥也没有的空壳 DOM——数据驱动和结构分支的折中。
3. 单测金字塔
纯函数单测:快、稳,11 条已够判定逻辑回归。组件测试要 mock intl / CopyToClipboard,成本高,但适合锁 UI 契约。E2E 用真实 13+5 订单走查。三层各干各的,别指望一层包打天下。
4. 遗留类组件上的最小 diff
Voucher.js 还扛着轮播、Popup、CopyToClipboard、路由跳转。这次只动 renderDetail 分支,没重构 Hooks——交付风险可控。规则外置到 Api.js,已经为将来抽 useVoucherDisplayPolicy(orderData, item) 留了接口。
结语
核心场景(13+5 待使用)符合;退款态按钮待产品拍板
判定精确,13+1 等场景未误伤
规则外置 + 单测较好;缺组件级与混合券回归
文档/抓包前置可显著缩短前期搜索
这次改造的价值,不在于又隐藏了一个红框,而在于用后端明确枚举替代前端推断,再用纯函数 + 精准分支实现"只改上传文件场景"。
下次接到"枚举型展示规则"的需求,我会先把文档或一条 orderDetails JSON 甩到聊天框里,再让 AI 写第一行代码。推断可以留着当草稿,但别把它当交付标准——不然你和我都会在前仓里多绕好几圈。
本文属于 AI 实用主义流派 的第 41 篇肉身实战。
发表评论
分享你的想法和反馈