Receber por email
← Voltar para o catálogo

jeecg-bpmn

Use when user asks to create/generate/edit/modify a BPM workflow, design a Flowable BPMN process, or says "创建流程", "生成流程", "新建流程", "设计流程", "画流程", "审批流程", "工作流", "BPM", "BPMN", "create flow", "create process", "new workflow", "generate workflow". Also triggers when user describes an approval chain like "先经理审批再HR审批" or mentions process nodes like "开始→审批→网关→结束". Also triggers for OA application creati

172estrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: Apache-2.0

Como adicionar

/plugin marketplace add jeecgboot/skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/jeecg-bpmn/svg)](https://www.skillteca.com.br/skills/jeecg-bpmn)
#ai

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

JeecgBoot BPM 流程自动生成器

将自然语言的流程描述转换为 Flowable BPMN 2.0 XML,并通过 API 在 JeecgBoot 系统中自动创建流程。

临时配置文件规则(强制)

所有传给脚本的 --config <xxx.json> 必须写到 {系统临时目录}/{SKILL_NAME}/ 下,由操作系统自动清理;skill 与脚本均不主动删除该目录或文件。

import tempfile, os, json

SKILL_NAME = "<SKILL_NAME>"               # 请替换为实际的技能名称
skill_dir = os.path.join(tempfile.gettempdir(), SKILL_NAME)
os.makedirs(skill_dir, exist_ok=True)          # 确保目录存在,不主动检查

config_path = os.path.join(skill_dir, 'sk_audit_create.json')   # 示例文件名
with open(config_path, 'w', encoding='utf-8') as f:
    json.dump(cfg, f, ensure_ascii=False, indent=2)

tempfile.gettempdir() 自动适配:Windows %TEMP%、Linux /tmp、macOS /var/folders/.../T(注意 macOS 并非 /tmp)。 文件名建议使用 <表名>_<步骤>.json(如 sk_audit_create.json),无需重复技能前缀,因路径已包含技能名称,便于排错。

禁止:

  • 写到 <skill>/tmp/ 或当前工作目录(污染 skill / 用户项目)
  • 硬编码 /tmp、C:\Temp 或任何固定路径(不跨平台)
  • 每步完成后主动 rm / Remove-Item(操作系统会清理,属多余 tool call)
  • 主动 os.path.exists() 检查(其本身即为一次 tool call)

(使用 os.makedirs(…, exist_ok=True) 满足需求,不算主动检查)

临时文件可能被操作系统异步清理,但仍遵循 乐观调用 + 报错补救:仅当脚本返回 FileNotFoundError 或 配置文件不存在 时,使用相同内容、在相同的 {系统临时目录}/{SKILL名称}/ 路径下重写(重写前仍需 os.makedirs(skill_dir, exist_ok=True) 确保目录存在),切勿更换路径或回退至 skill 目录。

介绍组件时的完整性要求

重要: 当用户要求介绍流程设计器各组件时,必须包含以下内容,不可遗漏:
1. 会签节点:串行/并行两种模式;全部通过/一人通过/半数通过/按比例/自定义 5种通过规则;指定人员/角色/审批角色/部门/岗位/职级/表单字段/流程变量 8种审批人类型
2. 条件表达式:系统内置流程变量(result、applyUserId、applyDate 等);13种条件运算符;多条件组合用法(AND/OR)
3. 监听器:执行监听器/任务监听器/全局事件监听器三种类型;系统预置监听器(ProcessEndListener必需、TaskSkipApprovalListener、TaskCreatedAutoSubmitListener等);taskExtendJson 节点行为控制字段说明

性能规范与已验证规律

⚠️ 禁止预防性读取参考文档。 执行任务前不要为了"以防万用"而读取 references/ 下的文档。只在遇到具体问题时按需读取,且使用 offset/limit 指定行范围。
⚠️ 对外部 API 响应结构,先用小脚本探测,再写主逻辑。 但下方速查表中已验证的数据不需要重新探测。
⚠️ 用不熟悉的 Python 模块前,必须先 dir() 查 exports。 但下方速查表中已验证的模块不需要重新 dir()。
⚠️ 禁止对 API 响应的 result 直接做 [:] 切片。 JeecgBoot API 的 result 格式不统一:分页接口返回 dict {"records": [...], "total": N},全量接口返回 list [...],写操作返回 string。对 dict 做切片 → KeyError: slice(None, 5, None)。强制规则:取值前必须根据「API 响应速查」表确定 result 类型,分页接口统一用 .get('result', {}).get('records', []),全量接口用 isinstance(result, list) 判后再切片。

模块导入(固定模式,直接复用)

import os, pathlib, sys
_SKILLS_DIR = pathlib.Path.home() / '.claude' / 'skills'
sys.path.insert(0, str(_SKILLS_DIR / 'jeecg-desform' / 'scripts'))  # desform_creator, desform_utils
sys.path.insert(0, str(_SKILLS_DIR / 'jeecg-bpmn'    / 'scripts'))  # bpmn_creator, bpmn_oa
sys.path.insert(0, str(_SKILLS_DIR / 'jeecg-system'  / 'scripts'))  # system_utils
os.chdir(str(_SKILLS_DIR / 'jeecg-bpmn' / 'scripts'))
import desform_utils as du; du.init_api(API_BASE, TOKEN)  # ⚠ 必须初始化,否则 ValueError: unknown url type
import desform_creator as dc  # 无需初始化
import bpmn_creator as bc     # 无需初始化,各函数直接传 api_base/token
# system_utils 需要: from system_utils import init_api, ...; init_api(API_BASE, TOKEN)

函数返回值速查

| 函数 | 返回类型 | 正确取值 | |------|---------|---------| | dc.create_form(...) | tuple (form_id, title_field_model) | result[0] | | dc.get_form_id(code) | tuple (form_id, index) | result[0] | | bc.get_desform_fields(api_base, token, code) | dict {label: {model, key, type}} | fields.get('薪资', {}).get('model') | | bc.authorize_form(...) | dict(不是 tuple) | r = bc.authorize_form(...) | | du.get_form_fields(code) | list [{name, model, type}] | 返回表单字段列表。注意:不存在 du.get_form_detail() |

API 响应速查

| API / 操作 | 返回值 | 正确取值 | |-----------|--------|---------| | saveProcess | dict | result['obj'] 含新ID(编辑时可能 null,按 processKey 查)。路径:/act/designer/api/saveProcess,Content-Type:application/x-www-form-urlencoded | | extActProcess/queryById | dict | result 含流程全字段;result['processXml'] 为 base64 编码的 XML,需 base64.b64decode().decode('utf-8') | | sys/sysDepart/add | result=null | 新建后用 queryDepartAndPostTreeSync 全量查找 | | approvalRole/rootList | result.records[](不是裸数组) | r['result']['records'],每条 {id, name, type, pid} | | approvalRole/childList?pid=xxx | result.records[](不是裸数组) | r['result']['records'] | | approvalRole/group/add | result="添加成功!"(字符串,不是 ID) | 创建后调 rootList 按 name 查 ID | | approvalRole/role/add | result="添加成功!"(字符串,不是 ID) | 创建后调 childList 按 name 查 ID | | sys/position/list | result.records[] | 每条 {id, name, code},用于 deptPosition 审批人 | | query_approval_roles() | {'roles': [...], 'persons': [...]} | 用 find_approval_role(keyword) | | query_dept_positions() | depart 树节点(departName 不是 name) | 过滤 orgCategory=='3' |

关键函数签名

| 函数 | 签名 | |------|------| | du.create_form | (name, code, widgets, title_index=0, layout='auto', ...) | | bc.edit_node_config | (api_base, token, process_id, node_code, node_settings) | | bc.set_node_field_permissions | (api_base, token, process_id, node_code, form_code, field_permissions, form_type='2') |

其他关键规律

  • dc.DIVIDER/USER/MONEY 等常量是函数不是字符串,创建 widget 用 dc.build_widget({'type':'money', 'name':'金额', 'required': True})
  • build_widget 对所有控件类型都强制要求 name 字段(含 divider:{'type': 'divider', 'name': '---', 'text': '标题'})
  • build_widget 合法 type 清单:基础 input textarea number integer money date time switch slider rate color / 选择 radio select checkbox / 系统 select-user select-depart select-depart-post phone email area-linkage org-role / 文件 file-upload imgupload hand-sign / 高级 auto-number formula barcode location table-dict select-tree link-record link-field capital-money text-compose ocr map summary editor markdown / OA oa-approval-comments / 布局 tabs grid card divider text buttons
  • DesForm 字段在 design["list"] 下(不是 design["fields"]),嵌套结构需递归提取:

``python def find_fields(node, results): if isinstance(node, dict): if node.get('type') not in ('grid','text','') and node.get('model'): results.append(node) for v in node.values(): find_fields(v, results) elif isinstance(node, list): for item in node: find_fields(item, results) fields = []; find_fields(design, fields) ``

  • userTask 含会签时 XML 子元素顺序:extensionElements → incoming/outgoing → multiInstanceLoopCharacteristics(顺序错报 cvc-complex-type.2.4.a)
  • 条件表达式必须调 bc.build_condition_b64(),手写格式:外层数组 [{"logic":"and","conditions":[...]}],flowUtil.evaluateExpression 需三参数 (execution, 'b64', 'and')
  • 手工分支 + 网关组合 → 自动使用水平多行布局(_detect_horizontal_multirow),W_GAP=60, MAIN_CY=330, LOWER_CY=540
  • 包含网关(inclusiveGateway)带 default flow 时:default flow 从 split 直达 join(无中间节点),_detect_parallel_blocks 已支持空链检测,calc_layout 只对非空分支做水平展开(已修复,此前空链导致检测失败、分支垂直堆叠重叠)
  • 子流程必须先于表单创建,否则表单关联冲突(修复:DELETE 子流程 formId 再重新 link_form)
  • bpmn_oa.py 支持 subprocess 键一键创建子流程,自动填充 calledElement
  • 手写子流程必须加 "isSubProcess": True(bpmn_oa.py 的 _setup_oa_subprocess 已自动设置)
  • system_utils 函数:查岗位 query_dept_positions(dept_id=None) / 查角色 find_approval_role(keyword) 返回 dict 或 None / 岗位列表 GET /sys/position/list / 不存在 /sys/position/rank/list /sys/duty/list
  • 不存在的 API(禁止尝试):queryDepartTreeSync?pid=xxx queryIdTree queryTreeList queryMyDept loadNodeGroupData?groupType=deptPosition queryByKeywords sysDepart/list recycleBin/*
  • 审批角色查找或创建模式(防重复 + 获取真实 ID):

``python def find_or_create_approval_role(name, grp_id): def query_id(): r = api_get(f'/sys/approvalRole/childList?pid={grp_id}') return next((c['id'] for c in r.get('result',{}).get('records',[]) if c['name']==name), None) rid = query_id() if not rid: api_post('/sys/approvalRole/role/add', {'name': name, 'pid': grp_id}) rid = query_id() return rid ``

  • bc.edit_node_config 不更新 nodeConfigJson(已踩坑):该函数只做 node.update(settings) 后 PUT,不同步 nodeConfigJson 字段。前端读 nodeConfigJson.formEditStatus 时仍为 false,导致可编辑节点实际不可编辑。凡需设置 formEditStatus=1 的节点,必须手动同步更新 nodeConfigJson,正确写法:

```python def fix_node_form_edit(api_

Compartilhar X LinkedIn