1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| class UserFriendlyRules extends RuleProvider { constructor(eventBus, canvas, translate) { super(eventBus); this.canvas = canvas; this.translate = translate; }
init() { this.addRule('connection.create', (context) => { const result = this.validateConnection(context); if (!result.allowed) { this.showTooltip(context.source, result.message); this.canvas.addMarker(context.source, 'highlight-error'); setTimeout(() => { this.canvas.removeMarker(context.source, 'highlight-error'); }, 2000); }
return result.allowed; }); }
validateConnection(context) { const source = context.source; const target = context.target;
if (source.type === 'bpmn:EndEvent') { return { allowed: false, message: this.translate('结束事件不能有出边') }; }
if (target.type === 'bpmn:StartEvent') { return { allowed: false, message: this.translate('启动事件不能有入边') }; }
return { allowed: true }; }
showTooltip(element, message) { const tooltip = document.createElement('div'); tooltip.className = 'validation-tooltip'; tooltip.textContent = message; const bounds = element.bounds || element; tooltip.style.left = `${bounds.x + bounds.width / 2}px`; tooltip.style.top = `${bounds.y - 30}px`; document.body.appendChild(tooltip); setTimeout(() => { tooltip.remove(); }, 3000); } }
UserFriendlyRules.$inject = ['eventBus', 'canvas', 'translate']; inherits(UserFriendlyRules, RuleProvider);
const tooltipStyle = ` .validation-tooltip { position: absolute; background: #ff4d4f; color: white; padding: 8px 12px; border-radius: 4px; font-size: 12px; pointer-events: none; z-index: 1000; animation: fadeOut 3s; }
@keyframes fadeOut { 0%, 80% { opacity: 1; } 100% { opacity: 0; } }
.highlight-error .djs-visual > * { stroke: #ff4d4f !important; animation: pulse 0.5s ease-in-out 2; }
@keyframes pulse { 0%, 100% { stroke-width: 2px; } 50% { stroke-width: 4px; } } `;
|