规则配置开发中的踩坑经验与优化思路分享

Mr.雨童 工具 阅读 1,298
赞 13 收藏
二维码
手机扫码查看
反馈

项目初期的技术选型

最近刚结束一个电商后台管理系统,说起来这个项目还挺有意思的。客户要求能在后台灵活配置各种促销规则,比如满减、折扣、赠品这些。一开始我还在想是不是直接写死逻辑算了,毕竟时间紧任务重。但后来发现规则组合实在太多了,硬编码根本搞不定。

规则配置开发中的踩坑经验与优化思路分享

经过一番调研,最后决定用JSON Schema来做规则配置。主要是看中了它的灵活性和可扩展性,而且社区生态也不错。说实话刚开始我对这玩意也不是很熟,完全是被逼上梁山。

核心代码实现

先说下最终的实现方案吧。我把所有规则都抽象成了一个个配置项,每个规则对应一个JSON Schema定义。下面是一个简单的满减规则示例:

const ruleSchema = {
  type: "object",
  properties: {
    ruleType: { enum: ["fullReduction"] },
    threshold: { type: "number", minimum: 0 },
    discount: { type: "number", minimum: 0 }
  },
  required: ["ruleType", "threshold", "discount"]
};

// 验证函数
function validateRule(rule) {
  const ajv = new Ajv();
  const validate = ajv.compile(ruleSchema);
  const valid = validate(rule);
  if (!valid) console.log(validate.errors);
  return valid;
}

// 使用示例
const sampleRule = {
  ruleType: "fullReduction",
  threshold: 100,
  discount: 20
};

validateRule(sampleRule); // true

最大的坑:性能问题

这里要重点说下性能问题,真是踩了不少坑。最初我是把所有规则都放在一个大的JSON Schema里,结果当规则数量超过50条时,页面就明显卡顿了。尤其是在表单验证的时候,动不动就几秒才出结果。

折腾了半天才发现,原来是AJV在处理复杂Schema时会有性能瓶颈。后来我把大Schema拆分成多个小Schema,按需加载。具体做法是根据ruleType来动态加载对应的Schema定义,这样每次只需要验证一小部分规则。

const schemaMap = {
  fullReduction: {...},
  discount: {...},
  gift: {...}
};

function getSchemaByType(type) {
  return schemaMap[type] || null;
}

不过这里还有个小问题没完全解决,就是当用户频繁切换规则类型时,还是会有些卡顿。目前是通过防抖来缓解的,但不是根本解决方案。

另一个麻烦:错误提示

说到错误提示,又是一把辛酸泪。AJV默认的错误信息对普通用户来说太技术化了,什么”should be number”这种。开始我尝试自己写错误映射,但随着规则变多,维护成本太高了。

最后用了个取巧的办法,在每个字段定义里直接加了errorMessage属性:

const ruleSchema = {
  type: "object",
  properties: {
    threshold: {
      type: "number",
      minimum: 0,
      errorMessage: {
        type: "必须填写数字",
        minimum: "金额不能小于0"
      }
    },
    // 其他字段...
  }
};

虽然这样会让Schema定义变得臃肿,但确实大大简化了错误处理逻辑。

回顾与反思

回过头来看,这个方案整体还是挺成功的。最大的收获是对JSON Schema的理解深入了不少,也积累了一些性能优化的经验。特别是在处理复杂表单验证时,分而治之的思路很重要。

当然也有一些遗憾的地方。比如那个切换卡顿的问题还没彻底解决,另外移动端的适配也花了不少时间。还有就是跟后端联调时发现,他们用的Java那边解析JSON Schema的库跟前端不太一致,导致一些边缘case需要额外处理。

以上是我个人对这个规则配置项目的完整讲解,有更优的实现方式欢迎评论区交流。这种技术点我觉得还挺有价值的,后续可能会再写篇关于JSON Schema进阶用法的文章。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论