后端

预订字段重名规则的跨端闭环

运营人员配置预订字段时,字段标签既出现在管理表单,也会进入消费者填写页面。若创建、编辑和历史归档对“重名”的定义不同,用户可能在管理端保存成功,却在另一个入口遇到冲突。这个案例的关键是先定义同一条规则,再决定每一层承担什么。

运营人员配置预订字段时,字段标签既出现在管理表单,也会进入消费者填写页面。若创建、编辑和历史归档对“重名”的定义不同,用户可能在管理端保存成功,却在另一个入口遇到冲突。这个案例的关键是先定义同一条规则,再决定每一层承担什么。

规则先于界面

本案例把标签首尾空格去掉,再按不区分大小写的方式比较;范围限定在同一公司。归档字段仍占用名称,避免旧订单引用的字段与新字段同名。编辑当前字段且标签实际未变化时,不应因历史数据而阻止保存;改成其他字段已有的标签才报冲突。

场景期望结果
新建 Email 后再建 email拒绝,提示标签已存在
标签已归档,再用相同名称新建仍拒绝
编辑字段但保持原标签允许保存其他设置
把另一字段改名为已有标签拒绝并定位到标签输入框
不同公司的同名字段各自独立判断

前端负责及时反馈

提交前先查询已有字段,包括归档项;结果分页时要检查完整列表,不能只看第一页。发现冲突就把错误显示在标签输入框旁并聚焦该字段,而不是给出笼统 toast。编辑且名称未变时跳过这次预检查,避免无意义的请求。

这一步只能改善操作体验。列表可能刚好过期,也可能因网络故障不可用;此时写接口仍是最终判断者。后端返回明确的冲突码后,前端同样要把错误映射回标签字段。

后端负责最终一致性

创建和改名都在事务中按公司取得同一把锁,再检查标签是否已存在。比较范围包含归档记录;改名时排除当前字段。这样两个遵循同一流程的请求不会同时通过检查。冲突以稳定的 409 业务错误返回,前端不需要解析错误文案来猜测原因。

这里的锁是应用写入路径的约定,不等同于数据库唯一索引。新增批量导入、脚本或其他写入入口时,必须复用这条规则;并发双请求测试也应单独验证。若将来把归一化值持久化,并能安全处理旧数据,可再评估数据库约束作为更强的最终保护。

两端归一化不能想当然

前端 toLowerCase() 与 Python 的 casefold() 并不对所有 Unicode 字符给出相同结果。预检查可以沿用界面可用的近似规则,但不能把它当成服务端判定的复制品。对差异字符、空白字符和历史数据,应以服务端规则为准,并给前端一个明确的冲突响应。

验收时分别覆盖前端的提前拦截、服务端冲突后的字段级错误、归档字段、大小写与空格、未改名编辑和跨公司隔离。代码与这些路径测试能证明规则被接入;是否在目标环境生效,还需要部署和实际操作验证。