Files
workspace/code/fms-workflow-refactor-backup-20260923/workflow/designer/nodes.js
T
2026-09-23 16:54:54 +08:00

135 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 流程设计器 —— LogicFlow 自定义节点注册。
*
* 7 种画布节点与 wf_node.b_node_type 一一映射(§19.5):
* fms-start / fms-user-task / fms-cc-task / fms-exclusive-gateway
* fms-parallel-gateway / fms-service-task / fms-end
*
* 形状与尺寸在模型层用 setAttributes() 定(矩形 width/height、圆 r、菱形 rx/ry),
* 配色覆写 getNodeStyle()。本项目没装 @logicflow/vue-node-registry,
* 因此节点一律用 LogicFlow 原生 SVG 形状渲染,不内嵌 Vue 组件。
*/
import {
CircleNode,
CircleNodeModel,
DiamondNode,
DiamondNodeModel,
RectNode,
RectNodeModel,
} from '@logicflow/core'
import { CANVAS_TO_NODE_TYPE, NODE_META } from './constants'
const TEXT_STYLE = {
color: '#1f2329',
fontSize: 12,
overflowMode: 'autoWrap',
wrapPadding: '6,8',
}
/** 画布类型 → 节点元数据 */
function metaOf(canvasType) {
return NODE_META[CANVAS_TO_NODE_TYPE[canvasType]]
}
/**
* 连线规则(§19.6 编辑器侧的即时校验):
* 开始节点只能作为起点,结束节点只能作为终点,避免连出语义不成立的流程。
* 返回值是 LogicFlow 的 ConnectRule:{ message, validate }。
*/
function connectionRules(canvasType) {
if (canvasType === 'fms-start') {
return { target: { message: '开始节点不能作为连线目标', validate: () => false } }
}
if (canvasType === 'fms-end') {
return { source: { message: '结束节点不能有出线', validate: () => false } }
}
return {}
}
/** 圆形节点(开始 / 结束) */
function circleConfig(canvasType) {
const meta = metaOf(canvasType)
const rules = connectionRules(canvasType)
class Model extends CircleNodeModel {
setAttributes() {
this.r = meta.size.r
}
getNodeStyle() {
return { ...super.getNodeStyle(), ...meta.style, strokeWidth: 2 }
}
getTextStyle() {
return { ...super.getTextStyle(), ...TEXT_STYLE }
}
getConnectedSourceRules() {
const base = super.getConnectedSourceRules()
return rules.source ? [...base, rules.source] : base
}
getConnectedTargetRules() {
const base = super.getConnectedTargetRules()
return rules.target ? [...base, rules.target] : base
}
}
class View extends CircleNode {}
return { type: canvasType, view: View, model: Model }
}
/** 矩形节点(人工审批 / 抄送 / 服务节点) */
function rectConfig(canvasType) {
const meta = metaOf(canvasType)
class Model extends RectNodeModel {
setAttributes() {
this.width = meta.size.width
this.height = meta.size.height
this.radius = 6
}
getNodeStyle() {
return { ...super.getNodeStyle(), ...meta.style, strokeWidth: 2 }
}
getTextStyle() {
return { ...super.getTextStyle(), ...TEXT_STYLE }
}
}
class View extends RectNode {}
return { type: canvasType, view: View, model: Model }
}
/** 菱形节点(条件分支 / 并行分支) */
function diamondConfig(canvasType) {
const meta = metaOf(canvasType)
class Model extends DiamondNodeModel {
setAttributes() {
this.rx = meta.size.rx
this.ry = meta.size.ry
}
getNodeStyle() {
return { ...super.getNodeStyle(), ...meta.style, strokeWidth: 2 }
}
getTextStyle() {
return { ...super.getTextStyle(), ...TEXT_STYLE }
}
}
class View extends DiamondNode {}
return { type: canvasType, view: View, model: Model }
}
/** 把 7 种工作流节点注册到 LogicFlow 实例 */
export function registerWorkflowNodes(lf) {
lf.batchRegister([
circleConfig('fms-start'),
circleConfig('fms-end'),
rectConfig('fms-user-task'),
rectConfig('fms-cc-task'),
rectConfig('fms-service-task'),
diamondConfig('fms-exclusive-gateway'),
diamondConfig('fms-parallel-gateway'),
])
}