mcpField
C
catalog-items

catalog-items

github.com/serac-labs开发7762 次安装9 周前更新
代码仓库

关于 catalog-items

面向 ServiceNow 开发人员的服务目录技能,介绍目录项目、变量、客户端脚本、审批与履行流程的设计,并包含记录生产器和订购指南示例。

主要功能

  1. 01设计目录、类别和可申请项目
  2. 02配置变量与可复用变量集
  3. 03编写客户端脚本和表单验证
  4. 04设置定价、审批与履行流程
  5. 05创建记录生产器和订购指南

适用场景

  1. 01构建自助服务申请表单
  2. 02复用多个目录项目的字段组
  3. 03按条件验证申请并计算价格
  4. 04为多项目入职申请设置向导

MCP 相关

文档提及用于创建目录变量的 MCP 工具,包括 snow_create_variable 和 snow_create_catalog_variable。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/serac-labs/serac --skill catalog-items

安装后在 Claude Code 中输入/catalog-items确认已加载。

详细介绍

ServiceNow 服务目录开发

服务目录允许用户通过自助服务门户申请服务和项目。

目录组件

组件用途示例
Catalog类别的容器IT 服务目录
Category项目分组硬件、软件
Item可申请的服务申请新笔记本电脑
Variable项目上的表单字段笔记本电脑型号下拉框
Variable Set可重复使用的变量组用户详细信息
Producer直接创建记录报告事件
Order Guide多项目向导新员工入职配置

目录项目结构

Catalog Item: Request New Laptop
├── Variables
│   ├── laptop_model (Reference: cmdb_model)
│   ├── reason (Multi-line text)
│   └── urgency (Choice: Low, Medium, High)
├── Variable Sets
│   └── Delivery Information (Address, Contact)
├── Catalog Client Scripts
│   ├── onLoad: Set defaults
│   └── onChange: Update price
├── Workflows/Flows
│   └── Laptop Approval Flow
└── Fulfillment
    └── Creates Task for IT

变量类型

类型使用场景示例
单行文本简短输入员工 ID
多行文本较长输入业务理由
选择框单选优先级
复选框是/否加急配送
引用链接到表申请对象
日期日期选择器需要日期
查找选择框筛选后的引用按类别选择型号
列表收集器多项选择抄送收件人
容器开始/结束视觉分组硬件选项
宏自定义小组件费用计算器

创建目录变量

基本变量
// Via MCP (snow_create_variable supports reference, checkbox, etc.;
// snow_create_catalog_variable covers text/choice types only)
snow_create_variable({
  cat_item: "<catalog item sys_id>",
  name: "laptop_model",
  question_text: "Laptop Model",
  type: "reference",
  mandatory: true,
  order: 100,
})

// Set the reference table and qualifier on the created variable
snow_record_manage({
  action: "update",
  table: "item_option_new",
  sys_id: "<variable sys_id>",
  data: { reference: "cmdb_model", reference_qual: "category=computer" },
})
带动态默认值的变量
// Variable: requested_for
// Type: Reference (sys_user)
// Default value (script):
javascript: gs.getUserID()
带引用限定条件的变量
// Variable: assignment_group
// Type: Reference (sys_user_group)
// Reference Qualifier:

// Simple:
active=true^type=it

// Dynamic (Script):
javascript: 'active=true^manager=' + gs.getUserID()

// Advanced (using current variables):
javascript: 'u_department=' + current.variables.department

目录客户端脚本

在 onLoad 时设置默认值
function onLoad() {
  // Set default values
  g_form.setValue("urgency", "low")

  // Hide admin-only fields
  if (!g_user.hasRole("catalog_admin")) {
    g_form.setDisplay("cost_center", false)
  }

  // Set default date to tomorrow
  var tomorrow = new GlideDateTime()
  tomorrow.addDays(1)
  g_form.setValue("needed_by", tomorrow.getDate().getValue())
}
在 onChange 时动态定价
function onChange(control, oldValue, newValue, isLoading) {
  if (isLoading) return

  // Get price from selected model
  var ga = new GlideAjax("CatalogUtils")
  ga.addParam("sysparm_name", "getModelPrice")
  ga.addParam("sysparm_model", newValue)
  ga.getXMLAnswer(function (price) {
    g_form.setValue("item_price", price)
    updateTotal()
  })
}

function updateTotal() {
  var price = parseFloat(g_form.getValue("item_price")) || 0
  var quantity = parseInt(g_form.getValue("quantity")) || 1
  g_form.setValue("total_cost", (price * quantity).toFixed(2))
}
在 onSubmit 时进行验证
function onSubmit() {
  // Validate business justification for high-cost items
  var cost = parseFloat(g_form.getValue("total_cost"))
  var justification = g_form.getValue("business_justification")

  if (cost > 1000 && !justification) {
    g_form.showFieldMsg("business_justification", "Required for items over $1000", "error")
    return false
  }

  // Validate date is in future
  var neededBy = g_form.getValue("needed_by")
  var today = new GlideDateTime().getDate().getValue()
  if (neededBy < today) {
    g_form.showFieldMsg("needed_by", "Date must be in the future", "error")
    return false
  }

  return true
}

变量集

创建可重复使用的变量集
Variable Set: User Contact Information
├── contact_name (Single Line Text)
├── contact_email (Email)
├── contact_phone (Single Line Text)
└── preferred_contact (Choice: Email, Phone, Either)

Use in multiple catalog items:
- New Laptop Request
- Software Installation
- Network Access Request
访问变量集值
// In workflow or script
var ritm = current // sc_req_item

// Access variable from variable set
var contactEmail = ritm.variables.contact_email
var preferredContact = ritm.variables.preferred_contact

目录工作流/流程

审批模式
Flow Trigger: sc_req_item created
├── If: Total cost > $5000
│   └── Request Approval: Department Manager
│   └── If: Rejected
│       └── Update: RITM state = Closed Incomplete
├── If: Total cost > $25000
│   └── Request Approval: VP
├── Create: Catalog Task for Fulfillment
└── Wait: Task completion
履行脚本
// In catalog item's "Execution Plan" or workflow

var ritm = current // sc_req_item

// Create an incident from catalog request
var inc = new GlideRecord("incident")
inc.initialize()
inc.setValue("short_description", ritm.short_description)
inc.setValue("description", ritm.description)
inc.setValue("caller_id", ritm.request.requested_for)
inc.setValue("category", ritm.variables.category)
inc.setValue("priority", ritm.variables.urgency)
inc.insert()

// Link incident to request
ritm.setValue("u_fulfillment_record", inc.getUniqueValue())
ritm.update()

记录生成器

通过目录创建事件
// Record Producer: Report an Issue
// Table: incident
// Script:

// Map variables to incident fields
current.short_description = producer.short_description
current.description = producer.description
current.caller_id = gs.getUserID()
current.category = producer.category
current.subcategory = producer.subcategory
current.priority = producer.urgency == "urgent" ? "2" : "3"

// Set assignment based on category
if (producer.category == "network") {
  current.assignment_group.setDisplayValue("Network Support")
} else {
  current.assignment_group.setDisplayValue("Service Desk")
}

订单指南

多步骤申请向导
Order Guide: New Employee Onboarding
├── Step 1: Employee Information
│   └── Variable Set: Employee Details
├── Step 2: Hardware Selection
│   ├── Catalog Item: Laptop
│   ├── Catalog Item: Monitor
│   └── Catalog Item: Peripherals
├── Step 3: Software Requests
│   └── Rule: Show software based on department
├── Step 4: Access Requests
│   └── Cascade Variable: Copy employee info
└── Submit: Creates multiple RITMs
订单指南规则
// Rule: Show software items based on department
function rule(item, guide_variables) {
  var dept = guide_variables.department

  // Show engineering software only for Engineering
  if (item.name == "Engineering Software Suite") {
    return dept == "engineering"
  }

  // Show finance software only for Finance
  if (item.name == "Financial Tools") {
    return dept == "finance"
  }

  return true // Show all other items
}

定价与审批

动态定价
// Catalog Item Script (Pricing)
// Runs when item is added to cart

var basePrice = parseFloat(current.price) || 0
var quantity = parseInt(current.variables.quantity) || 1
var expedited = current.variables.expedited == "true"

var total = basePrice * quantity
if (expedited) {
  total *= 1.5 // 50% rush fee
}

current.recurring_price = 0
current.price = total
审批规则
Approval Definition: High-Value Purchases
Condition: total_cost > 5000
Approver: requested_for.manager
Wait for: Approval
Rejection action: Cancel request

最佳实践

  1. 变量命名 - 使用具有描述性的全小写名称(不含空格)
  2. 变量集 - 重复使用常见的变量组
  3. 引用限定条件 - 仅筛选相关记录
  4. 客户端脚本 - 尽量减少服务器调用(谨慎使用 GlideAjax)
  5. 履行 - 创建任务,不要直接完成
  6. 测试 - 使用不同的用户角色进行测试
  7. 移动设备 - 在手机/平板电脑上测试目录项目
  8. 文档 - 为变量添加帮助文本

评论

支持 Markdown