先上个效果图。
以上效果为自己拖拽画布效果,可在每一个任务节点上去配置对应的name,function.
具体代码。
1.js,css引用
2。HTML JS
<script type="text/javascript">
$(function () {
var module = GetQueryString("ModuleID");
var Eid = $("#PosID").val();
$('#myflow')
.myflow(
{
basePath: "",
restore: eval(""),
tools: {
save: {
onclick: function (data) {
$.ajax({
type: "post",
url: "../Controllers/HumanResource/PubliceShow.ashx?ActionType=AddFlow",
data: {
"data": data,
"moduleid": module,
"Eid": Eid
},
success: function (data) {
// FunctionJson = eval("(" + data + ")"); ;
if (data == 'error') {
layer.alert('流程图保存失败,需要满足开始,结束,任务三个节点同时存在。', {
icon: 2
});
}
if (data == 'waring') {
layer.alert('流程图保存失败。', {
icon: 2
});
}
if (data == 'OK') {
layer.alert('流程图保存成功。', {
icon: 0
});
window.location.href = "ChartFlow.aspx";
}
}
});
}
}
}
});
});
</script>
<style type="text/css">
body
{
margin: 0;
pading: 0;
text-align: left;
font-family: Arial, sans-serif, Helvetica, Tahoma;
font-size: 12px;
line-height: 1.5;
color: black;
background-image: url(../MasterPager/js/myflow-min/img/bg.png);
}
.node
{
70px;
text-align: center;
vertical-align: middle;
border: 1px solid #fff;
}
.mover
{
border: 1px solid #ddd;
}
.selected
{
background-color: #ddd;
}
.state
{
}
#myflow_props table
{
}
#myflow_props th
{
letter-spacing: 2px;
text-align: left;
padding: 6px;
background: #ddd;
}
#myflow_props td
{
background: #fff;
padding: 6px;
}
#pointer
{
background-repeat: no-repeat;
background-position: center;
}
#path
{
background-repeat: no-repeat;
background-position: center;
}
#task
{
background-repeat: no-repeat;
background-position: center;
}
#state
{
background-repeat: no-repeat;
background-position: center;
}
</style>
<section class="content-header">
<h1>
流程图定制
</h1>
</section>
<div id="myflow_tools" style="position: absolute; top: 100px; left: 10px;
70px; cursor: default; padding: 3px;" class="ui-widget-content">
<div id="myflow_tools_handle" style="text-align: center;" class="ui-widget-header">
工具集</div>
<div class="node" id="myflow_save">
<img src="../MasterPager/js/myflow-min/img/save.gif" /> 保存</div>
<div>
<hr />
</div>
<div class="node selectable" id="pointer">
<img src="../MasterPager/js/myflow-min/img/select16.gif" /> 选择</div>
<div class="node selectable" id="path">
<img src="../MasterPager/js/myflow-min/img/16/flow_sequence.png" /> 转换</div>
<div>
<hr />
</div>
<div class="node state" id="start" type="start">
<img src="../MasterPager/js/myflow-min/img/16/start_event_empty.png" /> 开始</div>
<%--<div class="node state" id="state" type="state"><img
src="../MasterPager/js/myflow-min/img/16/task_empty.png" /> 状态</div>--%>
<div class="node state" id="task" type="task">
<img src="../MasterPager/js/myflow-min/img/16/task_empty.png" /> 任务</div>
<%--<div class="node state" id="fork" type="fork"><img
src="../MasterPager/js/myflow-min/img/16/gateway_parallel.png" /> 分支</div>
<div class="node state" id="join" type="join"><img
src="../MasterPager/js/myflow-min/img/16/gateway_parallel.png" /> 合并</div>--%>
<div class="node state" id="end" type="end">
<img src="../MasterPager/js/myflow-min/img/16/end_event_terminate.png" /> 结束</div>
<%--<div class="node state" id="end-cancel" type="end-cancel"><img
src="../MasterPager/js/myflow-min/img/16/end_event_cancel.png" /> 取消</div>
<div class="node state" id="end-error" type="end-error"><img
src="../MasterPager/js/myflow-min/img/16/end_event_error.png" /> 错误</div>--%>
</div>
<div id="myflow_props" style="position: absolute; top: 30; right: 50;
220px; padding: 3px;" class="ui-widget-content">
<div id="myflow_props_handle" class="ui-widget-header">
属性</div>
<table border="1" width="100%" cellpadding="0" cellspacing="0">
<tr>
<td>
aaa
</td>
</tr>
<tr>
<td>
aaa
</td>
</tr>
</table>
<div>
</div>
</div>
<input type="hidden" id="PosID" runat="server" clientidmode="Static" />
<div id="myflow">
</div>
3.如何将流程图拆散后保存入库。
private void AddFlow(HttpContext context)
{
string data = context.Request.Form["data"];
string moduleid = context.Request.Form["moduleid"];
string Eid = context.Request.Form["Eid"];
DataTable dts=new DataTable();
dts = SDA.GetModuleFunction(moduleid);
string functionNmae = "";
if (dts.Rows.Count>0)
{
functionNmae = dts.Rows[0][0].ToString();
}
//DataTable dt = new DataTable();
string strtempa = "type:'start'";//判断流程图是否选择了开始
string strtempb = "type:'end'";//判断流程图是否选择了结束
string strtempc = "type:'task";//判断流程图是否选择的了任务
int IndexofA = data.IndexOf(strtempa);
int IndexofB = data.IndexOf(strtempb);
int IndexofC = data.IndexOf(strtempc);
int error = 0;
if (IndexofA == -1)
{
error++;
}
if (IndexofB == -1)
{
error++;
}
if (IndexofC == -1)
{
error++;
}
if (error>0)
{
context.Response.Write("error");
}
else
{
List<string> ls = new List<string>();
ls=pb.DoDebug(data);
string strtempD = "temp3:";
string Flowname = "Flowname";
string FlowN = "";
ls.RemoveAt(ls.Count - 1);
ls.RemoveAt(ls.Count - 2);
for (int i = ls.Count - 1; i >= 0; i--)
{
if (ls[i].IndexOf(Flowname) == 0)
{
FlowN = ls[i];
}
if (ls[i].IndexOf(strtempD) !=0)
{
ls.RemoveAt(i);
}
}
FlowN = FlowN.Replace("Flowname:{value:", "").Replace("},desc:{value:", ",").Replace("}", "");
string[] strarr = FlowN.Replace("'","").Split(',');
List<string> lss = new List<string>();
foreach (var i in strarr)
{
if (i.ToString() != "")
{
lss.Add(i);
}
}
flow_Flow ff = new flow_Flow();
if (lss.Count==1)
{
ff.FlowName = lss[0];
}
else if (lss.Count > 1)
{
ff.FlowName = lss[0];
ff.FlowDesc = lss[1];
}
ff.ModuleID = moduleid;
ff.CreateEmployeeID = Eid;
ff.CreateDate = DateTime.Now;
flow_FlowText fft = new flow_FlowText();
fft.FlowText = data.Replace("'","''");
flow_FlowInfo fi = new flow_FlowInfo();
List<flow_FlowInfo> lfi=new List<flow_FlowInfo>();
for (int i = 0; i < ls.Count; i++)
{
string fitemp = ls[i].Replace("temp3:{value:", "").Replace("},temp2:{value:", ",").Replace("}", "");
string[] temparr = fitemp.Replace("'", "").Split(',');
if (temparr.Length>0)
{
fi = new flow_FlowInfo();
fi.Text = temparr[0];
fi.FunctionID = temparr[1];
if (fi.FunctionID=="")
{
fi.FunctionID = functionNmae;
}
fi.ISJH = 0;
lfi.Add(fi);
}
}
if (da.InsertFlow(ff, lfi, fft))
{
context.Response.Write("OK");
}
else
{
context.Response.Write("waring");
}
}
}
public List<string> DoDebug(string data)
{
List<string> oGet = new List<string>();
string sPut = data;
Stack<StringBuilder> stack = new Stack<StringBuilder>();
stack.Push(new StringBuilder(""));
foreach (var cPut in sPut)
{
switch (cPut)
{
case '{':
stack.Peek().Append(cPut);
stack.Push(new StringBuilder(""));
break;
case '}':
StringBuilder oPop = stack.Pop();
oGet.Add(oPop.ToString());
stack.Peek().Append(oPop.ToString());
stack.Peek().Append(cPut);
break;
default:
stack.Peek().Append(cPut);
break;
}
}
while (stack.Count > 0)
{
StringBuilder oPop = stack.Pop();
oGet.Add(oPop.ToString());
}
return oGet;
}
要点:当我们将要保存的value取去来时,会发现这是一个稍微比较复杂的json串,或者说是一个不是贴别规范的json串比较合适。
我将任务开始节点的名称取关键字段temp3,temp2,保证生成数据时,能够有唯一条件供我筛选。
下面是将保存在数据库的数据,在显示的截图。
在查看页面就是一个很简单的数据输出,并且不显示其他的图列,属性等信息。
有需要的同学,可以私聊我,给你们源码demo。有好多功能正在研究中,希望大家能够衍生出更好,更实际的功能。