Created
August 2, 2012 08:29
-
-
Save henryyan/3235428 to your computer and use it in GitHub Desktop.
jquery.workflow.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* jquery.workflow.js | |
* 说明:工作流相关的功能 | |
* @author HenryYan | |
*/ | |
; | |
(function($) { | |
$.workflow = $.workflow || {}; | |
$.workflow.trace = $.workflow.trace || {}; | |
$.extend($.workflow.trace, { | |
/* | |
* 跟踪流转记录 | |
*/ | |
traceList: function(pid, containerId, listId, pagerId) { | |
// 如果已经打开列表了,只刷新数据 | |
if ($('#gbox_' + listId).length == 1) { | |
$("#" + listId).jqGrid('setGridParam', { | |
url: ctx + '/activiti/activiti-task!historicActivityInstances.action', | |
postData: { | |
processInstanceId: pid | |
} | |
}).trigger('reloadGrid'); | |
return; | |
} | |
// 对话框高度 | |
var size = { | |
height: $('#' + containerId + ' .ui-accordion-content').height() - 55, | |
width: $('#' + containerId + ' .ui-accordion-content').width() - 2 | |
}; | |
$("#" + listId).jqGrid($.extend({}, $.common.plugin.jqGrid.settings({ | |
size: size, | |
pager: '#' + pagerId | |
}), { | |
url: ctx + '/activiti/activiti-task!historicActivityInstances.action', | |
postData: { | |
processInstanceId: pid | |
}, | |
colNames: ['节点', '操作人', '任务创建时间', '任务结束时间', '任务耗时'/*, '信息点', '描述'*/], | |
colModel: [{ | |
name: 'activityName', | |
align: 'center', | |
formatter: function(cellValue, options, rowObject) { | |
if (rowObject.activityType == 'startEvent') { | |
return "<font color='green'><b>启动流程</b></font>"; | |
} else { | |
return cellValue; | |
} | |
} | |
}, { | |
name: 'assigneeUser', | |
align: 'center', | |
formatter: function(cellValue, options, rowObject) { | |
if (!cellValue) { | |
return ""; | |
} | |
var userName = !cellValue.name ? "" : cellValue.name; | |
var loginName = !cellValue.loginName ? "" : cellValue.loginName; | |
var orgName = !cellValue.org ? "" : cellValue.org.name; | |
var text = userName + "/" + loginName + "/" + orgName; | |
return text == "/" ? "" : text; | |
} | |
}, { | |
name: 'startTime', | |
align: 'center', | |
formatter: function(cellValue, options, rowObject) { | |
return new Date(cellValue).format("yyyy-MM-dd hh:mm:ss"); | |
} | |
}, { | |
name: 'endTime', | |
align: 'center', | |
formatter: function(cellValue, options, rowObject) { | |
if (!cellValue) { | |
return ''; | |
} | |
return new Date(cellValue).format("yyyy-MM-dd hh:mm:ss"); | |
} | |
}, { | |
name: 'durationInMillis', | |
align: 'center', | |
formatter: function(cellValue, options, rowObject) { | |
return $.common.custom.timeRange(parseInt(cellValue)); | |
} | |
} /*, { | |
name: 'variables', | |
formatter: function(cellValue, options, rowObject) { | |
if (cellValue != null && cellValue != undefined) { | |
var contents = ''; | |
$.each(cellValue, function(i, v) { | |
$.log.debug('rowObject.taskDefinitionKey=' + rowObject.taskDefinitionKey); | |
$.log.debug('i=' + i); | |
// 逐层判断配置是否存在 | |
if ($.workflow.trace.variables) { | |
var variablesForProcess = $.workflow.trace.variables[rowObject.processDefinitionKey]; | |
if (variablesForProcess) { | |
var variablesForTask = variablesForProcess[rowObject.taskDefinitionKey]; | |
if (variablesForTask && variablesForTask[i]) { | |
var variableText = variablesForTask[i].text; | |
if (variableText) { | |
if (contents.length > 0) { | |
contents += "<br/>"; | |
} | |
var varValue = v; | |
if ($.isFunction(variablesForTask[i].formatter)) { | |
varValue = variablesForTask[i].formatter(v); | |
} | |
contents += variableText + ":" + varValue; | |
} | |
} | |
} | |
} | |
}); | |
return contents; | |
} | |
return ''; | |
} | |
}, { | |
name: 'description' | |
}*/ | |
], | |
loadComplete: function(data) { | |
}, | |
pgbuttons: false, | |
pagerpos: false, | |
pginput: false, | |
pgtext: false | |
})).jqGrid('navGrid', '#' + pagerId, $.extend({}, $.common.plugin.jqGrid.pager, { | |
add: false, | |
edit: false, | |
del: false, | |
search: false | |
}), {}, {}, {}, $.extend({}, $.common.plugin.jqGrid.form.search), {}); | |
} | |
}); | |
$.extend($.workflow, { | |
/* | |
* 图片形式跟踪流程 | |
*/ | |
graphTrace: function(options) { | |
var _defaults = { | |
srcEle: this, | |
pid: $(this).attr('pid') | |
}; | |
var opts = $.extend(true, _defaults, options); | |
var imageUrl = ctx + "/activiti/activiti!loadResource.action?resourceType=image&processInstanceId=" + opts.pid; | |
$.getJSON(ctx + '/activiti/activiti!traceProcess.action?processInstanceId=' + opts.pid, function(infos) { | |
var positionHtml = ""; | |
var varsArray = new Array(); | |
$.each(infos, function(i, v) { | |
var $positionDiv = $('<div/>', { | |
'class': 'activiyAttr' | |
}).css({ | |
position: 'absolute', | |
left: (v.x - 1), | |
top: (v.y - 1), | |
width: (v.width - 2), | |
height: (v.height - 2) | |
}) | |
if (v.currentActiviti) { | |
$positionDiv.addClass('ui-corner-all-12').css({ | |
border: '2px solid red' | |
}); | |
} | |
positionHtml += $positionDiv.outerHTML(); | |
varsArray[varsArray.length] = v.vars; | |
}); | |
if ($('#workflowTraceDialog').length == 0) { | |
$('<div/>', { | |
id: 'workflowTraceDialog', | |
title: '查看流程(按ESC键可以关闭)', | |
html: "<div id='workflowTraceAccordion'><h3><a href='#'>图片形式</a></h3><div><img src='" + imageUrl + "' style='position:absolute; left:0px; top:0px;' />" + | |
"<div id='processImageBorder'>" + | |
positionHtml + | |
"</div>" + | |
"</div><h3><a href='#'>文字形式</a></h3><div id='workflowTrace' class='workflow-trace-container'>" + | |
"<table id='workflowTraceList'></table><div id='workflowTracePager'></div></div></div>" | |
}).appendTo('body'); | |
} else { | |
$('#workflowTraceDialog img').attr('src', imageUrl); | |
$('#workflowTraceDialog #processImageBorder').html(positionHtml); | |
} | |
// 设置每个节点的data | |
$('#workflowTraceDialog .activiyAttr').each(function(i, v) { | |
$(this).data('vars', varsArray[i]); | |
}); | |
$('#workflowTraceDialog').dialog({ | |
modal: true, | |
resizable: false, | |
dragable: false, | |
open: function() { | |
$("#workflowTraceAccordion").accordion(); | |
$('#workflowTraceDialog').css('padding', '0.2em'); | |
$('#workflowTraceDialog .ui-accordion-content').css('padding', '0.2em').height($('#workflowTraceDialog').height() - 75); | |
$.workflow.trace.traceList(opts.pid, 'workflowTraceDialog', 'workflowTraceList', 'workflowTracePager'); | |
$('.activiyAttr').qtip({ | |
content: function() { | |
var vars = $(this).data('vars'); | |
var tipContent = "<table class='need-border'>"; | |
$.each(vars, function(varKey, varValue) { | |
if (varValue) { | |
tipContent += "<tr><td class='label'>" + varKey + "</td><td>" + varValue + "<td/></tr>"; | |
} | |
}); | |
tipContent += "</table>"; | |
return tipContent; | |
}, | |
position: { | |
at: 'bottom left', | |
adjust: { | |
x: 5 | |
} | |
} | |
}); | |
}, | |
width: $.common.window.getClientWidth(), | |
height: $.common.window.getClientHeight() | |
}); | |
}); | |
}, | |
/* | |
* 打开跟踪流程流转记录对话框 | |
*/ | |
showTraceList: function() { | |
var pid = $(this).attr('pid'); | |
if ($('#workflowTraceHistoricDialog').length == 0) { | |
$('<div/>', { | |
id: 'workflowTraceHistoricDialog', | |
title: '查看流程(按ESC键可以关闭)', | |
html: "<table id='workflowTraceHistoricList'></table><div id='workflowTraceHistoricPager'></div>" | |
}).appendTo('body'); | |
} | |
$('#workflowTraceHistoricDialog').dialog({ | |
modal: true, | |
resizable: false, | |
dragable: false, | |
open: function() { | |
$.workflow.trace.traceList(pid, 'workflowTraceHistoricDialog', 'workflowTraceHistoricList', 'workflowTraceHistoricPager'); | |
}, | |
width: $.common.window.getClientWidth(), | |
height: $.common.window.getClientHeight() | |
}); | |
}, | |
/* | |
* 删除流程实例 | |
*/ | |
deleteProcess: function(pid, callback) { | |
$('#deleteProcessTemplate').remove(); | |
$('<div/>', { | |
id: 'deleteProcessTemplate', | |
title: '删除流程', | |
html: "<textarea id='deleteProcessReason' style='width:100%;height: 100%'></textarea>" | |
}).dialog({ | |
modal: true, | |
buttons: [{ | |
text: '删除', | |
click: function() { | |
var dialog = this; | |
if ($('#deleteProcessReason').val() == '') { | |
alert('请输入原因!'); | |
return; | |
} | |
$.post(ctx + '/activiti/activiti!deleteProcessInstance.action', { | |
processInstanceId: pid, | |
deleteReason: $('#deleteProcessReason').val() | |
}, function(resp) { | |
$(dialog).dialog('close'); | |
if (resp == 'success') { | |
if ($.isFunction(callback)) { | |
callback(); | |
} | |
} else { | |
alert('删除流程失败'); | |
} | |
}); | |
} | |
}, { | |
text: '取消', | |
click: function() { | |
$(this).dialog('close'); | |
} | |
}] | |
}); | |
}, | |
/* | |
* 完成任务 | |
*/ | |
complete: function(options) { | |
var opts; | |
var _success = function(data, textStatus, jqXHR) { | |
if (data == 'success') { | |
if (opts.closeDialog && opts.dialog) { | |
$(opts.dialog).dialog('close'); | |
} | |
$('#' + opts.row.listId).jqGrid().trigger('reloadGrid'); | |
} else { | |
alert('操作失败,原因:' + data); | |
} | |
if ($.isFunction(opts.callback)) { | |
opts.callback(data, textStatus, jqXHR); | |
} | |
}; | |
var _error = function(jqXHR, textStatus, errorThrown) { | |
alert('操作失败!'); | |
}; | |
// 选择人员 | |
var selectUser = false; | |
try { | |
if ($.isFunction(options.settings.selectUser)) { | |
selectUser = options.settings.selectUser(options.row.rowData); | |
} else { | |
selectUser = options.settings.selectUser; | |
} | |
} catch (e) { | |
} | |
if (options.settings && selectUser) { | |
var nextTaskParam = {}; | |
if ($.isFunction(options.settings.nextTask)) { | |
nextTaskParam = options.settings.nextTask.call(this, options.row.rowData); | |
} else { | |
nextTaskParam = options.settings.nextTask; | |
} | |
var taskName = ""; | |
if (typeof nextTaskParam.taskName == 'string') { | |
taskName = nextTaskParam.taskName; | |
} else if ($.isFunction(nextTaskParam.taskName)) { | |
// 通过函数方式获取节点名称,因为考虑到可能需要条件判断 | |
taskName = nextTaskParam.taskName(options); | |
} | |
var taskZhName = options.row.rowData.taskNames[taskName] || taskName; | |
$.roleuser({ | |
role: nextTaskParam.role, | |
title: '选择[' + taskZhName + ']节点任务处理人', | |
confirmSelect: function(data) { | |
options.vars.push({ | |
key: nextTaskParam.assingee, | |
value: data.id, | |
type: 'S' | |
}); | |
sendRequest(); | |
}, | |
tree: { | |
loadComplete: function(data) { | |
// 单个用户时自动选择并确定 | |
if (data.length == 1) { | |
if (confirm('是否由系统将自动提交给[' + data[0].attr.userName + ']?')) { | |
options.vars.push({ | |
key: nextTaskParam.assingee, | |
value: data[0].attr.id, | |
type: 'S' | |
}); | |
sendRequest(); | |
$(this).dialog('close'); | |
} | |
} | |
} | |
} | |
}); | |
} else { | |
sendRequest(); | |
} | |
function sendRequest() { | |
// ajax params | |
var _ajaxParams = { | |
url: ctx + '/activiti/activiti-task!complete.action', | |
type: 'post', | |
data: { | |
taskId: options.row.rowData.task.id, | |
variables: $.jsonToString(options.vars) | |
}, | |
beforeSend: function() { | |
if (confirm('提交流程到下个节点?')) { | |
return true; | |
} | |
return false; | |
}, | |
success: _success, | |
error: _error | |
}; | |
$.log.debug('compelte variables:' + $.jsonToString(options.vars)); | |
var _defaults = { | |
row: {}, | |
vars: {}, | |
dialog: null, // 需要关闭的对话框,支持多个对话框,传入参数的时候可以$('#aaa').add('#bbb') | |
closeDialog: true, // 提交完成是否关闭对话框 | |
ajaxOpts: _ajaxParams, | |
callback: null | |
}; | |
opts = $.extend(true, _defaults, options); | |
// send ajax request | |
$.ajax($.extend({}, opts.ajaxOpts)); | |
} | |
}, | |
/* | |
* 驳回row, vars | |
*/ | |
reject: function(options) { | |
var _btns = [{ | |
text: '驳回', | |
icons: 'ui-icon-arrowreturnthick-1-w', | |
click: function() { | |
var turnDownReason = $('#turnDownReason', this).val(); | |
if (turnDownReason == '') { | |
alert('请输入驳回理由!'); | |
$('#turnDownReason', this).focus(); | |
return; | |
} | |
options.vars[options.vars.length] = { | |
key: 'turnDownReason', | |
type: 'S', | |
value: turnDownReason | |
}; | |
var _innerDialog = this; | |
$.workflow.complete({ | |
row: options.row, | |
vars: options.vars, | |
dialog: $(options.dialog).add(_innerDialog) | |
}); | |
} | |
}, { | |
text: '取消', | |
icons: 'ui-icon-cancel', | |
click: function() { | |
$(this).dialog('close'); | |
if ($.isFunction(options.settings.afterClose)) { | |
options.settings.afterClose(); | |
} | |
} | |
}]; | |
$('<div/>', { | |
title: '驳回理由?', | |
html: "<textarea id='turnDownReason' title='请填写驳回理由' style='height: 70px;width: 100%'></textarea>" | |
}).dialog({ | |
modal: true, | |
zIndex: 16000, | |
open: function() { | |
$.common.plugin.jqui.dialog.button.setAttrs(_btns); | |
}, | |
close: function() { | |
if ($.isFunction(options.settings.beforeClose)) { | |
options.settings.beforeClose(); | |
} | |
}, | |
buttons: _btns | |
}); | |
}, | |
/* | |
* 返回代理实现 | |
*/ | |
getAccessor: function(obj, expr) { | |
var ret, p, prm = [], i; | |
if (typeof expr === 'function') { | |
return expr(obj); | |
} | |
ret = obj[expr]; | |
if (ret === undefined) { | |
try { | |
if (typeof expr === 'string') { | |
prm = expr.split('.'); | |
} | |
i = prm.length; | |
if (i) { | |
ret = obj; | |
while (ret && i--) { | |
p = prm.shift(); | |
ret = ret[p]; | |
} | |
} | |
} catch (e) { | |
} | |
} | |
return ret; | |
}, | |
extend: function(methods) { | |
$.extend($.fn.workflow, methods); | |
} | |
}); | |
$.fn.workflow = function(pin) { | |
if (typeof pin == 'string') { | |
var fn = $.workflow.getAccessor($.fn.workflow, pin); | |
if (!fn) { | |
throw ("workflow - No such method: " + pin); | |
} | |
var args = $.makeArray(arguments).slice(1); | |
return fn.apply(this, args); | |
} | |
return this.each(function() { | |
// empty | |
}); | |
}; | |
// 各种工作流中使用的功能 | |
$.workflow.extend({ | |
/* | |
* 签收 | |
*/ | |
claim: function(options) { | |
var _defaults = { | |
listId: 'list', | |
confirm: true, | |
callback: null | |
}; | |
var opts = $.extend(true, _defaults, options); | |
/** | |
* 签收动作 | |
*/ | |
function claim(srcEle, opts) { | |
$.ajax({ | |
url: ctx + '/activiti/activiti-task!claim.action', | |
data: 'taskId=' + $(srcEle).attr('taskId') | |
}).success(function(resp) { | |
if (resp == 'success') { | |
$('#' + opts.listId).jqGrid().trigger('reloadGrid'); | |
} else { | |
alert('签收任务失败,原因:' + resp); | |
} | |
if ($.isFunction(opts.callback)) { | |
opts.callback(); | |
} | |
}); | |
}; | |
// 循环处理 | |
this.each(function() { | |
var _this = $(this); | |
// 美化按钮 | |
if (_this.get(0).nodeName == 'BUTTON') { | |
_this.button({ | |
icons: { | |
primary: 'ui-icon-person' | |
} | |
}); | |
} else { | |
alert('目前仅支持按钮'); | |
return; | |
} | |
_this.off('click').on('click', function() { | |
if (opts.confirm) { | |
if (confirm('签收此任务?')) { | |
claim(this, opts); | |
} | |
} else { | |
claim(this, opts); | |
} | |
}); | |
}); | |
}, | |
/* | |
* 办理 | |
*/ | |
handle: function(options) { | |
var _defaults = { | |
listId: 'list', | |
template: '', // 最外层模板 | |
map: {} | |
}; | |
var opts = $.extend(true, _defaults, options); | |
// 循环处理 | |
this.each(function() { | |
var _this = $(this); | |
var pid = _this.attr('pid'); | |
var taskId = $(this).attr('taskId'); | |
// 美化按钮 | |
if (_this.get(0).nodeName == 'BUTTON') { | |
_this.button({ | |
icons: { | |
primary: 'ui-icon-check' | |
} | |
}); | |
} else { | |
alert('目前仅支持按钮'); | |
return; | |
} | |
_this.on('click', function() { | |
var rowId = $(this).parents('tr').attr('id'); | |
// 当前节点英文、中文名称 | |
var currentNode = { | |
en: $(this).attr('taskDefinitionKey'), | |
cn: $(this).attr('taskName') | |
}; | |
var _handleDefault = { | |
form: { | |
autoSetValue: true, | |
fieldContainer: null, | |
afterSetValue: null, | |
valueFilter: null | |
}, | |
dialog: { | |
modal: true, | |
width: 300, | |
height: 300, | |
title: { | |
pre: '任务办理—[', | |
text: '', | |
suffix: ']' | |
}, | |
afterOpen: null | |
}, | |
flow: { | |
buttons: { | |
complete: { | |
show: true, | |
text: '提交', | |
title: '提交至下一节点', | |
icons: 'ui-icon-circle-arrow-e' | |
}, | |
sendBack: { | |
show: false, | |
text: '退回', | |
title: '退回至下一节点', | |
icons: 'ui-icon-arrowreturnthick-1-w' | |
}, | |
reject: { | |
show: false, | |
text: '驳回', | |
title: '驳回请求', | |
icons: 'ui-icon-closethick' | |
}, | |
redirect: { | |
show: false, | |
text: '转办', | |
title: '把当前任务转给其他人处理', | |
icons: 'ui-icon-person' | |
}, | |
delProc: { | |
show: false, | |
text: '删除流程', | |
title: '删除流程实例', | |
icons: 'ui-icon-trash' | |
}, | |
close: { | |
show: true, | |
text: '关闭', | |
title: '关闭对话框', | |
icons: 'ui-icon-cancel', | |
click: function() { | |
$(this).dialog("close"); | |
} | |
}, | |
attachs: [] | |
}, | |
buttonSettings: { | |
complete: { | |
variables: [], | |
ajaxOpts: {}, | |
beforeShow: null, | |
afterShow: null, | |
beforeSubmit: null, | |
afterSubmit: null, | |
beforeClose: null, | |
afterClose: null, | |
selectUser: false, | |
click: $.workflow.complete, | |
selectUser: false | |
}, | |
sendBack: { | |
variables: [], | |
ajaxOpts: {}, | |
beforeShow: null, | |
afterShow: null, | |
beforeSubmit: null, | |
afterSubmit: null, | |
beforeClose: null, | |
afterClose: null, | |
click: function(data) { | |
alert('暂未实现'); | |
} | |
}, | |
reject: { | |
variables: [], | |
ajaxOpts: {}, | |
beforeShow: null, | |
afterShow: null, | |
beforeSubmit: null, | |
afterSubmit: null, | |
beforeClose: null, | |
afterClose: null, | |
click: $.workflow.reject | |
}, | |
redirect: { | |
variables: [], | |
ajaxOpts: {}, | |
beforeShow: null, | |
afterShow: null, | |
beforeSubmit: null, | |
afterSubmit: null, | |
beforeClose: null, | |
afterClose: null, | |
click: function(data) { | |
alert('暂未实现'); | |
} | |
}, | |
delProc: { | |
variables: [], | |
ajaxOpts: {}, | |
beforeShow: null, | |
afterShow: null, | |
beforeSubmit: null, | |
afterSubmit: null, | |
beforeClose: null, | |
afterClose: null, | |
click: function(data) { | |
var dialogBtn = this; | |
$.workflow.deleteProcess(pid, function() { | |
$(dialogBtn).dialog('close'); | |
$('#' + opts.listId).jqGrid().trigger('reloadGrid'); | |
}); | |
} | |
}, | |
attachs: {} | |
} | |
} | |
}; | |
var handleOpts = $.extend(true, _handleDefault, opts.map[currentNode.en]); | |
var _handle_dialog = { | |
getButtons: function(ele) { | |
var btns = []; | |
// 扩展按钮 | |
$.each(handleOpts.flow.buttons.attachs, function() { | |
btns[btns.length] = this; | |
}); | |
// 流程按钮 | |
$.each(handleOpts.flow.buttons, function(i, v) { | |
if (v.show) { | |
try { | |
if (!v.click) { | |
v.click = function() { | |
var _srcEle = this; | |
var _cbtns = handleOpts.flow.buttonSettings[i]; | |
var _rowId = rowId; | |
var _listId = opts.listId; | |
var _rowData = $('body').data('jqgridResult_' + opts.listId)[rowId]; | |
var _callback = null; | |
// 处理列表中出现多余一个业务对象对应多个task,所以需要把taskId用按钮的属性替换 | |
_rowData.task.id = taskId; | |
var _rowParams = { | |
rowId: _rowId, | |
listId: _listId, | |
rowData: _rowData | |
}; | |
// 设置值 | |
var _vars = []; | |
$.each(_cbtns.variables, function() { | |
var map = {}; | |
$.each(this, function(j, jv) { | |
if ($.isFunction(jv)) { | |
map[j] = jv(_rowParams.rowData); | |
} else { | |
map[j] = jv; | |
} | |
}); | |
_vars[_vars.length] = map; | |
}); | |
// 按钮事件--执行前确认 | |
if ($.isFunction(_cbtns.beforeShow)) { | |
var result = _cbtns.beforeShow(_rowParams); | |
if (!result) { | |
return; | |
} | |
} | |
// 按钮的click事件 | |
_cbtns.click.call(_srcEle, { | |
row: _rowParams, | |
vars: _vars, | |
settings: _cbtns, | |
ajaxOpts: _cbtns.ajaxOpts, | |
dialog: $(_srcEle).dialog(), | |
callback: _cbtns.afterSubmit | |
}) | |
}; | |
} | |
} catch (e) { | |
} | |
btns[btns.length] = v; | |
} | |
}); | |
return btns; | |
} | |
}; | |
// 对话框标题 | |
var title = $(this).attr('taskName'); | |
if (typeof handleOpts.dialog.title == 'string') { | |
title = handleOpts.dialog.title; | |
} else { | |
var _pre = handleOpts.dialog.title.pre; | |
if ($.isFunction(_pre)) { | |
_pre.call(this, rowId); | |
} | |
var _text = handleOpts.dialog.title.text || title; | |
if ($.isFunction(_text)) { | |
_text = _text.call(this, rowId); | |
} | |
var _suffix = handleOpts.dialog.title.suffix; | |
if ($.isFunction(_suffix)) { | |
_suffix = _suffix.call(this, rowId); | |
} | |
title = _pre + _text + _suffix; | |
} | |
// 显示对话框 | |
var dialogTemplate = $('#' + currentNode.en, opts.template); | |
if (dialogTemplate.length == 0) { | |
dialogTemplate = $('#' + currentNode.en, '.ui-dialog'); | |
} | |
var buttons = _handle_dialog.getButtons(_this); | |
dialogTemplate.addClass('workflow-handle-dialog').dialog($.extend(handleOpts.dialog, { | |
title: title, | |
buttons: buttons, | |
open: function() { | |
var _dialog = this; | |
var _listId = opts.listId; | |
var _attachBtns = handleOpts.flow.buttonSettings.attachs; | |
// 错误提示的滚动条 | |
$(_dialog).scroll(function() { | |
$('.validator-error').each(function() { | |
var elem = $(this).data('elem'); | |
var position = elem.position(); | |
$(this).css({ | |
top: position.top + elem.height() + elem.height() + 8 | |
}); | |
}); | |
}); | |
// 如果handleOpts.form.fieldContainer没有设置默认使用当前的dialog | |
if (!handleOpts.form.fieldContainer) { | |
handleOpts.form.fieldContainer = _dialog; | |
} | |
// 设置按钮属性、功能 | |
$.common.plugin.jqui.dialog.button.setAttrs(buttons); | |
// 自定义按钮事件,目的是拦截之后传递一系列参数 | |
$.each(_attachBtns, function(i, v) { | |
var attachClick = v.click; | |
if ($.isFunction(attachClick)) { | |
// 先接触click事件,因为jqueryui在初始化的时候绑定了,否则会报错 | |
$('.ui-button-text').filter(function() { | |
return $(this).text() == i; | |
}).parent().off('click').click(function() { | |
var _rowData = $('body').data('jqgridResult_' + opts.listId)[rowId]; | |
// 处理列表中出现多余一个业务对象对应多个task,所以需要把taskId用按钮的属性替换 | |
_rowData.task.id = taskId; | |
var _rowParams = { | |
rowId: rowId, | |
listId: _listId, | |
rowData: _rowData, | |
dialog: _dialog | |
}; | |
// beforeShow回调 | |
if ($.isFunction(v.beforeShow)) { | |
var result = v.beforeShow(_vars); | |
if (!result) { | |
return; | |
} | |
} | |
// 自定义的变量,用来控制流程走向或者业务数据 | |
var _vars = []; | |
if (v.variables) { | |
$.each(v.variables, function() { | |
var map = {}; | |
$.each(this, function(j, jv) { | |
if ($.isFunction(jv)) { | |
map[j] = jv(_rowParams.rowData); | |
} else { | |
map[j] = jv; | |
} | |
}); | |
_vars[_vars.length] = map; | |
}); | |
} | |
// 回调click事件 | |
attachClick.call(_dialog, _rowParams, _vars, v.afterSubmit); | |
}); | |
} | |
}); | |
// 设置表单内容 | |
var gridData = $('body').data('jqgridResult_' + opts.listId); | |
if (handleOpts.form.autoSetValue) { | |
// 设置数据 | |
$('*[name]', handleOpts.form.fieldContainer).each(function() { | |
var colModel = $('#' + opts.listId).jqGrid('getGridParam', 'colModel'); | |
var colModelMap = {}; | |
$.each(colModel, function() { | |
colModelMap[this.name] = this; | |
}); | |
var nodeName = $(this).get(0).nodeName; | |
var value = ''; | |
var eleName = $(this).attr('name'); | |
var objs = eleName.split('.'); | |
if (objs.length > 1) { | |
// 排除多级属性中为空的情况 | |
try { | |
if (eval('(gridData[rowId].' + eleName + ')')) { | |
value = eval('(gridData[rowId].' + eleName + ')'); | |
} | |
} catch (e) { | |
// error | |
} | |
} else { | |
if ($(this).hasClass('variable')) { | |
if (gridData[rowId].variables[eleName]) { | |
value = gridData[rowId].variables[eleName]; | |
} | |
} else { | |
if (gridData[rowId][eleName]) { | |
value = gridData[rowId][eleName]; | |
} | |
} | |
} | |
// 再次让业务处理valueFilter | |
if ($.isFunction(handleOpts.form.valueFilter)) { | |
var newValue = handleOpts.form.valueFilter.call(this, eleName, value, gridData[rowId]); | |
value = newValue; | |
} | |
/* | |
* 只读 | |
*/ | |
if (nodeName == 'TD' || nodeName == 'SPAN' || nodeName == 'P' || nodeName == 'DIV' || | |
nodeName == 'LI') { | |
if (colModelMap[$(this).attr('name')] && colModelMap[$(this).attr('name')].formatter == 'date') { | |
$(this).html($('#' + opts.listId + ' #' + rowId + ' td[aria-describedby=' + opts.listId + '_' + $(this).attr('name') + ']').text()); | |
} else { | |
$(this).html(value); | |
} | |
} else if (nodeName == 'INPUT' || nodeName == 'SELECT' || nodeName == 'TEXTAREA') { | |
/* | |
* 可编辑 | |
*/ | |
if (!$(this).hasClass('no-auto-set-value')) { | |
$(this).val(value); | |
} | |
} | |
}); | |
if ($.isFunction(handleOpts.form.afterSetValue)) { | |
handleOpts.form.afterSetValue.call(this, gridData[rowId]); | |
} | |
} | |
if ($.isFunction(handleOpts.dialog.afterOpen)) { | |
handleOpts.dialog.afterOpen.call(this, gridData[rowId]); | |
} | |
}, | |
close: function() { | |
// 销毁验证用的qtip | |
if ($('.validator-error').length > 0) { | |
$('.validator-error').qtip('destroy'); | |
} | |
} | |
})); | |
}); | |
}); | |
return this; | |
} // end handle | |
}); | |
})(jQuery); | |
/* | |
* jqgrid支持 | |
*/ | |
(function($) { | |
$.workflow.jqgrid = $.workflow.jqgrid || {}; | |
$.extend($.workflow.jqgrid, { | |
/* | |
* 列表完成时绑定事件 | |
*/ | |
gridComplete: function() { | |
$('.trace-grpah').off('click').on('click', $.workflow.graphTrace); | |
$('.trace-historic').off('click').on('click', $.workflow.showTraceList); | |
$('.workflow-claim').workflow('claim'); | |
}, | |
/* | |
* 按钮扩展 | |
*/ | |
button: { | |
/** | |
* 任务列表的签收和办理按钮,实现jqgrid的formatter | |
* @param {Object} cellValue | |
* @param {Object} options | |
* @param {Object} rowObject | |
*/ | |
handle: function(cellValue, options, rowObject) { | |
if (!cellValue) { | |
return ''; | |
} | |
var flowDataType = $('body').data('flowDataType_' + options.gid); | |
if (!flowDataType) { | |
flowDataType = 'todo'; | |
} | |
if (flowDataType == 'todo') { | |
var procDef = rowObject.processDefinition; | |
var attrs = "pid='" + cellValue.processInstanceId + "' taskId='" + cellValue.id + "'"; | |
attrs += " taskName='" + cellValue.name + "' procDefId='" + procDef.id + "'"; | |
attrs += " proDefKey='" + procDef.name + "' version='" + procDef.version + "'"; | |
attrs += " taskDefinitionKey='" + cellValue.taskDefinitionKey + "'"; | |
return "<button class='workflow-do' + " + attrs + ">办理</button>"; | |
} else if (flowDataType == 'unsigned') { | |
var attrs = "' taskId='" + cellValue.id + "'"; | |
return "<button class='workflow-claim'" + attrs + ">签收</button>"; | |
} | |
} | |
} | |
}); | |
// task类型的流程数据列 | |
var taskColModels = [{ | |
name: 'task.createTime', | |
align: 'center', | |
title: false, | |
search: false, | |
formatter: "date", | |
formatoptions: { | |
srcformat: 'Y-m-dTH:i:s', | |
newformat: 'Y-m-d H:i:s' | |
} | |
}, { | |
name: 'task.name', | |
align: 'center', | |
title: false, | |
formatter: function(cellValue, options, rowObject) { | |
return "<a href='#' class='trace-grpah' title='跟踪流程图' pid='" + rowObject.processInstanceId + "'>" + | |
cellValue + | |
"</a> " + | |
"[<span title='流程版本号'>V:<span style='color:red'>" + | |
rowObject.processDefinition.version + | |
"</span></span>]"; | |
} | |
}, { | |
name: 'task.priority', | |
align: 'center', | |
width: 70, | |
formatter: function(cellValue, options, rowObject) { | |
var priority = parseInt(cellValue); | |
if (priority >= 0 && priority <50) { | |
return "<span class='task-priority-minium'>低</span>"; | |
} else if (priority >= 50 && priority < 100) { | |
return "<span class='task-priority-normal'>一般</span>"; | |
} else if (priority >= 100) { | |
return "<span class='task-priority-maximum'>高</span>"; | |
} | |
} | |
}, { | |
name: 'historicProcessInstance.startUser', | |
index: 'historicProcessInstance.startUserId', | |
align: 'center', | |
width: 90, | |
search: false, | |
formatter: function(cellValue, options, rowObject) { | |
return !cellValue ? "" : cellValue.name + "/" + cellValue.loginName; | |
} | |
}, { | |
name: 'task', | |
align: 'center', | |
title: false, | |
search: false, | |
sortable: false, | |
formatter: $.workflow.jqgrid.button.handle | |
}]; | |
/** | |
* 针对jqgrid的静态定义 | |
*/ | |
$.extend($.workflow.jqgrid, { | |
static: { | |
colNames: { | |
unsigned: ['发送时间', '当前节点', '优先级', '发起人', '操作'], | |
todo: ['发送时间', '当前节点', '优先级', '发起人', '操作'], | |
unfinished: ['当前节点', '状态', '发起人'], | |
finished: ['发起时间', '发起人', '完成时间', '查看流转'] | |
}, | |
colModels: { | |
unsigned: taskColModels, | |
todo: taskColModels, | |
unfinished: [{ | |
name: 'task.name', | |
align: 'center', | |
title: false, | |
formatter: function(cellValue, options, rowObject) { | |
var taskName = rowObject.taskNames[rowObject.processInstance.activityId]; | |
return "<a href='#' class='trace-grpah' title='跟踪流程图' pid='" + rowObject.processInstanceId + "'>" + | |
taskName + | |
"</a>"; | |
} | |
}, { | |
name: 'task.status', | |
sortable: false, | |
search: false, | |
align: 'center', | |
formatter: function(cellValue, options, rowObject) { | |
if (rowObject.task == null || rowObject.task.assignee == null) { | |
return '未签收'; | |
} else { | |
var user = rowObject.task.assigneeUser; | |
return '办理中(' + (user ? user.name + "/" + user.loginName : "") + ')'; | |
} | |
} | |
}, { | |
name: 'historicProcessInstance.startUser', | |
index: 'historicProcessInstance.startUserId', | |
align: 'center', | |
width: 90, | |
search: false, | |
formatter: function(cellValue, options, rowObject) { | |
return !cellValue ? "" : cellValue.name + "/" + cellValue.loginName; | |
} | |
}], | |
finished: [{ | |
name: 'historicProcessInstance.startTime', | |
align: 'center', | |
title: false, | |
width: 80, | |
formatter: "date", | |
formatoptions: { | |
srcformat: 'Y-m-dTH:i:s', | |
newformat: 'Y-m-d H:i:s' | |
} | |
}, { | |
name: 'historicProcessInstance.startUser', | |
index: 'historicProcessInstance.startUserId', | |
align: 'center', | |
width: 90, | |
search: false, | |
formatter: function(cellValue, options, rowObject) { | |
return !cellValue ? "" : cellValue.name + "/" + cellValue.loginName; | |
} | |
}, { | |
name: 'historicProcessInstance.endTime', | |
align: 'center', | |
title: false, | |
width: 80, | |
formatter: "date", | |
formatoptions: { | |
srcformat: 'Y-m-dTH:i:s', | |
newformat: 'Y-m-d H:i:s' | |
} | |
}, { | |
name: 'traceHistoricProcessInstance', | |
align: 'center', | |
width: 80, | |
search: false, | |
sortable: false, | |
formatter: function(cellValue, options, rowObject) { | |
return "<a href='#' class='trace-historic' pid='" + rowObject.processInstanceId + "'>查看</a>"; | |
} | |
}] | |
}, | |
groupHeaders: { | |
unfinished: { | |
startColumnName: 'task.name', | |
numberOfColumns: 5, | |
titleText: '流程信息' | |
}, | |
finished: { | |
startColumnName: 'historicProcessInstance.startTime', | |
numberOfColumns: 4, | |
titleText: '流程信息' | |
}, | |
tasks: { | |
startColumnName: 'task.createTime', | |
numberOfColumns: 4, | |
titleText: '流程信息' | |
} | |
} | |
}, | |
/** | |
* 列表头部的4个状态按钮 | |
* @param {Object} listId 列表ID | |
* @param {Object} data 列表数据,可以通过body的data获取,参见common.js中的loadComplete实现 | |
* @param {Object} autoResize 自动设置列表高度和宽度参数 | |
*/ | |
statusBtns: function(listId, data, autoResize) { | |
var gridData = data; | |
var workflowCounter = gridData.page.attachValues.workflowCounter; | |
var taskForGroupCounter = !workflowCounter ? 0 : workflowCounter.unsigned; | |
var todoTaskCounter = !workflowCounter ? 0 : workflowCounter.todo; | |
var unFinishedCounter = !workflowCounter ? 0 : workflowCounter.unfinished; | |
var finishedCounter = !workflowCounter ? 0 : workflowCounter.finished; | |
if ($('#t_' + listId + ' .workflow-list-status').length == 0) { | |
var btns = "<div class='workflow-list-status'>"; | |
btns += "<input type='radio' id='status1' name='workflowStatus' value='unsigned' /><label for='status1'>未签收:<span class='ui-state-error'>" + taskForGroupCounter + "</span></label>"; | |
btns += "<input type='radio' id='status2' name='workflowStatus' value='todo' /><label for='status2'>待处理:<span class='ui-state-error'>" + todoTaskCounter + "</span></label>"; | |
btns += "<input type='radio' id='status3' name='workflowStatus' value='unfinished' /><label for='status3'>运行中:<span class='ui-state-error'>" + unFinishedCounter + "</span></label>"; | |
btns += "<input type='radio' id='status4' name='workflowStatus' value='finished' /><label for='status4'>已结束:<span class='ui-state-error'>" + finishedCounter + "</span></label>"; | |
btns += "</div>"; | |
$('#t_list').css('textAlign', 'center').html(btns); | |
$('.workflow-list-status').find(':radio[value=' + $('body').data('flowDataType_list') + ']').attr('checked', 'checked'); | |
$('.workflow-list-status').buttonset(); | |
$(':radio[name=workflowStatus]').change(function() { | |
var selectedFlowDataType = $(this).val(); | |
// 上次数据类型 | |
var lastFlowDataType = $('body').data('flowDataType_' + listId); | |
// 设置本次数据类型 | |
$('body').data('flowDataType_' + listId, selectedFlowDataType); | |
// 签收和待处理是一类,运行中和已结束是一类 | |
if ((selectedFlowDataType == 'unsigned' || selectedFlowDataType == 'todo') && (lastFlowDataType == 'unsigned' || lastFlowDataType == 'todo')) { | |
listParams = '?flowDataType=' + selectedFlowDataType; | |
$('#list').jqGrid('setGridParam', { | |
url: listDataUrl + '?flowDataType=' + selectedFlowDataType | |
}).trigger('reloadGrid'); | |
} else { | |
$('#' + listId).jqGrid('GridUnload', '#' + listId); | |
// 不同类型切换 | |
$.common.plugin.jqGrid.autoResize($.extend({ | |
dataGrid: '#' + listId, | |
callback: function(size) { | |
var url = listDataUrl + '?flowDataType=' + selectedFlowDataType; | |
listDatas(size, url) | |
} | |
}, autoResize)); | |
} | |
}); | |
} else { | |
$('.workflow-list-status').show(); | |
$('label[for=status1] .ui-state-error').text(taskForGroupCounter); | |
$('label[for=status2] .ui-state-error').text(todoTaskCounter); | |
$('label[for=status3] .ui-state-error').text(unFinishedCounter); | |
$('label[for=status4] .ui-state-error').text(finishedCounter); | |
} | |
} | |
}); | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment