关于 business-rule-patterns
面向 ServiceNow 开发者的业务规则模式技能,讲解规则时机、记录操作和字段变更检测,并提供性能与常见模式建议。
主要功能
- 01区分 Before、After、Async 和 Display
- 02使用 current 与 previous 处理记录
- 03检测字段变化并设置运行条件
- 04提供自动分配和级联更新模式
- 05优化规则性能
适用场景
- 01验证记录并自动填写字段
- 02在记录更新后创建关联记录
- 03将耗时集成放到后台处理
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ serac-labs/ serac --skill business-rule-patterns安装后在 Claude Code 中输入/business-rule-patterns确认已加载。
详细介绍
ServiceNow 业务规则最佳实践
业务规则是在显示、插入、更新或删除记录时执行的服务器端脚本。
各类型的适用场景
| 类型 | 时机 | 使用场景 | 性能影响 |
|---|---|---|---|
| Before | 写入数据库之前 | 验证、修改当前记录 | 低 |
| After | 写入数据库之后 | 创建相关记录、发送通知 | 中 |
| Async | 后台(提交后) | 耗时处理、集成 | 无(在后台运行) |
| Display | 表单加载时 | 修改表单显示、设置默认值 | 低 |
可用对象
// In Business Rules, these are always available:
current // The record being operated on
previous // The record BEFORE changes (update/delete only)
gs // GlideSystem utilities
Before 业务规则
用于验证和字段操作:
// Prevent update if condition not met
;(function executeRule(current, previous) {
if (current.state == 7 && previous.state != 6) {
current.setAbortAction(true)
gs.addErrorMessage("Must resolve before closing")
}
})(current, previous)
// Auto-populate fields
;(function executeRule(current, previous) {
if (current.isNewRecord()) {
current.setValue("caller_id", gs.getUserID())
current.setValue("opened_by", gs.getUserID())
}
})(current, previous)
Before 规则中切勿执行以下操作:
- 调用
current.update()(会导致递归!) - 查询其他表(保持执行快速)
- 调用外部 API
After 业务规则
用于处理相关记录:
// Create child record when priority is P1
;(function executeRule(current, previous) {
if (current.priority.changesTo(1)) {
var task = new GlideRecord("task")
task.initialize()
task.setValue("short_description", "P1 Follow-up: " + current.number)
task.setValue("parent", current.sys_id)
task.insert()
}
})(current, previous)
// Update parent record
;(function executeRule(current, previous) {
var parent = new GlideRecord("problem")
if (parent.get(current.problem_id)) {
parent.setValue("related_incidents", parent.related_incidents + 1)
parent.update()
}
})(current, previous)
Async 业务规则
用于不应阻塞事务的耗时处理:
// External integration
;(function executeRule(current, previous) {
var integrator = new ExternalSystemIntegration()
integrator.syncIncident(current.sys_id)
})(current, previous)
// Send custom notification
;(function executeRule(current, previous) {
gs.eventQueue("incident.priority.high", current, current.assigned_to, gs.getUserID())
})(current, previous)
实用方法
current 方法
current.isNewRecord() // True if insert
current.isValidRecord() // True if record exists
current.getValue("field") // Get field value
current.setValue("field", val) // Set field value
current.setAbortAction(true) // Cancel the operation
current.operation() // 'insert', 'update', 'delete'
current.isActionAborted() // Check if aborted
字段变更检测
current.priority.changes() // Field changed (any value)
current.priority.changesTo(1) // Changed TO this value
current.priority.changesFrom(3) // Changed FROM this value
current.priority.nil() // Field is empty
previous 比较
// Check if field was modified
if (current.state != previous.state) {
gs.info("State changed from " + previous.state + " to " + current.state)
}
// Check specific change
if (current.assigned_to.changes() && !previous.assigned_to.nil()) {
gs.info("Reassignment occurred")
}
条件示例
使用条件限制规则的运行时机:
| 条件 | 含义 |
|---|---|
current.active == true | 仅处理活动记录 |
current.isNewRecord() | 仅在插入时运行 |
current.priority.changes() | 仅在优先级变更时运行 |
gs.hasRole('admin') | 仅对管理员运行 |
current.assignment_group.nil() | 仅在未分配时运行 |
性能最佳实践
- 使用条件 - 限制规则的运行时机
- 保持 Before 规则快速 - 尽可能不执行查询
- 集成使用 Async - 不要阻塞事务
- 避免使用 Display 规则 - 会减慢表单加载速度
- 设置 Order - 数值越小越先运行(范围为 100-500)
- 检查“何时运行” - 插入、更新、删除、查询
常见模式
自动分配
// Before Insert/Update
if (current.assignment_group.changes() && !current.assignment_group.nil()) {
var members = new GroupMembers(current.assignment_group)
current.assigned_to = members.getNextAvailable()
}
级联更新
// After Update
if (current.state.changesTo(7)) {
// Closed
var tasks = new GlideRecord("task")
tasks.addQuery("parent", current.sys_id)
tasks.addQuery("state", "!=", 7)
tasks.query()
while (tasks.next()) {
tasks.setValue("state", 7)
tasks.update()
}
}
评论
支持 Markdown