(function ($, zou) {
"use strict";
$.lrworkflow = {
render: function ($self) {
var dfop = $self[0].dfop;
$self.addClass('z-workflow');
// 添加工具栏
if (!dfop.isPreview) {
var $tool = $('
');
$tool[0].dfop = dfop;
$tool.append('');
$tool.append('');
var toolbtnlen = dfop.toolBtns.length;
if (toolbtnlen > 0) {
$tool.append('');
for (var i = 0; i < toolbtnlen; ++i) {
var btn = dfop.toolBtns[i];
$tool.append('');//加入自定义按钮
}
}
dfop.currentBtn = "cursor";
$tool.on("click", function (e) {
var $this = $(this);
var dfop = $this[0].dfop;
e = e || window.event;
var tar;
switch (e.target.tagName) {
case "SPAN": return false;
case "DIV": return false;
case "B": tar = e.target.parentNode; break;
case "A": tar = e.target;
};
var type = $(tar).attr("type");
$.lrworkflow.switchToolBtn(dfop, type);
return false;
});
$self.append($tool);
}
else {
$self.addClass('z-workflow-preview');
}
// 工作流画板(工作区域)
$self.append('');
var $workArea = $("")
.attr({ "unselectable": "on", "onselectstart": 'return false', "onselect": 'document.selection.empty()' });
$self.children(".z-workflow-work").mCustomScrollbar({ // 优化滚动条
axis: "xy"
});
$self.children(".z-workflow-work").find('.mCSB_container').append($workArea);
$workArea[0].dfop = dfop;
$.lrworkflow.initDraw($workArea, dfop);
$workArea.on("click", $.lrworkflow.clickWorkArea);
$.lrworkflow.initNodeEvent($workArea);
$.lrworkflow.initLineEvent($workArea);
//对结点进行移动或者RESIZE时用来显示的遮罩层
var $ghost = $("").attr({ "unselectable": "on", "onselectstart": 'return false', "onselect": 'document.selection.empty()' });
$self.append($ghost);
var $lineMove = $('');//操作折线时的移动框
$workArea.append($lineMove);
$lineMove.on("mousedown", { $workArea: $workArea }, function (e) {
if (e.button == 2) return false;
var lm = $(this);
lm.css({ "background-color": "#333" });
var $workArea = e.data.$workArea;
var ev = $.lrworkflow.mousePosition(e), t = $.lrworkflow.getElCoordinate($workArea[0]);
var X, Y;
X = ev.x - t.left;
Y = ev.y - t.top;
var p = lm.position();
var vX = X - p.left, vY = Y - p.top;
var isMove = false;
document.onmousemove = function (e) {
if (!e) e = window.event;
var ev = $.lrworkflow.mousePosition(e);
var ps = lm.position();
X = ev.x - t.left;
Y = ev.y - t.top;
if (lm.data("type") == "lr") {
X = X - vX;
if (X < 0) X = 0;
else if (X > 5000)
X = 5000;
lm.css({ left: X + "px" });
}
else if (lm.data("type") == "tb") {
Y = Y - vY;
if (Y < 0) Y = 0;
else if (Y > 5000)
Y = 5000;
lm.css({ top: Y + "px" });
}
isMove = true;
}
document.onmouseup = function (e) {
var lineId = lm.data("tid");
var dfop = $('#' + lineId)[0].dfop;
if (isMove) {
var p = lm.position();
if (lm.data("type") == "lr")
$.lrworkflow.setLineM(lineId, p.left + 3);
else if (lm.data("type") == "tb")
$.lrworkflow.setLineM(lineId, p.top + 3);
}
lm.css({ "background-color": "transparent" });
if (dfop.focusId == lm.data("tid")) {
$.lrworkflow.focusItem(lm.data("tid"));
}
document.onmousemove = null;
document.onmouseup = null;
}
});
// 设置线条工具条选定线时显示的操作框
var $lineOper = $("
");
$workArea.append($lineOper);
$lineOper.on("click", function (e) {
if (!e) e = window.event;
if (e.target.tagName != "A" && e.target.tagName != "B") return;
var id = $(this).data("tid");
var type = $(e.target).attr("class");
if (type == 'x') {
$.lrworkflow.delLine(id);
this.style.display = "none";
}
else {
$.lrworkflow.setLineType(id, type);
}
});
},
switchToolBtn: function (dfop, type) {
var $oldBtn = $('#' + dfop.id + "_btn_" + dfop.currentBtn);
var $newBtn = $('#' + dfop.id + "_btn_" + type);
$oldBtn.removeClass('z-workflow-btndown');
$oldBtn.addClass('z-workflow-btn');
$newBtn.removeClass('z-workflow-btn');
$newBtn.addClass('z-workflow-btndown');
dfop.currentBtn = type;
},
initDraw: function ($workArea, dfop) {
var $draw;
var elem;
$draw = document.createElementNS("http://www.w3.org/2000/svg", "svg");//可创建带有指定命名空间的元素节点
$workArea.prepend($draw);
var defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
$draw.appendChild(defs);
defs.appendChild($.lrworkflow.getSvgMarker("arrow1", "gray"));
defs.appendChild($.lrworkflow.getSvgMarker("arrow2", "#ff3300"));
defs.appendChild($.lrworkflow.getSvgMarker("arrow3", "#225ee1"));
$draw.id = 'draw_' + dfop.id;
$draw.style.width = "5000px";
$draw.style.height = "5000px";
},
getSvgMarker: function (id, color) {
var m = document.createElementNS("http://www.w3.org/2000/svg", "marker");
m.setAttribute("id", id);
m.setAttribute("viewBox", "0 0 6 6");
m.setAttribute("refX", 5);
m.setAttribute("refY", 3);
m.setAttribute("markerUnits", "strokeWidth");
m.setAttribute("markerWidth", 6);
m.setAttribute("markerHeight", 6);
m.setAttribute("orient", "auto");
var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("d", "M 0 0 L 6 3 L 0 6 z");
path.setAttribute("fill", color);
path.setAttribute("stroke-width", 0);
m.appendChild(path);
return m;
},
clickWorkArea: function (e) {
var $this = $(this);
var dfop = $this[0].dfop;
if (!dfop.isPreview) {
e = e || window.event;
var type = dfop.currentBtn;
if (type == "cursor") {
var t = $(e.target);
var n = t.prop("tagName");
if (n == "svg" || (n == "DIV" && t.prop("class").indexOf("z-workflow-workinner") > -1)) {
$.lrworkflow.blurItem(dfop);
}
return;
}
else if (type == "direct") {
return;
}
var X, Y;
var ev = $.lrworkflow.mousePosition(e), t = $.lrworkflow.getElCoordinate(this);
X = ev.x - t.left;
Y = ev.y - t.top;
var name = dfop.nodeRemarks[type];
var executeadd = true;
if (type == 'startround') {
name = "开始";
if (dfop.hasStartround) {
zou.alert.error('只能有一个开始节点');
return false;
}
}
if (type == 'endround') {
name = "结束";
if (dfop.hasEndround) {
zou.alert.error('只能有一个结束节点');
return false;
}
}
$.lrworkflow.addNode($this, dfop, { id: zou.newGuid(), name: name, left: X, top: Y, type: type });
}
},
// 取消所有结点/连线被选定的状态
blurItem: function (dfop) {
if (dfop.focusId != "") {
var $item = $("#" + dfop.focusId);
if ($item.prop("tagName") == "DIV") {
$item.removeClass("z-workflow-nodefocus");
$item.find('.z-workflow-nodeclose').hide();
$item.removeClass("z-workflow-nodemark");
}
else {
var lineData = $.lrworkflow.getLine(dfop, dfop.focusId);
if (!lineData.marked) {
if (lineData.wftype == '2') {
$item[0].childNodes[1].setAttribute("stroke", "#ff3300");
$item[0].childNodes[1].setAttribute("marker-end", "url(#arrow2)");
}
else {
$item[0].childNodes[1].setAttribute("stroke", "gray");
$item[0].childNodes[1].setAttribute("marker-end", "url(#arrow1)");
}
}
var $lineOper = $('.z-workflow-lineoper');
var $lineMove = $('.z-workflow-linemover');
$lineMove.hide().removeData("type").removeData("tid");
$lineOper.hide().removeData("tid");
}
}
dfop.focusId = "";
return true;
},
// 选定某个结点/转换线
focusItem: function (id) {
var $item = $("#" + id);
if ($item.length == 0) {
return;
}
$item.removeClass("z-workflow-nodemark");
var dfop = $item[0].dfop;
if (!this.blurItem(dfop)) {//先执行"取消选中",如果返回FLASE,则也会阻止选定事件继续进行.
return;
}
if ($item.prop("tagName") == "DIV") {
$item.addClass("z-workflow-nodefocus");
$item.find('.z-workflow-nodeclose').show();
}
else {//如果是连接线
$item[0].childNodes[1].setAttribute("stroke", "#225ee1");
$item[0].childNodes[1].setAttribute("marker-end", "url(#arrow3)");
var x, y, from, to;
from = $item.attr("from").split(",");
to = $item.attr("to").split(",");
from[0] = parseInt(from[0], 10);
from[1] = parseInt(from[1], 10);
to[0] = parseInt(to[0], 10);
to[1] = parseInt(to[1], 10);
var lineData = $.lrworkflow.getLine(dfop, id);
if (lineData.type == "lr") {
from[0] = lineData.M;
to[0] = from[0];
var $lineMove = $('.z-workflow-linemover');
$lineMove.css({
width: "5px", height: (to[1] - from[1]) * (to[1] > from[1] ? 1 : -1) + "px",
left: from[0] - 3 + "px",
top: (to[1] > from[1] ? from[1] : to[1]) + 1 + "px",
cursor: "e-resize", display: "block"
}).data({ "type": "lr", "tid": id });
}
else if (lineData.type == "tb") {
from[1] = lineData.M;
to[1] = from[1];
var $lineMove = $('.z-workflow-linemover');
$lineMove.css({
width: (to[0] - from[0]) * (to[0] > from[0] ? 1 : -1) + "px", height: "5px",
left: (to[0] > from[0] ? from[0] : to[0]) + 1 + "px",
top: from[1] - 3 + "px",
cursor: "s-resize", display: "block"
}).data({ "type": "tb", "tid": id });
}
x = (from[0] + to[0]) / 2 - 35;
y = (from[1] + to[1]) / 2 + 6;
var $lineOper = $('.z-workflow-lineoper');
$lineOper.css({ display: "block", left: x + "px", top: y + "px" }).data("tid", id);
}
dfop.focusId = id;
$.lrworkflow.switchToolBtn(dfop, "cursor");
},
//获取一个DIV的绝对坐标的功能函数,即使是非绝对定位,一样能获取到
getElCoordinate: function (dom) {
var t = dom.offsetTop;
var l = dom.offsetLeft;
dom = dom.offsetParent;
while (dom) {
t += dom.offsetTop;
l += dom.offsetLeft;
dom = dom.offsetParent;
}; return {
top: t,
left: l
};
},
// 获取鼠标定位点坐标
mousePosition: function (ev) {
if (!ev) ev = window.event;
if (ev.pageX || ev.pageY) {
return { x: ev.pageX, y: ev.pageY };
}
return {
x: ev.clientX + document.documentElement.scrollLeft - document.body.clientLeft,
y: ev.clientY + document.documentElement.scrollTop - document.body.clientTop
};
},
// 节点操作
//增加一个流程结点,传参为一个JSON,有id,name,top,left,width,height,type(结点类型)等属性
addNode: function ($workArea, dfop, node, isold) {
var mark = node.type;
var $node;
if (!node.width || node.width < 150) node.width = 150;
if (!node.height || node.height < 65) node.height = 65;
if (!node.top || node.top < 0) node.top = 0;
if (!node.left || node.left < 0) node.left = 0;
if (mark == "conditionnode")
{
node.width = 160;
node.height = 90;
$node = $('');
}
else if (mark != "startround" && mark != "endround") {
$node = $('');
}
else {
node.width = 52;
node.height = 52;
if (mark == 'startround') {
node.name = "开始";
dfop.hasStartround = true;
}
else if (mark == 'endround') {
node.name = "结束";
dfop.hasEndround = true;
}
$node = $('');
}
$node.find('.z-workflow-nodeassemble').append('');
$node.find('.z-workflow-nodeassemble').append('');
$node.find('.z-workflow-nodeassemble').append('');
$node.find('.z-workflow-nodeassemble').append('');
$node.find('.z-workflow-nodeassemble').append('');
$node.css({ 'top': node.top + 'px', 'left': node.left + 'px', 'width': node.width + 'px', 'height': node.height + 'px' });
if (node.state != undefined && (node.type == 'startround' || node.type == 'auditornode' || node.type == 'stepnode' || node.type == 'confluencenode')) {
$node.css({ 'padding-left': '0','color':'#fff' }).find('.z-workflow-nodeico').remove();
switch (node.state) {//0正在处理 1 已处理同意 2 已处理不同意 3 未处理 4 当前需要处理的节点
case '0':
$node.css({ 'background': '#5bc0de', 'border': '0' });
break;
case '1':
$node.css({ 'background': '#5cb85c', 'border': '0' });
break;
case '2':
$node.css({ 'background': '#d9534f', 'border': '0' });
break;
case '3':
$node.css({ 'background': '#999', 'border': '0' });
break;
case '4':
$node.css({ 'background': '#f0ad4e', 'border': '0' });
break;
}
}
// 初始化节点的配置信息
if (!isold) {
switch (node.type) {
case 'startround':
node.wfForms = [];
node.authorizeFields = [];
node.iocName = '';
node.dbSuccessId = '';
node.dbSuccessSql = '';
break;
case 'stepnode':
node.dbFailId = '';
node.dbFailSql = '';
case 'auditornode':
node.auditors = [];
node.wfForms = [];
node.authorizeFields = [];
node.iocName = '';
node.dbSuccessId = '';
node.dbSuccessSql = '';
node.timeoutAction = 48;// 超时流转时间
node.timeoutNotice = 24;// 超时通知时间
break;
case 'confluencenode':// 会签
node.confluenceType = '1';
node.confluenceRate = '100';
node.iocName = '';
node.dbSuccessId = '';
node.dbSuccessSql = '';
node.dbFailId = '';
node.dbFailSql = '';
break;
case 'conditionnode':// 条件
node.conditions = [];
node.dbConditionId = "";
node.conditionSql = "";
break;
}
}
$node[0].wfdata = node;
$node[0].dfop = dfop;
$workArea.append($node);
dfop.node.push(node);
},
//删除结点
delNode: function (dfop, nodeData) {
var tmplines = [];
for (var i = 0, l = dfop.line.length; i < l; i++) {
var tmpLine = dfop.line[i];
if (tmpLine.from != nodeData.id && tmpLine.to != nodeData.id) {
tmplines.push(tmpLine);
}
else {
$('#' + tmpLine.id).remove();
}
}
$('#' + nodeData.id).remove();
dfop.line = tmplines;
dfop.node.splice(dfop.node.indexOf(nodeData), 1);
if (nodeData.type == 'startround') {
dfop.hasStartround = false;
}
else if (nodeData.type == 'endround') {
dfop.hasEndround = false;
}
dfop.focusId = "";
},
//移动结点到一个新的位置
moveNode: function (id, left, top) {
if (left < 0) left = 0;
if (top < 0) top = 0;
var $node = $("#" + id);
$node.css({ left: left + "px", top: top + "px" });
var nodedata = $node[0].wfdata;
var dfop = $node[0].dfop;
nodedata.left = left;
nodedata.top = top;
//重画转换线
this.resetLines(id, dfop);
},
// 更新节点名字
updateNodeName: function ($workArea, nodeId) {
var $node = $workArea.find('#' + nodeId);
var nodeData = $node[0].wfdata;
$node.find('.z-workflow-nodetext').html(nodeData.name);
},
initNodeEvent: function ($workArea) {
var dfop = $workArea[0].dfop;
//节点双击事件
$workArea.delegate(".z-workflow-node", "dblclick", { $workArea: $workArea }, function (e) {
var $workArea = e.data.$workArea;
var dfop = $workArea[0].dfop;
var $node = $(this);
var nodeData = $node[0].wfdata;
dfop.openNode(nodeData);
});
if (!dfop.isPreview) {
//绑定点击事件
$workArea.delegate(".z-workflow-node", "click", function (e) {
$.lrworkflow.focusItem(this.id);
return false;
});
//绑定右击事件
$workArea.delegate(".z-workflow-node", "contextmenu", function (e) {
//$.lrworkflow.focusItem(this.id);
//return false;
});
//绑定用鼠标移动事件(节点拖动)
$workArea.delegate(".z-workflow-nodeico", "mousedown", { $workArea: $workArea }, function (e) {
var $node = $(this).parents(".z-workflow-node");
var dfop = $node[0].dfop;
var nodeData = $node[0].wfdata;
e = e || window.event;
if (dfop.$nowType == "direct") {
return;
}
var id = $node.attr("id");
var $workArea = e.data.$workArea;
$.lrworkflow.focusItem(id);
var ev = $.lrworkflow.mousePosition(e), t = $.lrworkflow.getElCoordinate($workArea[0]);
var $ghost = $('#' + dfop.id).find('.z-workflow-rsghost');
if (nodeData.type == "endround" || nodeData.type == "startround" || nodeData.type == "conditionnode") {
$ghost.css({ 'padding-left': '0px' });
}
else {
$ghost.css({ 'padding-left': '48px' });
}
$node.children().clone().prependTo($ghost);
if (nodeData.type == "conditionnode") {
$ghost.find('b').css({ 'width': '100%', 'height': '100%', 'position': 'absolute', 'z-index': '-1' });
}
$ghost.find('.z-workflow-nodeclose').remove();
var X, Y;
X = ev.x - t.left;
Y = ev.y - t.top;
var vX = X - nodeData.left, vY = Y - nodeData.top;
var isMove = false;
var hack = 1;
if (navigator.userAgent.indexOf("8.0") != -1) hack = 0;
document.onmousemove = function (e) {
if (!e) e = window.event;
var ev = $.lrworkflow.mousePosition(e);
if (X == ev.x - vX && Y == ev.y - vY) return false;
X = ev.x - vX; Y = ev.y - vY - 47;
if (isMove && $ghost.css("display") == "none") {
$ghost.css({
display: "table",
width: $('#' + id).css('width'), height: $('#' + id).css('height'),
top: nodeData.top + "px",
left: nodeData.left + t.left + "px", cursor: "move"
});
}
if (X < 60) {
X = 60;
}
else if (X + nodeData.width > t.left + $workArea.width()) {
X = t.left + $workArea.width() - nodeData.width;
}
if (Y < 0) {
Y = 0;
}
else if (Y + nodeData.height > t.top + $workArea.height() - 47) {
Y = $workArea.height() - nodeData.height + t.top - 47;
}
$ghost.css({ left: X + "px", top: Y + "px" });
isMove = true;
}
document.onmouseup = function (e) {
if (isMove) $.lrworkflow.moveNode(id, X - t.left, Y + 47 - t.top);
$ghost.empty().hide();
document.onmousemove = null;
document.onmouseup = null;
}
return false;
});
//绑定鼠标覆盖/移出事件
$workArea.delegate(".z-workflow-node", "mouseenter", { $workArea: $workArea }, function (e) {
var dfop = e.data.$workArea[0].dfop;
if (dfop.currentBtn != "direct") return;
$(this).addClass("z-workflow-nodemark");
});
$workArea.delegate(".z-workflow-node", "mouseleave", { $workArea: $workArea }, function (e) {
var dfop = e.data.$workArea[0].dfop;
if (dfop.currentBtn != "direct") return;
$(this).removeClass("z-workflow-nodemark");
});
$workArea.delegate(".z-workflow-nodespot", "mouseenter", { $workArea: $workArea }, function (e) {
var dfop = e.data.$workArea[0].dfop;
if (dfop.currentBtn != "direct") return;
$(this).addClass("z-workflow-nodespotmark");
});
$workArea.delegate(".z-workflow-nodespot", "mouseleave", { $workArea: $workArea }, function (e) {
var dfop = e.data.$workArea[0].dfop;
if (dfop.currentBtn != "direct") return;
$(this).removeClass("z-workflow-nodespotmark");
});
//绑定连线时确定初始点
$workArea.delegate(".z-workflow-nodespot", "mousedown", { $workArea: $workArea }, function (e) {
var dfop = e.data.$workArea[0].dfop;
if (dfop.currentBtn != "direct") return;
var $this = $(this);
var $node = $this.parents('.z-workflow-node');
var nodeData = $node[0].wfdata;
var X, Y;
X = nodeData.left;
Y = nodeData.top;
var position = 'left';
if ($this.hasClass('left')) {
position = 'left';
Y += nodeData.height / 2;
}
else if ($this.hasClass('top')) {
position = 'top';
X += nodeData.width / 2;
}
else if ($this.hasClass('right')) {
position = 'right';
X += nodeData.width;
Y += nodeData.height / 2;
}
else if ($this.hasClass('bottom')) {
position = 'bottom';
X += nodeData.width / 2;
Y += nodeData.height;
}
e.data.$workArea.data("lineStart", { "x": X, "y": Y, "id": nodeData.id, "position": position }).css("cursor", "crosshair");
var line = $.lrworkflow.drawLine('1',"lr_workflow_tmp_line", [X, Y], [X, Y], true, true);
var $draw = $('#' + dfop.id).find('svg');
$draw.append(line);
});
//划线时用的绑定
$workArea.mousemove(function (e) {
var $workArea = $(this);
var dfop = $workArea[0].dfop;
if (dfop.currentBtn != "direct") return;
var lineStart = $workArea.data("lineStart");
if (!lineStart) return;
var ev = $.lrworkflow.mousePosition(e), t = $.lrworkflow.getElCoordinate(this);
var X, Y;
X = ev.x - t.left;
Y = ev.y - t.top;
var line = document.getElementById("lr_workflow_tmp_line");
line.childNodes[0].setAttribute("d", "M " + lineStart.x + " " + lineStart.y + " L " + X + " " + Y);
line.childNodes[1].setAttribute("d", "M " + lineStart.x + " " + lineStart.y + " L " + X + " " + Y);
if (line.childNodes[1].getAttribute("marker-end") == "url(\"#arrow2\")")
line.childNodes[1].setAttribute("marker-end", "url(#arrow3)");
else line.childNodes[1].setAttribute("marker-end", "url(#arrow3)");
});
$workArea.mouseup(function (e) {
var $workArea = $(this);
var dfop = $workArea[0].dfop;
if (dfop.currentBtn != "direct") return;
$(this).css("cursor", "auto").removeData("lineStart");
$("#lr_workflow_tmp_line").remove();
});
//绑定连线时确定结束点
$workArea.delegate(".z-workflow-nodespot", "mouseup", { $workArea: $workArea }, function (e) {
var $workArea = e.data.$workArea;
var dfop = $workArea[0].dfop;
if (dfop.currentBtn != "direct") return;
var $this = $(this);
var $node = $this.parents('.z-workflow-node');
var nodeData = $node[0].wfdata;
var lineStart = $workArea.data("lineStart");
var position = 'left';
if ($this.hasClass('left')) {
position = 'left';
}
else if ($this.hasClass('top')) {
position = 'top';
}
else if ($this.hasClass('right')) {
position = 'right';
}
else if ($this.hasClass('bottom')) {
position = 'bottom';
}
if (lineStart) $.lrworkflow.addLine(dfop, { id: zou.newGuid(), from: lineStart.id, to: nodeData.id, sp: lineStart.position, ep: position, name: "" });
});
//绑定结点的删除功能
$workArea.delegate(".z-workflow-nodeclose", "click", function () {
var $node = $(this).parents('.z-workflow-node');
var nodeData = $node[0].wfdata;
var dfop = $node[0].dfop;
$.lrworkflow.delNode(dfop, nodeData);
return false;
});
}
},
initLineEvent: function ($workArea) {
var dfop = $workArea[0].dfop;
if (!dfop.isPreview) {
$workArea.delegate('g', "click", function (e) {
$.lrworkflow.focusItem(this.id);
});
$workArea.delegate('g', "dblclick", { $workArea: $workArea }, function (e) {
var $workArea = e.data.$workArea;
var dfop = $workArea[0].dfop;
var lineData = $.lrworkflow.getLine(dfop, this.id);
dfop.openLine(lineData);
});
}
},
// 获取线条数据
getLine: function (dfop, lineId) {
for (var i = 0, l = dfop.line.length; i < l; i++) {
if (lineId == dfop.line[i].id) {
return dfop.line[i];
}
}
},
// 获取线条端点坐标
getLineSpotXY: function (nodeId, dfop, type) {
var nodeData;
for (var i = 0, l = dfop.node.length; i < l; i++) {
if (nodeId == dfop.node[i].id) {
nodeData = dfop.node[i];
break;
}
}
var X, Y;
X = nodeData.left;
Y = nodeData.top;
switch (type)
{
case 'left':
Y += nodeData.height / 2;
break;
case 'top':
X += nodeData.width / 2;
break;
case 'right':
X += nodeData.width;
Y += nodeData.height / 2;
break;
case 'bottom':
X += nodeData.width / 2;
Y += nodeData.height;
break;
}
return [X, Y];
},
// 绘制一条箭头线,并返回线的DOM
drawLine: function (wftype, id, sp, ep, mark, dash, cursor) {
var line;
line = document.createElementNS("http://www.w3.org/2000/svg", "g");
var hi = document.createElementNS("http://www.w3.org/2000/svg", "path");
var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
if (id != "") line.setAttribute("id", id);
line.setAttribute("from", sp[0] + "," + sp[1]);
line.setAttribute("to", ep[0] + "," + ep[1]);
hi.setAttribute("visibility", "hidden");
hi.setAttribute("stroke-width", 9);
hi.setAttribute("fill", "none");
hi.setAttribute("stroke", "white");
hi.setAttribute("d", "M " + sp[0] + " " + sp[1] + " L " + ep[0] + " " + ep[1]);
hi.setAttribute("pointer-events", "stroke");
path.setAttribute("d", "M " + sp[0] + " " + sp[1] + " L " + ep[0] + " " + ep[1]);
path.setAttribute("stroke-width", 2.0);
path.setAttribute("stroke-linecap", "round");
path.setAttribute("fill", "none");
if (dash) path.setAttribute("style", "stroke-dasharray:6,5");
if (mark) {
path.setAttribute("stroke", "#3498DB");//ff3300
path.setAttribute("marker-end", "url(#arrow3)");
}
else if (wftype == '2')
{
path.setAttribute("stroke", "#ff3300");//ff3300
path.setAttribute("marker-end", "url(#arrow2)");
}
else {
path.setAttribute("stroke", "gray");
path.setAttribute("marker-end", "url(#arrow1)");
}
///console.log(wftype);
line.appendChild(hi);
line.appendChild(path);
line.style.cursor = "crosshair";
if (id != "" && id != "lr_workflow_tmp_line") {
var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
//text.textContent=id;
line.appendChild(text);
var x = (ep[0] + sp[0]) / 2;
var y = (ep[1] + sp[1]) / 2;
text.setAttribute("text-anchor", "middle");
text.setAttribute("x", x);
text.setAttribute("y", y - 5);
line.style.cursor = "pointer";
text.style.cursor = "text";
}
return line;
},
//画一条只有两个中点的折线
drawPoly: function (wftype, id, sp, m1, m2, ep, mark) {
var poly, strPath;
poly = document.createElementNS("http://www.w3.org/2000/svg", "g");
var hi = document.createElementNS("http://www.w3.org/2000/svg", "path");
var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
if (id != "") poly.setAttribute("id", id);
poly.setAttribute("from", sp[0] + "," + sp[1]);
poly.setAttribute("to", ep[0] + "," + ep[1]);
hi.setAttribute("visibility", "hidden");
hi.setAttribute("stroke-width", 9);
hi.setAttribute("fill", "none");
hi.setAttribute("stroke", "white");
strPath = "M " + sp[0] + " " + sp[1];
if (m1[0] != sp[0] || m1[1] != sp[1])
strPath += " L " + m1[0] + " " + m1[1];
if (m2[0] != ep[0] || m2[1] != ep[1])
strPath += " L " + m2[0] + " " + m2[1];
strPath += " L " + ep[0] + " " + ep[1];
hi.setAttribute("d", strPath);
hi.setAttribute("pointer-events", "stroke");
path.setAttribute("d", strPath);
path.setAttribute("stroke-width", 2.0);
path.setAttribute("stroke-linecap", "round");
path.setAttribute("fill", "none");
if (mark) {
path.setAttribute("stroke", "#3498DB");//ff3300
path.setAttribute("marker-end", "url(#arrow3)");
}
else if (wftype == '2') {
path.setAttribute("stroke", "#ff3300");//ff3300
path.setAttribute("marker-end", "url(#arrow2)");
}
else {
path.setAttribute("stroke", "gray");
path.setAttribute("marker-end", "url(#arrow1)");
}
poly.appendChild(hi);
poly.appendChild(path);
var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
//text.textContent=id;
poly.appendChild(text);
var x = (m2[0] + m1[0]) / 2;
var y = (m2[1] + m1[1]) / 2;
text.setAttribute("text-anchor", "middle");
text.setAttribute("x", x);
text.setAttribute("y", y - 5);
text.style.cursor = "text";
poly.style.cursor = "pointer";
return poly;
},
// 计算两个结点间要连折线的话,连线的所有坐标
calcPolyPoints: function (SP, EP, type, M) {
var m1 = [], m2 = [], m;
if (type == "lr") {
var m = M || (SP[0] + EP[0]) / 2;
//粗略计算2个中点
m1 = [m, SP[1]];
m2 = [m, EP[1]];
}
//如果是允许中段可上下移动的折线,则参数M为可移动中段线的Y坐标
else if (type == "tb") {
var m = M || (SP[1] + EP[1]) / 2;
//粗略计算2个中点
m1 = [SP[0], m];
m2 = [EP[0], m];
}
return { start: SP, m1: m1, m2: m2, end: EP };
},
// 增加一条线
addLine: function (dfop, line) {
var $line;
if (line.from == line.to) return;
// 避免两个节点间不能有一条以上同向接连线
for (var i = 0, l = dfop.line.length; i < l; i++) {
if ((line.from == dfop.line[i].from && line.to == dfop.line[i].to)) {
return;
}
}
// 获取开始和结束节点的坐标
var sxy = $.lrworkflow.getLineSpotXY(line.from, dfop, line.sp);
var exy = $.lrworkflow.getLineSpotXY(line.to, dfop, line.ep);
line.name = line.name || '';
line.wftype = line.wftype || '1';
dfop.line.push(line);
if (line.type && line.type != "sl") {
var res = $.lrworkflow.calcPolyPoints(sxy, exy, line.type, line.M);
$line = $.lrworkflow.drawPoly(line.wftype, line.id, res.start, res.m1, res.m2, res.end, line.mark);
}
else {
line.type = "sl";//默认为直线
$line = $.lrworkflow.drawLine(line.wftype, line.id, sxy, exy, line.mark);
}
var $draw = $('#' + dfop.id).find('svg');
$($line)[0].dfop = dfop;
if (line.name != "") {
$($line).find('text').html(line.name);
}
$draw.append($line);
},
// 重构所有连向某个结点的线的显示,传参结构为$nodeData数组的一个单元结构
resetLines: function (nodeId, dfop) {
var $line;
for (var i = 0, l = dfop.line.length; i < l; i++) {
var sxy = [];
var exy = [];
var line = dfop.line[i];
if (line.from == nodeId || line.to == nodeId) {
sxy = $.lrworkflow.getLineSpotXY(line.from, dfop, line.sp);
exy = $.lrworkflow.getLineSpotXY(line.to, dfop, line.ep);
$('#' + line.id).remove();
if (line.type == "sl") {
$line = $.lrworkflow.drawLine(line.wftype, line.id, sxy, exy, line.mark);
}
else {
var res = $.lrworkflow.calcPolyPoints(sxy, exy, line.type, line.M);
$line = $.lrworkflow.drawPoly(line.wftype, line.id, res.start, res.m1, res.m2, res.end, line.mark);
}
var $draw = $('#' + dfop.id).find('svg');
$($line)[0].dfop = dfop;
$draw.append($line);
var lineId = $($line).attr('id');
var lineData = $.lrworkflow.getLine(dfop, lineId);
$($line).find('text').html(lineData.name);
}
}
},
//重新设置连线的样式 newType= "sl":直线, "lr":中段可左右移动型折线, "tb":中段可上下移动型折线
setLineType: function (id, newType) {
var $line = $('#' + id);
var dfop = $line[0].dfop;
var lineData = $.lrworkflow.getLine(dfop, id);
if (!newType || newType == null || newType == "" || newType == lineData.type) return false;
var from = lineData.from;
var to = lineData.to;
lineData.type = newType;
var sxy = $.lrworkflow.getLineSpotXY(from, dfop, lineData.sp);
var exy = $.lrworkflow.getLineSpotXY(to, dfop, lineData.ep);
var res;
// 如果是变成折线
if (newType != "sl") {
var res = $.lrworkflow.calcPolyPoints(sxy, exy, lineData.type, lineData.M);
$.lrworkflow.setLineM(id, $.lrworkflow.getMValue(sxy, exy, newType), true);
}
// 如果是变回直线
else {
delete lineData.M;
var $lineMove = $('.z-workflow-linemover');
$lineMove.hide().removeData("type").removeData("tid");
$line.remove();
$line = $.lrworkflow.drawLine(lineData.wftype, lineData.id, sxy, exy, lineData.mark);
var $draw = $('#' + dfop.id).find('svg');
$($line)[0].dfop = dfop;
$draw.append($line);
var lineData = $.lrworkflow.getLine(dfop, id);
$($line).find('text').html(lineData.name);
}
if (dfop.focusId == id) {
$.lrworkflow.focusItem(id);
}
},
//设置折线中段的X坐标值(可左右移动时)或Y坐标值(可上下移动时)
setLineM: function (id, M, noStack) {
var dfop = $('#' + id)[0].dfop;
var lineData = $.lrworkflow.getLine(dfop, id);
if (!lineData || M < 0 || !lineData.type || lineData.type == "sl") return false;
var from = lineData.from;
var to = lineData.to;
lineData.M = M;
var sxy = $.lrworkflow.getLineSpotXY(from, dfop, lineData.sp);
var exy = $.lrworkflow.getLineSpotXY(to, dfop, lineData.ep);
var ps = $.lrworkflow.calcPolyPoints(sxy, exy, lineData.type, lineData.M);
$('#' + id).remove();
console.log(lineData);
var $line = $.lrworkflow.drawPoly(lineData.wftype, id, ps.start, ps.m1, ps.m2, ps.end, lineData.marked || dfop.focusId == id);
var $draw = $('#' + dfop.id).find('svg');
$($line)[0].dfop = dfop;
$draw.append($line);
$($line).find('text').html(lineData.name);
},
//初始化折线中段的X/Y坐标,mType='rb'时为X坐标,mType='tb'时为Y坐标
getMValue: function (sxy, exy, mType) {
if (mType == "lr") {
return (sxy[0] + exy[0]) / 2;
}
else if (mType == "tb") {
return (sxy[1] + exy[1]) / 2;
}
},
// 删除线条
delLine: function (lineId) {
var $line = $('#' + lineId)
var dfop = $line[0].dfop;
for (var i = 0, l = dfop.line.length; i < l; i++) {
if (lineId == dfop.line[i].id) {
dfop.line.splice(i, 1);
break;
}
}
dfop.focusId = "";
$line.remove();
},
updateLineName: function ($workArea, lineId) {
var $line = $('#' + lineId);
var dfop = $workArea[0].dfop;
var lineData = $.lrworkflow.getLine(dfop, lineId);
$line.find('text').html(lineData.name);
if (lineData.wftype == '2') {
$line[0].childNodes[1].setAttribute("stroke", "#ff3300");
$line[0].childNodes[1].setAttribute("marker-end", "url(#arrow2)");
}
else {
$line[0].childNodes[1].setAttribute("stroke", "gray");
$line[0].childNodes[1].setAttribute("marker-end", "url(#arrow1)");
}
}
};
$.fn.lrworkflow = function (op) {
var dfop = {
openNode: function () { },
openLine: function () { },
toolBtns: ["startround", "endround", "stepnode", "confluencenode", "conditionnode", "auditornode"],//"childwfnode"
nodeRemarks: {
cursor: "选择指针",
direct: "步骤连线",
startround: "开始节点",
endround: "结束节点",
stepnode: "普通节点",
confluencenode: "会签节点",
conditionnode: "条件判断节点",
auditornode: "传阅节点"
//childwfnode: "子流程节点"
},
node: [],
line: [],
hasStartround: false,
hasEndround: false,
focusId: ''
};
$.extend(dfop, op);
var $self = $(this);
dfop.id = $self.attr("id");
$self[0].dfop = dfop;
$.lrworkflow.render($self);
};
$.fn.lrworkflowGet = function () {
var $self = $(this);
var $workArea = $self.find(".z-workflow-workinner");
var dfop = $workArea[0].dfop;
var data = {
nodes: dfop.node,
lines: dfop.line
};
return data;
}
$.fn.lrworkflowSet = function (name, op) {
var $self = $(this);
var $workArea = $self.find(".z-workflow-workinner");
switch (name) {
case 'updateNodeName':
$.lrworkflow.updateNodeName($workArea, op.nodeId);
break;
case 'updateLineName':
$.lrworkflow.updateLineName($workArea, op.lineId);
break;
case 'set':
var dfop = $workArea[0].dfop;
for (var i = 0, l = op.data.nodes.length; i < l; i++) {
var node = op.data.nodes[i];
$.lrworkflow.addNode($workArea, dfop, node, true);
}
for (var i = 0, l = op.data.lines.length; i < l; i++) {
var line = op.data.lines[i];
$.lrworkflow.addLine(dfop, line);
}
break;
}
}
})(jQuery, top.zou);