gooflow0.6的流程设计
为何使用gooflow:1、兼容性好
2、扩展点很多可以个性化设计
3、配有api文档
4、json格式的数据传输
由于最近项目需要,急需设计一个流程,考虑到时间问题,和用户个性化的需求,没办法跟现在项目的后台集成,所以考虑到选择一款jquery插件,并通过存储过程来集成现在的业务模块。
直接上图了:
双击节点可以选择人员

双击连接线可以选择条件

使用gooflow版本为0.4的 网上可以搜到 另外当前版本有些bug需要自己改。需要提供帮助的可以加我QQ:512948935
gooflow版本为0.6




后台使用的是mvc+spring+NHibernate,主要是保存比较麻烦。
前台js
<script type="text/javascript">
var property = {
toolBtns: ["start", "end", "task"],
haveHead: true,
headBtns: ["save", "undo", "redo", "reload"], //如果haveHead=true,则定义HEAD区的按钮
haveTool: true,
haveGroup: true,
useOperStack: true
};
var remark = {
cursor: "选择指针",
direct: "转换连线",
start: "开始结点",
end: "结束结点",
task: "任务结点",
group: "组织划分框编辑开关"
};
var gooFlow, focusId, flow_title, flowID;
$(function () {
gooFlow = $.createGooFlow($("#flow"), property);
flow_title = getUrlParam1("title");
flowID = getUrlParam("flowID");
if (flow_title != "") {
//自适应调整
gooFlow.reinitSize($(this).width() - 5, $(parent).height() - 25);
gooFlow.setTitle(flow_title + "·流程绘制");
parent.$('#div_layout').layout('panel', 'center').panel({
onResize: function (width, height) {
gooFlow.reinitSize(width - 5, height - 30);
}
});
}
else
gooFlow.reinitSize($(this).width() - 5, $(this).height() - 5);
if (flowID == "") flowID = 0;
gooFlow.setNodeRemarks(remark);
//新建流程
gooFlow.onBtnNewClick = function () {
gooFlow.clearData();
}
//保存流程
gooFlow.onBtnSaveClick = function () {
var h = gooFlow.$bgDiv.height();
$("<div class=\"datagrid-mask\"></div>").css({ display: "block", width: "100%", height: h }).appendTo(gooFlow.$bgDiv);
$("<div class=\"datagrid-mask-msg\"></div>").html("数据正在保存中,请稍候……").appendTo(gooFlow.$bgDiv).css({
display: "block",
left: (gooFlow.$bgDiv.width() - 200) / 2,
top: (h - 45) / 2
});
var obj = gooFlow.exportAlter();
//节点
var nodeData = "";
for (var i in obj.nodes) {
var id = gooFlow.$nodeData[i].ID == null ? 0 : gooFlow.$nodeData[i].ID;
var userID = gooFlow.$nodeData[i].userID == null ? 0 : gooFlow.$nodeData[i].userID;
nodeData += '{"ID": ' + id + ''
+ ',"FlowID": ' + flowID + ''
+ ',"NodeID": "' + i + '"'
+ ',"UserID": "' + userID + '"'
+ ',"UserName": "' + gooFlow.$nodeData[i].name + '"'
+ ',"NodeType": "' + gooFlow.$nodeData[i].type + '"'
+ ',"NodeLeft": ' + gooFlow.$nodeData[i].left + ''
+ ',"NodeTop": ' + gooFlow.$nodeData[i].top + ''
+ ',"NodeWidth": ' + gooFlow.$nodeData[i].width + ''
+ ',"NodeHeight": ' + gooFlow.$nodeData[i].height + ''
+ ',"Marked": false},';
}
if (nodeData != "") {
nodeData = "[" + $.trimend(nodeData, ',') + "]";
}
//连接线
var lineData = "";
for (var i in obj.lines) {
var id = gooFlow.$lineData[i].ID == null ? 0 : gooFlow.$lineData[i].ID;
var conditionID = gooFlow.$lineData[i].conditionID == null ? 0 : gooFlow.$lineData[i].conditionID;
var lineM = gooFlow.$lineData[i].M == null ? 0 : gooFlow.$lineData[i].M;
lineData += '{"ID": ' + id + ''
+ ',"FlowID": ' + flowID + ''
+ ',"LineID": "' + i + '"'
+ ',"ConditionID": ' + conditionID + ''
+ ',"ConditionName": "' + gooFlow.$lineData[i].name + '"'
+ ',"LineType": "' + gooFlow.$lineData[i].type + '"'
+ ',"LineFrom": "' + gooFlow.$lineData[i].from + '"'
+ ',"LineTo": "' + gooFlow.$lineData[i].to + '"'
+ ',"LineM": ' + lineM + ''
+ ',"Marked": false},';
}
if (lineData != "") {
lineData = "[" + $.trimend(lineData, ',') + "]";
}
//区域
var areaData = "";
for (var i in obj.areas) {
var id = gooFlow.$areaData[i].ID == null ? 0 : gooFlow.$areaData[i].ID;
areaData += '{"ID": ' + id + ''
+ ',"FlowID": ' + flowID + ''
+ ',"AreaID": "' + i + '"'
+ ',"AreaName": "' + gooFlow.$areaData[i].name + '"'
+ ',"AreaLeft": ' + gooFlow.$areaData[i].left + ''
+ ',"AreaTop": ' + gooFlow.$areaData[i].top + ''
+ ',"AreaWidth": ' + gooFlow.$areaData[i].width + ''
+ ',"AreaHeight": ' + gooFlow.$areaData[i].height + ''
+ ',"AreaColor": "' + gooFlow.$areaData[i].color + '"'
+ ',"Marked": false},';
}
if (areaData != "") {
areaData = "[" + $.trimend(areaData, ',') + "]";
}
if (nodeData == "" && lineData == "" && areaData == "") {
$('.datagrid-mask-msg').remove();
$('.datagrid-mask').remove();
return;
}
$.ajax({
type: "post",
url: "/HR/BacthSave",
data: { node: nodeData, line: lineData, area: areaData },
success: function (data) {
if (data.status == 1) {
jqAlert('保存成功.', 'info', "reload");
}
else
jqAlert('保存失败:' + data, 'error')
$('.datagrid-mask-msg').remove();
$('.datagrid-mask').remove();
}
});
}
//刷新
gooFlow.onFreshClick = function () {
location.reload();
}
//单元节点双击事件
gooFlow.$workArea.delegate(".ico + td", "dblclick", { inthis: gooFlow }, function (e) {
var newId = $(this).parents(".GooFlow_item").attr("id");
var $frame = $("#frame_choose_aud");
if ($frame.attr("src") == undefined) {
focusId = newId;
$frame.attr("src", "/HR/BaseFlowChooseEmp");
}
else {
if (focusId != newId) {
focusId = newId;
window.frames["choose_aud"].initData();
}
}
$("#div_win_choose_aud").window('open');
});
//单元连接线双击事件
var tmpClk = "PolyLine";
if (GooFlow.prototype.useSVG != "")
tmpClk = "g";
$(gooFlow.$draw).delegate(tmpClk, "dblclick", { inthis: gooFlow }, function (e) {
if (GooFlow.prototype.useSVG != "") {
var $frame = $("#frame_choose_con");
if ($frame.attr("src") == undefined) {
focusId = this.id;
$frame.attr("src", "/HR/BaseFlowCondition?typeID=" + getUrlParam("typeID"));
}
else {
if (focusId != this.id) {
focusId = this.id;
window.frames["choose_con"].unselect();
}
}
$("#div_win_choose_con").window('open');
}
});
//操作单元删除事件
gooFlow.onItemDel = function (id, type) {
var delItem = gooFlow.getItemInfo(id, type);
if (delItem.ID != null) {
uiConfirm("确定要删除该单元吗.", function () {
$.post("/HR/DeleteFlowItem", { "id": id, "type": type }, function (data) {
if (data.status == 1) {
delItem.ID = null;
if (type == "node")
gooFlow.delNode(id);
else if (type == "line")
gooFlow.delLine(id);
else if (type == "area")
gooFlow.delArea(id);
return true;
}
else
jqAlert('删除失败:' + data, 'error')
});
});
}
else
return true
}
//初始化人员选择窗体
showMyWindow($("#div_win_choose_aud"), '选择人员信息', 'icon-edit', '', 900, 450, true);
//初始化人员选择窗体
showMyWindow($("#div_win_choose_con"), '选择条件信息', 'icon-edit', '', 900, 450, true);
//加载数据
var h = gooFlow.$bgDiv.height();
$("<div class=\"datagrid-mask\"></div>").css({ display: "block", width: "100%", height: h }).appendTo(gooFlow.$bgDiv);
$("<div class=\"datagrid-mask-msg\"></div>").html("图形正在加载中,请稍候……").appendTo(gooFlow.$bgDiv).css({
display: "block",
left: (gooFlow.$bgDiv.width() - 200) / 2,
top: (h - 45) / 2
});
var para = { "type": "get", "url": "/HR/LoadWorkArea?flowID=" + flowID, "success": onLoadSuccess, "error": onLoadError };
gooFlow.loadDataAjax(para);
});
function onLoadSuccess(msg) {
$('.datagrid-mask-msg').remove();
$('.datagrid-mask').remove();
}
function onLoadError(status, errorThrown) {
$('.datagrid-mask-msg').remove();
$('.datagrid-mask').remove();
}
function backAudChoose(row) {
gooFlow.setName(focusId, row.user_truename + "(" + row.user_no + ")", "node");
var focusNode = gooFlow.getItemInfo(focusId, "node");
focusNode.name = row.user_truename + "(" + row.user_no + ")";
focusNode.userID = row.ID;
$("#div_win_choose_aud").window('close');
}
function backConChoose(row) {
gooFlow.setName(focusId, row.ConditionName, "line")
var focusLine = gooFlow.getItemInfo(focusId, "line");
focusLine.name = row.ConditionName;
focusLine.conditionID = row.ID;
$("#div_win_choose_con").window('close');
}
</script>
后台处理
#region BaseFlowPicture
public ActionResult BaseFlowPicture()
{
return View();
}
public ActionResult BacthSave(string node = "", string line = "", string area = "")
{
try
{
if (node != "")
{
List<Q_HR_WorkFlow_Node> nodes = JSONStringToList<Q_HR_WorkFlow_Node>(node);
int s = nodes.Where(c => c.NodeType == "start").Count();
int e = nodes.Where(c => c.NodeType == "end").Count();
if (s != 1)
throw new Exception("请设置一个开始节点.");
if (e != 1)
throw new Exception("请设置一个结束节点.");
Q_HR_WorkFlow_NodeManage.BatchSave(nodes);
}
if (line != "")
{
List<Q_HR_WorkFlow_Line> lines = JSONStringToList<Q_HR_WorkFlow_Line>(line);
Q_HR_WorkFlow_LineManage.BatchSave(lines);
}
if (area != "")
{
List<Q_HR_WorkFlow_Area> areas = JSONStringToList<Q_HR_WorkFlow_Area>(area);
Q_HR_WorkFlow_AreaManage.BatchSave(areas);
}
return Json(new { status = 1 }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
public string LoadWorkArea(int flowID = 0)
{
DataTable nodes = Q_HR_WorkFlow_NodeManage.GetList(flowID);
DataTable lines = Q_HR_WorkFlow_LineManage.GetList(flowID);
IList<Q_HR_WorkFlow_Area> areas = Q_HR_WorkFlow_AreaManage.GetList(flowID);
string jsonStr = "{";
string alt;
//jsonStr += "\"initNum\":" + Q_HR_WorkFlow_NodeManage.GetInitNum() + ",";
if (nodes.Rows.Count > 0)
{
jsonStr += "\"nodes\":{";
foreach (DataRow row in nodes.Rows)
{
alt = "false";
if (row["NodeType"].ToString() == "start" || row["NodeType"].ToString() == "end")
alt = "true";
jsonStr += "\"" + row["NodeID"] + "\":{"
+ "\"ID\":" + row["ID"] + ""
+ ",\"name\":\"" + row["UserName"] + "(" + row["user_no"] + ")\""
+ ",\"userID\":" + row["UserID"] + ""
+ ",\"type\":\"" + row["NodeType"] + "\""
+ ",\"left\":" + row["NodeLeft"] + ""
+ ",\"top\":" + row["NodeTop"] + ""
+ ",\"width\":" + row["NodeWidth"] + ""
+ ",\"height\":" + row["NodeHeight"] + ""
+ ",\"alt\":" + alt + ""
+ ",\"mark\":" + row["Marked"].ToString().ToLower() + ""
+ "},";
}
jsonStr = jsonStr.TrimEnd(',') + "},";
}
if (lines.Rows.Count > 0)
{
jsonStr += "\"lines\":{";
foreach (DataRow row in lines.Rows)
{
jsonStr += "\"" + row["LineID"] + "\":{"
+ "\"ID\":" + row["ID"] + ""
+ ",\"name\":\"" + row["ConditionName"] + "\""
+ ",\"conditionID\":" + row["ConditionID"] + ""
+ ",\"type\":\"" + row["LineType"] + "\""
+ ",\"from\":\"" + row["LineFrom"] + "\""
+ ",\"to\":\"" + row["LineTo"] + "\""
+ ",\"M\":" + row["LineM"] + ""
+ ",\"mark\":" + row["Marked"].ToString().ToLower() + ""
+ "},";
}
jsonStr = jsonStr.TrimEnd(',') + "},";
}
if (areas.Count > 0)
{
jsonStr += "\"areas\":{";
foreach (Q_HR_WorkFlow_Area area in areas)
{
jsonStr += "\"" + area.AreaID + "\":{"
+ "\"ID\":" + area.ID + ""
+ ",\"name\":\"" + area.AreaName + "\""
+ ",\"left\":" + area.AreaLeft + ""
+ ",\"top\":" + area.AreaTop + ""
+ ",\"width\":" + area.AreaWidth + ""
+ ",\"height\":" + area.AreaHeight + ""
+ ",\"color\":\"" + area.AreaColor + "\""
+ "},";
}
jsonStr = jsonStr.TrimEnd(',') + "},";
}
jsonStr = jsonStr.TrimEnd(',') + "}";
return jsonStr;
}
public ActionResult DeleteFlowItem(string id, string type)
{
try
{
if (type.Equals("node"))
Q_HR_WorkFlow_NodeManage.DeleteFlowNode(id, type);
else if (type.Equals("line"))
Q_HR_WorkFlow_LineManage.DeleteFlowLine(id, type);
else if (type.Equals("area"))
Q_HR_WorkFlow_AreaManage.DeleteFlowArea(id, type);
return Json(new { status = 1 }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
#endregion
|
属性名称 |
作用 |
|
$id |
装载整个UI的DOM对象的ID。 |
|
$bgDiv |
最父框架的DIV。 |
|
$tool |
左侧工具栏JQ对象。 |
|
$head |
顶部栏标题标签及工具栏按钮。 |
|
$title |
载入的流程图的名称。 |
|
$nodeRemark |
左侧工具栏中每一种结点或按钮的说明文字,JSON格式,key为按钮类型名,value为用户自定义文字说明。 |
|
$nowType |
当前要绘制的对象类型,开始时为“cursor”,即不绘制任何元素,只是作为鼠标指针进行元素选定。 |
|
$lineData={} |
转换线数据Map集,以id为key,value为详细数据JSON对象。 |
|
$lineCount=0 |
转换线数据的数量。 |
|
$nodeData={} |
节点数据Map集,以id为key,value为详细数据JSON对象。 |
|
$nodeCount=0 |
节点数据的数量。 |
|
$areaData={} |
分组区数据Map集,以id为key,value为详细数据JSON对象。 |
|
$areaCount=0 |
分组区数据的数量。 |
|
$lineDom={} |
转换线DOM展示对象Map集,以id为key,value为详细在DOM对象。 |
|
$nodeDom={} |
节点JQ展示对象Map集,以id为key,value为详细在JO对象。 |
|
$areaDom={} |
分组区JQ展示对象Map集,以id为key,value为详细在JO对象。 |
|
$max |
计算默认ID值的起始SEQUENCE,默认不填时为1。 |
|
$focus |
当前被选定的结点/转换线ID,如果没选中或者工作区被清空,则为""。 |
|
$cursor |
鼠标指针在工作区内的样式,初始时为default。 |
|
$editable |
当前工作区是否可编辑,即是编辑模式还是仅浏览模式。 |
|
$workArea |
装载结点/线条/分组区域的工作区。 |
|
$draw |
画矢量线条的容器,处于工作区中。 |
|
$group |
仅用来装配分组区域DOM元素的容器,处于工作区中。 |
|
$ghost |
专门用在移动、重置大小等操作时,给用户操作的半透明浮动区。 |
|
$textArea |
双击操作对象后出现的浮动文本域,用来写重命名方法setName所需的新名称传参。 |
|
$lineMove |
操作移动折线的中段时用到的浮动DIV |
|
$lineOper |
选定一条转换线后出现的浮动操作栏,有改变线的样式和删除线等按钮。 |
|
//以下是当初始化的参数property.useOperStack=true且$editable=true时,才存在的属性: |
|
|
$undoStack=[] |
“撤销操作”栈。 |
|
$redoStack=[] |
重做操作栈。 |
|
$isUndo |
事务操作标志位,内部调用 |
|
$deletedItem={} |
在流程图的编辑操作中被删除掉的元素ID集合,元素ID为KEY,元素类型(node,line.area)为VALUE |
[GooFlow对象供使用者调用的方法集]
|
方法名称 |
作用 |
|
setNodeRemarks(remark) |
设定左侧工具栏中每一种结点或按钮的说明文字,传参是JSON格式,key为按钮类型名,value为用户自定义文字说明。 |
|
switchToolBtn(type) |
切换左边工具栏按钮,传参type表示切换成哪种类型的按钮 |
|
addNode(id,json) |
增加一个结点,传参json内容结构与$nodeData的每个属性单元一样。 |
|
getItemInfo(id,type) |
根据id这个KEY,和要获取的数据类型type(有”node”,”line”,”area”三种取值),返回相应的结点json数据单元 |
|
blurItem() |
取消所有结点/连线被选定的状态 |
|
focusItem(id,bool) |
选定某个结点/转换线;传参bool:TRUE决定了要触发选中事件,FALSE则不触发选中事件,多用在程序内部调用。 |
|
moveNode(id,left,top) |
移动一个结点到一个新的位置 |
|
setName(id,name,type) |
设置结点/连线/分组区域的文字信息;传参id为序列,name为新的名称,type为更名对象的数据类型(有”node”,”line”,”area”三种取值) |
|
resizeNode(id,width,height) |
重新设置结点的尺寸,开始/结束类型的结点不支持该方法 |
|
delNode(id) |
删除结点 |
|
setTitle(text) |
设置流程图的名称 |
|
loadData(data) |
载入一组数据JSON格式的流程图数据,传参data中有title,nodes,lines,areas四个KEY的数据,还有一个可选属性数据initNum:ID起始序列号最大数字+1——由于绘制的新单元的ID都是按一定序列号及规则自动生成的,为了防止新载入的数据的ID与编辑时新加入的ID值有重复,将给设计器对象对于新生成单元的ID序列一个新的起始序列号;如果传参JSON中没有这个属性,也可以在调用loadData方法前修改设计器对象的$max属性值(其实loadData方法执行时会检查传参中如果有initNum时,将自动给设计器对象的$max赋上此值); nodes,lines,areas都为一组{key:value}式的Map数据,内容结构分别与GooFlow对象属性中的$nodeData,$lineData,$areaData一致. |
|
loadDataAjax(para) |
用AJAX方式,远程读取一组数据; 参数para为JSON结构,与JQUERY中$.ajax()方法的传参一样 需要后台异步返回JSON格式的msg结果,其内容格式与loadData方法的传参一样。 |
|
exportData() |
把画好的结束导出到一个本函数返回的变量中(其实也可以直接访问GooFlow对象的$nodeData,$lineData,$areaData这三个JSON属性) |
|
exportAlter() |
//只把本次编辑流程图中作了变更(包括增删改)的元素导出到一个变量中,以方便用户每次编辑载入的流程图后只获取变更过的数据 |
|
transNewId(oldId,newId,type) |
变更元素的ID,一般用于快速保存后,将后台返回新元素的ID更新到页面中;type为元素类型(节点,连线,区块) |
|
clearData() |
清空工作区及已载入的数据 |
|
destrory() |
销毁自己 |
|
addLine(id,json) |
增加一条线,传参json内容结构与$lineData的每个属性单元一样。 |
|
setLineType(id,newType) |
重新设置连线的样式. 传参newType的取值有:"sl"直线, "lr"中段可左右移动型折线, "tb"中段可上下移动型折线 |
|
setLineM(id,M) |
设置折线中段的X坐标值(可左右移动时)或Y坐标值(可上下移动时);直线不支持此方法 |
|
delLine(id) |
删除转换线 |
|
markItem(id,type,mark) |
//用颜色标注/取消标注一个结点或转换线,常用于显示重点或流程的进度。 //这是一个在编辑模式中无用,但是在纯浏览模式中非常有用的方法,实际运用中可用于跟踪流程的进度。 //传参:id是操作单元对象唯一序列号;type是操作单元类型(“node”或者”line”,分组区域不支持此方法);mark为布尔值,表示是否标注/取消标注某个ID值的数据单元对象 |
|
addArea(id,json) |
增加一个分组区域,传参json内容结构与$areaData的每个属性单元一样。 |
|
moveArea(id,left,top) |
移动分组区域到新的位置上. |
|
delArea(id) |
删除分组区域 |
|
setAreaColor(id,color) |
设置分组区域的颜色,传参color为颜色样式,只有”red”,”yellow”,”blue”,”green”四种取值 |
|
resizeArea(id,width,height) |
重新设置区分组区域的尺寸 |
|
reinitSize(width,height) |
重构整个流程图设计器的宽高,在浏览器窗口大小改变或者父容器宽高改变时,执行这个方法能让设计器重新适应新的宽高显示。 |
|
//以下是当初始化的参数property.useOperStack=true时,才存在的方法: |
|
|
pushOper(funcName,paras) |
仅供内部方法调用的方法:把对工作区内的数据单元编辑操作(增/删/改/重命名/移动/标注等)加入整条管理栈中,好进入撤销/重做的控制; 注意:将为了节省浏览器内存空间,undo/redo中的操作缓存栈,最多只可放40步操作;超过40步时,将自动删掉最旧的一个缓存。 |
|
pushExternalOper (func,jsonPara) |
//将外部的方法加入到GooFlow对象的事务操作堆栈中,在过后的undo/redo操作中可以进行控制,一般用于对流程图以外的附加信息进行编辑的事务撤销/重做控制; //传参func为要执行方法对象,jsonPara为外部方法仅有的一个面向字面的JSON传参或者数据,由JSON对象或数组带入所有要传的信息; //提示:为了让外部方法能够被UNDO/REDO,需要在编写这些外部方法实现时,加入对该方法执行后效果回退的另一个执行方法的pushExternalOper。 |
|
undo() |
撤销最近一次操作 |
|
redo() |
重做最近一次被撤销的操作 |
gooflow0.6的流程设计的更多相关文章
- Atitit 修改密码的功能流程设计 attilax总结
Atitit 修改密码的功能流程设计 attilax总结 1.1. 注意点1 1.2. 设计修改用户密码功能时把用户ID保存在哪里?1 1.3. Ui设计1 1.4. 功能设计源码1 1.5. Agt ...
- 审核流(2)流程设计-SNF.WorkFlow功能使用说明--SNF快速开发平台3.1
流程设计 图形化的流程设计,更方便.直观 1.打开“流程设计“程序,如上.点击”新建“如下: 2.红色部分为必填项,审批对象是选择要审批的程序菜单,单据名称是在审核流流转时用于提示的单据名称,还要选择 ...
- asp.net 微信企业号办公系统-表单及流程设计配置实例
在环境搭建好之后,我们就来学习一下怎样快速创建一个流程,并执行和流转该流程(我们这里讲的只是入门,不涉及到具体流程参数设置). 创建一个流程步骤为:在数据库在创建表-->设计表单-->设置 ...
- asp.net 微信企业号办公系统-流程设计--保存与发布
如果流程未设计完时可以先保存,以后再打开接着设计.点击工具栏上的保存按钮即可保存当前流程设计: 如果下次要接着设计,则可以打开该流程继续设计: 如果流程设计完成,可以点击安装按钮来发布流程,流程安装成 ...
- asp.net 微信企业号办公系统-流程设计--流程步骤设置-策略设置
策略设置包括当前步骤的流转方式,处理人员,退回策略等设置. 流转类型:当前步骤后面有多个步骤时,此类型选择可以决定后续步骤的发送方式. 1.系统控制:由系统根据您在线上设置的流转条件来判断该发送到哪一 ...
- 三、activiti工作流-流程设计工具
首先在diagrams下面新建一个文件夹 然后在这个文件夹下new一个Activiti Diagram new好后出现bpmn文件, 可以通过右键以xml方式打开bpmn文件查看源码 双击打开文件然后 ...
- 移动端与PHP服务端接口通信流程设计(增强版)
前面讲过:移动端与PHP服务端接口通信流程设计(基础版) 对于 api_token 的校验,其安全性还可再增强: 增强地方一: 再增加2张表,一个接口表,一个授权表,设计参考如下: 接口表 字段名 字 ...
- 移动端与PHP服务端接口通信流程设计(基础版)
针对 --->非开放性平台 --->公司内部产品 接口特点汇总: 1.因为是非开放性的,所以所有的接口都是封闭的,只对公司内部的产品有效: 2.因为是非开放性的,所以OAuth那套协议是行 ...
- cclfow_小流程设计
官网演示地址:http://demo.ccflow.org/ 流程的主要需求: 新建流程 登陆系统后台进行设置流程:鼠标右键流程树 选择新建子级类别 输入子级类别名称:流程演示,点击确定即可 点击流程 ...
随机推荐
- [ZETCODE]wxWidgets教程二:辅助类
本教程原文链接:http://zetcode.com/gui/wxwidgets/helperclasses/ 翻译:瓶哥 日期:2013年11月27日星期三 邮箱:414236069@qq.com ...
- 开发者MAC电脑里的十八般兵器
古人常以刀.枪.剑.戟.斧.钺.铲.叉.鞭.锏.锤.戈.镋.棍.槊.棒.矛.钯十八种兵器,样样精通,来形容一个人的武学技能get状态.在开发者的世界里,熟练掌握各种辅助工具,可以达到事半功倍,快速提高 ...
- 【转】[精华] 跟我一起写 Makefile
陈皓 概述 —— 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,m ...
- [置顶] 分析Java死锁:分析jstack日志
本文中我将展示一段垃圾代码,这段代码会产生死锁,这样围绕这段代码重点展示三种不同的方法来分析线程日志,从而得知什么地方有问题. 下面的讨论将用到两个类 Account 和 DeadlockDemo c ...
- KindEditor编辑器(初始化参数)
width 编辑器的宽度,可以设置px或%,比textarea输入框样式表宽度优先度高. 数据类型: String 默认值: textarea输入框的宽度 示例: K.create('#id', { ...
- ASP.NET- Web.Config配置大文件上传
在web.config中的<system.web></system.web>内加入如下代码: <httpRuntime executionTimeout="60 ...
- Android-Unable to resolve target 'android-8'
- strcmp函数和strcpy函数
(一)strcmp函数 strcmp函数是比較两个字符串的大小,返回比較的结果.一般形式是: i=strcmp(字符串,字符串); 当中,字符串1.字符串2均可为字符串常量或变量:i 是用于存放比 ...
- 微软Office与金山WPS Office有何私密关系?
新浪科技讯,9月1日午间消息,国家工商总局在其官网公布消息称.对微软公司副总裁陈实进行反垄断调查询问,要求微软就其综合情况以及企业反映的微软公司Windows操作系统和Office办公软件相关信息没有 ...
- java连接oracle的简单实例
连接oracle的时候,要导入oracle驱动的jar包. 连接的时候,有statement和preparedstatement两种,从代码中可以看出不同. example: package com. ...