提交 5a456b80 编写于 作者: lakernote's avatar lakernote

(新增)[后端](引入流程引擎)

上级 21f9e0ff
......@@ -5,6 +5,7 @@ import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.Order;
import org.snaker.engine.entity.Process;
import org.snaker.engine.entity.Task;
import org.snaker.engine.model.TaskModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
......@@ -182,4 +183,30 @@ public class SnakerEngineFacets {
public List<Task> getTasks(String orderId) {
return engine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
}
/**
* 转办 主办
* @param taskId
* @param operator
* @param actors
* @return
*/
public List<Task> transferMajor(String taskId, String operator, String... actors) {
List<Task> tasks = engine.task().createNewTask(taskId, TaskModel.TaskType.Major.ordinal(), actors);
engine.task().complete(taskId, operator);
return tasks;
}
/**
* 转办 协办
* @param taskId
* @param operator
* @param actors
* @return
*/
public List<Task> transferAidant(String taskId, String operator, String... actors) {
List<Task> tasks = engine.task().createNewTask(taskId, TaskModel.TaskType.Aidant.ordinal(), actors);
engine.task().complete(taskId, operator);
return tasks;
}
}
\ No newline at end of file
/*
* Copyright 2014-2015 snakerflow.com
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.laker.admin.module.flow;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.snaker.engine.entity.HistoryTask;
import org.snaker.engine.entity.Task;
import org.snaker.engine.model.*;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Snaker的帮助类
*
* @author yuqs
* @since 0.1
*/
public class SnakerHelper {
private static Map<Class<? extends NodeModel>, String> mapper = new HashMap<Class<? extends NodeModel>, String>();
static {
mapper.put(TaskModel.class, "task");
mapper.put(CustomModel.class, "custom");
mapper.put(DecisionModel.class, "decision");
mapper.put(EndModel.class, "end");
mapper.put(ForkModel.class, "fork");
mapper.put(JoinModel.class, "join");
mapper.put(StartModel.class, "start");
mapper.put(SubProcessModel.class, "subprocess");
}
public static String getStateJson(ProcessModel model, List<Task> activeTasks, List<HistoryTask> historyTasks) {
StringBuffer buffer = new StringBuffer();
buffer.append("{'activeRects':{'rects':[");
if (activeTasks != null && activeTasks.size() > 0) {
for (Task task : activeTasks) {
buffer.append("{'paths':[],'name':'");
buffer.append(task.getTaskName());
buffer.append("'},");
}
buffer.deleteCharAt(buffer.length() - 1);
}
buffer.append("]}, 'historyRects':{'rects':[");
if (historyTasks != null && historyTasks.size() > 0) {
for (HistoryTask historyTask : historyTasks) {
NodeModel parentModel = model.getNode(historyTask.getTaskName());
if (parentModel == null) continue;
buffer.append("{'name':'").append(parentModel.getName()).append("','paths':[");
buffer.append("]},");
}
buffer.deleteCharAt(buffer.length() - 1);
}
buffer.append("]}}");
return buffer.toString();
}
public static String getModelJson(ProcessModel model) {
StringBuffer buffer = new StringBuffer();
List<TransitionModel> tms = new ArrayList<TransitionModel>();
for (NodeModel node : model.getNodes()) {
for (TransitionModel tm : node.getOutputs()) {
tms.add(tm);
}
}
buffer.append("{");
buffer.append(getNodeJson(model.getNodes()));
buffer.append(getPathJson(tms));
buffer.append("props:{props:{name:{name:'name',value:'");
buffer.append(convert(model.getName()));
buffer.append("'},displayName:{name:'displayName',value:'");
buffer.append(convert(model.getDisplayName()));
buffer.append("'},expireTime:{name:'expireTime',value:'");
buffer.append(convert(model.getExpireTime()));
buffer.append("'},instanceUrl:{name:'instanceUrl',value:'");
buffer.append(convert(model.getInstanceUrl()));
buffer.append("'},instanceNoClass:{name:'instanceNoClass',value:'");
buffer.append(convert(model.getInstanceNoClass()));
buffer.append("'}}}}");
return buffer.toString();
}
public static String getNodeJson(List<NodeModel> nodes) {
StringBuffer buffer = new StringBuffer();
buffer.append("states: {");
for (NodeModel node : nodes) {
buffer.append(node.getName());
buffer.append(getBase(node));
buffer.append(getLayout(node));
buffer.append(getProperty(node));
buffer.append(",");
}
buffer.deleteCharAt(buffer.length() - 1);
buffer.append("},");
return buffer.toString();
}
public static String getPathJson(List<TransitionModel> tms) {
StringBuffer buffer = new StringBuffer();
buffer.append("paths:{");
for (TransitionModel tm : tms) {
buffer.append(tm.getName());
buffer.append(":{from:'");
buffer.append(tm.getSource().getName());
buffer.append("',to:'");
buffer.append(tm.getTarget().getName());
buffer.append("', dots:[");
if (StringUtils.isNotEmpty(tm.getG())) {
String[] bendpoints = tm.getG().split(";");
for (String bendpoint : bendpoints) {
buffer.append("{");
String[] xy = bendpoint.split(",");
buffer.append("x:").append(getNumber(xy[0]));
buffer.append(",y:").append(xy[1]);
buffer.append("},");
}
buffer.deleteCharAt(buffer.length() - 1);
}
buffer.append("],text:{text:'");
buffer.append(tm.getDisplayName());
buffer.append("'},textPos:{");
if (StringUtils.isNotEmpty(tm.getOffset())) {
String[] values = tm.getOffset().split(",");
buffer.append("x:").append(values[0]).append(",");
buffer.append("y:").append(values[1]).append("");
}
buffer.append("}, props:{name:{value:'" + tm.getName() + "'},expr:{value:'" + tm.getExpr() + "'}}}");
buffer.append(",");
}
buffer.deleteCharAt(buffer.length() - 1);
buffer.append("},");
return buffer.toString();
}
private static String getBase(NodeModel node) {
StringBuffer buffer = new StringBuffer();
buffer.append(":{type:'");
buffer.append(mapper.get(node.getClass()));
buffer.append("',text:{text:'");
buffer.append(node.getDisplayName());
buffer.append("'},");
return buffer.toString();
}
private static String getProperty(NodeModel node) {
StringBuffer buffer = new StringBuffer();
buffer.append("props:{");
try {
PropertyDescriptor[] beanProperties = PropertyUtils.getPropertyDescriptors(node);
for (PropertyDescriptor propertyDescriptor : beanProperties) {
if (propertyDescriptor.getReadMethod() == null || propertyDescriptor.getWriteMethod() == null)
continue;
String name = propertyDescriptor.getName();
String value = "";
if (propertyDescriptor.getPropertyType() == String.class) {
value = (String) BeanUtils.getProperty(node, name);
} else {
continue;
}
if (value == null || value.equals("")) continue;
buffer.append(name);
buffer.append(":{value:'");
buffer.append(convert(value));
buffer.append("'},");
}
} catch (Exception e) {
e.printStackTrace();
}
buffer.deleteCharAt(buffer.length() - 1);
buffer.append("}}");
return buffer.toString();
}
private static String getLayout(NodeModel node) {
StringBuffer buffer = new StringBuffer();
buffer.append("attr:{");
String[] values = node.getLayout().split(",");
buffer.append("x:").append(getNumber(values[0])).append(",");
buffer.append("y:").append(values[1]).append(",");
if ("-1".equals(values[2])) {
if (node instanceof TaskModel || node instanceof CustomModel || node instanceof SubProcessModel) {
values[2] = "100";
} else {
values[2] = "50";
}
}
if ("-1".equals(values[3])) {
values[3] = "50";
}
buffer.append("width:").append(values[2]).append(",");
buffer.append("height:").append(values[3]);
buffer.append("},");
return buffer.toString();
}
private static String convert(String value) {
if (StringUtils.isEmpty(value))
return "";
if (value.indexOf("'") != -1) {
value = value.replaceAll("'", "#1");
}
if (value.indexOf("\"") != -1) {
value = value.replaceAll("\"", "#2");
}
if (value.indexOf("\r\n") != -1) {
value = value.replaceAll("\r\n", "#3");
}
if (value.indexOf("\n") != -1) {
value = value.replaceAll("\n", "#4");
}
if (value.indexOf(">") != -1) {
value = value.replaceAll(">", "#5");
}
if (value.indexOf("<") != -1) {
value = value.replaceAll("<", "#6");
}
if (value.indexOf("&amp;") != -1) {
value = value.replaceAll("&amp;", "#7");
}
return value;
}
public static String convertXml(String value) {
if (value.indexOf("#1") != -1) {
value = value.replaceAll("#1", "'");
}
if (value.indexOf("#2") != -1) {
value = value.replaceAll("#2", "\"");
}
if (value.indexOf("#5") != -1) {
value = value.replaceAll("#5", "&gt;");
}
if (value.indexOf("#6") != -1) {
value = value.replaceAll("#6", "&lt;");
}
if (value.indexOf("&") != -1) {
value = value.replaceAll("#7", "&amp;");
}
return value;
}
private static int getNumber(String value) {
if (value == null) return 0;
try {
return Integer.parseInt(value) + 180;
} catch (Exception e) {
return 0;
}
}
}
package com.laker.admin.module.flow;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.laker.admin.framework.PageResponse;
import com.laker.admin.framework.Response;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.snaker.engine.access.Page;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.Process;
import org.snaker.engine.entity.*;
import org.snaker.engine.helper.AssertHelper;
import org.snaker.engine.helper.StreamHelper;
import org.snaker.engine.helper.StringHelper;
import org.snaker.engine.model.ProcessModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.snaker.engine.access.QueryFilter.DESC;
@RestController
@RequestMapping("/flow")
@Slf4j
public class SnakerflowFacetsController {
@Autowired
private SnakerEngineFacets snakerEngineFacets;
/**
* --------- 流程相关 ---------
*/
@GetMapping("/process/modelJson")
@ApiOperation(value = "根据流程定义名称获取流程定义json", tags = "流程引擎-流程")
public String getProcess(@RequestParam(required = false) String processId) {
if (StrUtil.isBlank(processId)) {
return "";
}
Process process = snakerEngineFacets.getEngine().process().getProcessById(processId);
AssertHelper.notNull(process);
ProcessModel processModel = process.getModel();
if (processModel != null) {
String json = SnakerHelper.getModelJson(processModel);
return json;
}
return null;
}
/**
* 流程定义查询列表
*/
@ApiOperation(value = "根据给定的参数列表args分页查询process", tags = "流程引擎-流程")
@RequestMapping(value = "/process/list", method = RequestMethod.GET)
public Response processList(Page<Process> page, String displayName) {
QueryFilter filter = new QueryFilter();
if (StringHelper.isNotEmpty(displayName)) {
filter.setDisplayName(displayName);
}
filter.orderBy("create_Time").order(DESC);
snakerEngineFacets.getEngine().process().getProcesss(page, filter);
return PageResponse.ok(JSONUtil.parse(page.getResult()), page.getTotalCount());
}
/**
* 根据流程定义ID,删除流程定义
*
* @param id
* @return
*/
@ApiOperation(value = "根据流程定义ID,删除流程定义", tags = "流程引擎-流程")
@RequestMapping(value = "/process/delete/{id}", method = RequestMethod.GET)
public Response processDelete(@PathVariable("id") String id) {
snakerEngineFacets.getEngine().process().undeploy(id);
return Response.ok();
}
/**
* 保存流程定义[web流程设计器]
*
* @param model
* @return
*/
@ApiOperation(value = "保存流程定义[web流程设计器]", tags = "流程引擎-流程")
@RequestMapping(value = "/process/deployXml", method = RequestMethod.POST)
public boolean processDeploy(String model, String id) {
InputStream input = null;
try {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" + SnakerHelper.convertXml(model);
System.out.println("model xml=\n" + xml);
input = StreamHelper.getStreamFromString(xml);
if (StringUtils.isNotEmpty(id)) {
snakerEngineFacets.getEngine().process().redeploy(id, input);
} else {
snakerEngineFacets.getEngine().process().deploy(input);
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
@ApiOperation(value = "流程定义+流程状态", tags = "流程引擎-流程")
@RequestMapping(value = "/process/json", method = RequestMethod.GET)
public Object json(String processId, String orderId) {
Process process = snakerEngineFacets.getEngine().process().getProcessById(processId);
AssertHelper.notNull(process);
ProcessModel model = process.getModel();
Map<String, String> jsonMap = new HashMap<String, String>();
if (model != null) {
jsonMap.put("process", SnakerHelper.getModelJson(model));
}
if (StringUtils.isNotEmpty(orderId)) {
List<Task> tasks = snakerEngineFacets.getEngine().query().getActiveTasks(new QueryFilter().setOrderId(orderId));
List<HistoryTask> historyTasks = snakerEngineFacets.getEngine().query().getHistoryTasks(new QueryFilter().setOrderId(orderId));
jsonMap.put("state", SnakerHelper.getStateJson(model, tasks, historyTasks));
}
log.info(jsonMap.get("state"));
//{"historyRects":{"rects":[{"paths":["TO 任务1"],"name":"开始"},{"paths":["TO 分支"],"name":"任务1"},{"paths":["TO 任务3","TO 任务4","TO 任务2"],"name":"分支"}]}}
return jsonMap;
}
/**
* --------- 任务相关 ---------
*/
/**
* 根据当前用户查询待办任务列表
*/
@GetMapping("/task/todoList")
@ApiOperation(value = "根据当前用户查询待办任务列表", tags = "流程引擎-任务")
public Response userTaskTodoList() {
Page<WorkItem> page = new Page<>(30);
snakerEngineFacets.getEngine().query().getWorkItems(page,
new QueryFilter().setOperator(StpUtil.getLoginIdAsString()));
return Response.ok(page);
}
/**
* 根据当前用户查询待办任务列表
*/
@GetMapping("/task/doneList")
@ApiOperation(value = "根据当前用户查询已办任务列表", tags = "流程引擎-任务")
public Response userTaskdoneList() {
Page<WorkItem> page = new Page<>(30);
snakerEngineFacets.getEngine().query().getHistoryWorkItems(page,
new QueryFilter().setOperator(StpUtil.getLoginIdAsString()));
return Response.ok(page);
}
@GetMapping("/task/actor/add")
@ApiOperation(value = "根据流程实例id和任务名称,增加任务参与者", tags = "流程引擎-任务")
public Response addTaskActor(String orderId, String taskName, String operator) {
List<Task> tasks = snakerEngineFacets.getEngine().query().getActiveTasks(new QueryFilter().setOrderId(orderId));
for (Task task : tasks) {
if (task.getTaskName().equalsIgnoreCase(taskName) && StringUtils.isNotEmpty(operator)) {
snakerEngineFacets.getEngine().task().addTaskActor(task.getId(), operator);
}
}
return Response.ok();
}
@GetMapping("/task/tip")
@ApiOperation(value = "根据流程实例id和任务名称,查找当前任务的到达时间和待执行人", tags = "流程引擎-任务")
public Response taskTip(String orderId, String taskName) {
List<Task> tasks = snakerEngineFacets.getEngine().query().getActiveTasks(new QueryFilter().setOrderId(orderId));
StringBuilder builder = new StringBuilder();
String createTime = "";
String finishTime = "";
boolean find = false;
for (Task task : tasks) {
if (task.getTaskName().equalsIgnoreCase(taskName)) {
String[] actors = snakerEngineFacets.getEngine().query().getTaskActorsByTaskId(task.getId());
for (String actor : actors) {
builder.append(actor).append(",");
find = true;
}
createTime = task.getCreateTime();
}
}
if (!find) {
List<HistoryTask> historyTasks = snakerEngineFacets.getEngine().query().getHistoryTasks(new QueryFilter().setOrderId(orderId));
for (HistoryTask task : historyTasks) {
if (task.getTaskName().equalsIgnoreCase(taskName)) {
String[] actors = snakerEngineFacets.getEngine().query().getHistoryTaskActorsByTaskId(task.getId());
for (String actor : actors) {
builder.append(actor).append(",");
}
createTime = task.getCreateTime();
finishTime = task.getFinishTime();
}
}
}
if (builder.length() > 0) {
builder.deleteCharAt(builder.length() - 1);
}
Map<String, String> data = new HashMap<String, String>();
data.put("actors", builder.toString());
data.put("createTime", createTime);
data.put("finishTime", finishTime);
return Response.ok(data);
}
/**
* 活动任务的驳回
*/
@GetMapping("/task/reject")
@ApiOperation(value = "\t 【审批任务】驳回,根据任务主键ID,操作人ID,参数列表执行任务,并且根据nodeName跳转到任意节点\n" +
"\t 1、nodeName为null时,则跳转至上一步处理\n" +
"\t 2、nodeName不为null时,则任意跳转,即动态创建转移", tags = "流程引擎-任务")
public Response activeTaskReject(String taskId, String nodeName, String reason) {
Dict rejectReason = Dict.create()
// 拒绝原因,建议单独搞个 审核表 审核的comment file单独存储
.set("rejectReason", reason);
snakerEngineFacets.executeAndJump(taskId, StpUtil.getLoginIdAsString(), rejectReason, nodeName);
return Response.ok();
}
@RequestMapping(value = "/task/approval", method = RequestMethod.POST)
@ApiOperation(value = "【审批任务】同意", tags = "流程引擎-任务")
public Response doApproval(String taskId, String reason) {
snakerEngineFacets.execute(taskId, StpUtil.getLoginIdAsString(), null);
return Response.ok();
}
/**
* 历史任务撤回
*
* @param taskId
* @return
*/
@GetMapping("/task/undo")
@ApiOperation(value = "根据任务主键id、操作人撤回任务", tags = "流程引擎-任务")
public Response historyTaskUndo(String taskId) {
snakerEngineFacets.getEngine().task().withdrawTask(taskId, StpUtil.getLoginIdAsString());
return Response.ok();
}
@GetMapping("/task/transferMajor")
@ApiOperation(value = "转办", tags = "流程引擎-任务")
public Response transferMajor(String taskId, String nextOperator) {
snakerEngineFacets.transferMajor(taskId, StpUtil.getLoginIdAsString(), nextOperator.split(","));
return Response.ok();
}
/**
* 流程实例管理
*/
@ApiOperation(value = "流程分页查询", tags = "流程引擎-流程实例")
@RequestMapping(value = "/order/list", method = RequestMethod.GET)
public Response orderList(Page<HistoryOrder> page, String displayName) {
QueryFilter filter = new QueryFilter();
if (StringHelper.isNotEmpty(displayName)) {
filter.setDisplayName(displayName);
}
filter.orderBy("create_Time").order(DESC);
snakerEngineFacets.getEngine().query().getHistoryOrders(page, filter);
return PageResponse.ok(JSONUtil.parse(page.getResult()), page.getTotalCount());
}
}
......@@ -173,15 +173,15 @@ public class SnakerEngineFacetsTest {
Console.log("组长第一次看待办请假单:{}", activeTasks);
Console.log("组长处理请假单,并设置参数 day = 3, 修改 approveBoss.operator = 老板娘");
snakerEngineFacets.execute(activeTasks.get(0).getId(), "组长", Dict.create()
.set("day", 1)// #day &gt; 2 ? 'transition5' : 'transition4'
.set("day", 3)// #day &gt; 2 ? 'transition5' : 'transition4'
.set("approveBoss.operator", "老板娘"));
activeTasks = snakerEngineFacets.getEngine().query().getActiveTasks(new QueryFilter().setOperator("老板娘"));
Console.log("老板娘第一次看待办请假单:{}", activeTasks);
Console.log("老板娘处理请假单");
snakerEngineFacets.execute(activeTasks.get(0).getId(), "老板娘", null);
activeTasks = snakerEngineFacets.getEngine().query().getActiveTasks(new QueryFilter().setOperator("老板娘"));
Console.log("老板娘第二次看待办请假单:{}", activeTasks);
// snakerEngineFacets.execute(activeTasks.get(0).getId(), "老板娘", null);
// activeTasks = snakerEngineFacets.getEngine().query().getActiveTasks(new QueryFilter().setOperator("老板娘"));
// Console.log("老板娘第二次看待办请假单:{}", activeTasks);
}
......
function selectOrg(ctx, e1, e2)
{
var element1 = document.getElementById(e1);
var element2 = document.getElementById(e2);
var l = window.showModalDialog(ctx + "/dialogs/selectDialog.jsp?type=orgTree"," ","dialogWidth:800px;dialogHeight:540px;center:yes;scrolling:yes");
if (l == null )
return;
var result = splitUsersAndAccounts(l);
element1.value = result[0];
element1.title = result[0];
element2.value = result[1];
}
function selectOrgUser(ctx, e1, e2)
{
var element1 = document.getElementById(e1);
var element2 = document.getElementById(e2);
var l = window.showModalDialog(ctx + "/dialogs/selectDialog.jsp?type=orgUserTree"," ","dialogWidth:800px;dialogHeight:540px;center:yes;scrolling:yes");
if (l == null )
return;
var result = splitUsersAndAccounts(l);
element1.value = result[0];
element1.title = result[0];
element2.value = result[1];
}
function splitUsersAndAccounts( userNamesAndAccount )
{
var userNames = "";
var accounts = "";
var array = userNamesAndAccount.split( ";" );
for(i=0; i<array.length; i++)
{
var temp = splitUserNameAndAccount(array[i]);
userNames += temp[0] + ",";
accounts += temp[1] + ",";
}
userNames = userNames.substr(0, userNames.length - 1);
accounts = accounts.substr(0, accounts.length - 1);
var result = new Array(2);
result[0] = userNames;
result[1] = accounts;
return result;
}
function splitUserNameAndAccount( userNameAndAccount )
{
var temp = new Array(2);
if(userNameAndAccount.indexOf( "(" ) != -1)
{
temp[0] = userNameAndAccount.substring( 0,
userNameAndAccount.indexOf( "(" ) );
temp[1] = userNameAndAccount.substring( userNameAndAccount.indexOf( "(" ) + 1,
userNameAndAccount.indexOf( ")" ) );
}
else
{
temp[0] = userNameAndAccount;
temp[1] = userNameAndAccount;
}
return temp;
}
\ No newline at end of file
body {
margin: 0;
pading: 0;
text-align: left;
font-family: Arial, sans-serif, Helvetica, Tahoma;
font-size: 12px;
line-height: 1.5;
color: black;
}
.node {
width: 120px;
text-align: left;
vertical-align: middle;
border: 1px solid #fff;
}
.mover {
border: 1px solid #ddd;
background-color: #ddd;
}
.selected {
background-color: #ddd;
}
.state {
}
#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;
}
#toolbox {
border:1px solid #9AC3E1;
position: absolute;
top: 10;
left: 10;
background-color: #fff;
width: 120px;
cursor: default;
padding: 3px;
}
#toolbox_handle {
border:1px solid #9AC3E1;
margin-top:1px;
margin-bottom:10px;
width:98%;
align:center;
text-align:left;
font-weight: bold;
background-color: #CDF07F;
}
#properties {
border:1px solid #9AC3E1;
position: absolute;
top: 400;
right: 10;
width: 560px;
padding: 3px;
}
#properties_handle {
border:1px solid #9AC3E1;
margin-top:1px;
font-weight: bold;
align:center;
text-align:left;
background-color: #CDF07F;
}
.properties_all {
border-right:1px solid #9AC3E1;
width:100%;
text-align:left;
font-family: Arial, sans-serif, Helvetica, Tahoma;
font-size: 12px;
}
.properties_name {
background-color:#CDF07F;
border-left:1px solid #9AC3E1;
border-bottom:1px solid #9AC3E1;
color:#000;
font-weight: bold;
text-align:left;
width:100px;
}
.properties_value {
border-left:1px solid #9AC3E1;
border-bottom:1px solid #9AC3E1;
height: 24px;
width:460px;
}
\ No newline at end of file
(function($){
var snakerflow = $.snakerflow;
$.extend(true, snakerflow.editors, {
inputEditor : function(){
var _props,_k,_div,_src,_r;
this.init = function(props, k, div, src, r){
_props=props; _k=k; _div=div; _src=src; _r=r;
$('<input style="width:98%;"/>').val(props[_k].value).change(function(){
props[_k].value = $(this).val();
}).appendTo('#'+_div);
$('#'+_div).data('editor', this);
}
this.destroy = function(){
$('#'+_div+' input').each(function(){
_props[_k].value = $(this).val();
});
}
},
selectEditor : function(arg){
var _props,_k,_div,_src,_r;
this.init = function(props, k, div, src, r){
_props=props; _k=k; _div=div; _src=src; _r=r;
var sle = $('<select style="width:99%;"/>').val(props[_k].value).change(function(){
props[_k].value = $(this).val();
}).appendTo('#'+_div);
if(typeof arg === 'string'){
$.ajax({
type: "GET",
url: arg,
success: function(data){
var opts = eval(data);
if(opts && opts.length){
for(var idx=0; idx<opts.length; idx++){
sle.append('<option value="'+opts[idx].value+'">'+opts[idx].name+'</option>');
}
sle.val(_props[_k].value);
}
}
});
}else {
for(var idx=0; idx<arg.length; idx++){
sle.append('<option value="'+arg[idx].value+'">'+arg[idx].name+'</option>');
}
sle.val(_props[_k].value);
}
$('#'+_div).data('editor', this);
};
this.destroy = function(){
$('#'+_div+' input').each(function(){
_props[_k].value = $(this).val();
});
};
},
assigneeEditor : function(arg){
var _props,_k,_div,_src,_r;
this.init = function(props, k, div, src, r){
_props=props; _k=k; _div=div; _src=src; _r=r;
$('<input style="width:88%;" readonly="true" id="dialogEditor"/>').val(props[_k].value).appendTo('#'+_div);
$('<input style="width:10%;" type="button" value="选择"/>').click(function(){
//alert("选择:" + snakerflow.config.ctxPath + arg);
var element = document.getElementById("dialogEditor");
var l = window.showModalDialog(snakerflow.config.ctxPath + arg," ","dialogWidth:800px;dialogHeight:540px;center:yes;scrolling:yes");
if (l == null )
return;
var result = splitUsersAndAccounts(l);
element.title = result[1];
element.value = result[1];
props[_k].value = result[1];
props['assignee'].value = result[0];
}).appendTo('#'+_div);
$('#'+_div).data('editor', this);
}
this.destroy = function(){
//
}
}
});
})(jQuery);
\ No newline at end of file
function dbTable() {
$.ajax({
type:"GET",
url: parent.formData.ctx + "/form/form/tables?formId=" + parent.formData.id,
success:function(data){
var selectElement = document.getElementById("dbTable");
for(var i=0;i<data.length;i++) {
selectElement.options.add(new Option(data[i].name + '[' + data[i].displayName + ']', data[i].name));
}
}
});
}
function dbField(tableName) {
$.ajax({
type:"GET",
url: parent.formData.ctx + "/form/dbtable/fields?table=" + tableName,
success:function(data){
var selectElement = document.getElementById("dbField");
selectElement.options.length = 1;
for(var i=0;i<data.length;i++) {
selectElement.options.add(new Option(data[i].displayName,data[i].name));
}
}
});
}
function dict(element, config) {
$.ajax({
type:"GET",
url: parent.formData.ctx + "/config/dictionary/items?config=" + config,
success:function(data){
var selectElement = document.getElementById(element);
for(var i=0;i<data.length;i++) {
selectElement.options.add(new Option(data[i].name,data[i].code));
}
}
});
}
function dictionary(element) {
$.ajax({
type:"GET",
url: parent.formData.ctx + "/config/dictionary/dicts",
success:function(data){
var selectElement = document.getElementById(element);
for(var i=0;i<data.length;i++) {
selectElement.options.add(new Option(data[i].cnName,data[i].name));
}
}
});
}
\ No newline at end of file
(function ($) {
var snakerflow = $.snakerflow;
$.extend(true, snakerflow.config.rect, {
attr: {
r: 8,
fill: '#F6F7FF',
stroke: '#03689A',
"stroke-width": 2
}
});
$.extend(true, snakerflow.config.props.props, {
name: {
name: 'name', label: '名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
displayName: {
name: 'displayName', label: '显示名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
expireTime: {
name: 'expireTime', label: '期望完成时间', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
instanceUrl: {
name: 'instanceUrl', label: '实例启动Url', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
instanceNoClass: {
name: 'instanceNoClass', label: '实例编号生成类', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
}
});
$.extend(true, snakerflow.config.tools.states, {
start: {
showType: 'image',
type: 'start',
name: {text: '<<start>>'},
text: {text: 'start'},
img: {src: 'images/48/start_event_empty.png', width: 48, height: 48},
attr: {width: 50, heigth: 50},
props: {
name: {
name: 'name', label: '名称', value: 'start', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
preInterceptors: {
name: 'preInterceptors', label: '前置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
postInterceptors: {
name: 'postInterceptors', label: '后置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
}
}
},
end: {
showType: 'image',
type: 'end',
name: {text: '<<end>>'},
text: {text: 'end'},
img: {src: 'images/48/end_event_terminate.png', width: 48, height: 48},
attr: {width: 50, heigth: 50},
props: {
name: {
name: 'name', label: '名称', value: 'end', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
preInterceptors: {
name: 'preInterceptors', label: '前置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
postInterceptors: {
name: 'postInterceptors', label: '后置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
}
}
},
task: {
showType: 'text',
type: 'task',
name: {text: '<<task>>'},
text: {text: 'task'},
img: {src: 'images/48/task_empty.png', width: 48, height: 48},
props: {
name: {
name: 'name', label: '名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
displayName: {
name: 'displayName', label: '显示名称', value: '', editor: function () {
return new snakerflow.editors.textEditor();
}
},
form: {
name: 'form', label: '表单', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
assignee: {name: 'assignee', value: ''},
assigneeDisplay: {
name: 'assigneeDisplay', label: '参与者', value: '', editor: function () {
// return new snakerflow.editors.assigneeEditor('/dialogs/selectDialog.jsp?type=orgUserTree');
return new snakerflow.editors.inputEditor();
}
},
assignmentHandler: {
name: 'assignmentHandler', label: '参与者处理类', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
taskType: {
name: 'taskType', label: '任务类型', value: '', editor: function () {
return new snakerflow.editors.selectEditor([{name: '主办任务', value: 'Major'}, {
name: '协办任务',
value: 'Aidant'
}]);
}
},
performType: {
name: 'performType', label: '参与类型', value: '', editor: function () {
return new snakerflow.editors.selectEditor([{name: '普通参与', value: 'ANY'}, {
name: '会签参与',
value: 'ALL'
}]);
}
},
preInterceptors: {
name: 'preInterceptors', label: '前置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
postInterceptors: {
name: 'postInterceptors', label: '后置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
reminderTime: {
name: 'reminderTime', label: '提醒时间', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
reminderRepeat: {
name: 'reminderRepeat', label: '重复提醒间隔', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
expireTime: {
name: 'expireTime', label: '期望完成时间', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
autoExecute: {
name: 'autoExecute', label: '是否自动执行', value: '', editor: function () {
return new snakerflow.editors.selectEditor([{name: '', value: 'N'}, {name: '', value: 'Y'}]);
}
},
callback: {
name: 'callback', label: '回调处理', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
}
}
},
custom: {
showType: 'text',
type: 'custom',
name: {text: '<<custom>>'},
text: {text: 'custom'},
img: {src: 'images/48/task_empty.png', width: 48, height: 48},
props: {
name: {
name: 'name', label: '名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
displayName: {
name: 'displayName', label: '显示名称', value: '', editor: function () {
return new snakerflow.editors.textEditor();
}
},
clazz: {
name: 'clazz', label: '类路径', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
methodName: {
name: 'methodName', label: '方法名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
args: {
name: 'args', label: '参数变量', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
preInterceptors: {
name: 'preInterceptors', label: '前置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
postInterceptors: {
name: 'postInterceptors', label: '后置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
}
}
},
subprocess: {
showType: 'text',
type: 'subprocess',
name: {text: '<<subprocess>>'},
text: {text: 'subprocess'},
img: {src: 'images/48/task_empty.png', width: 48, height: 48},
props: {
name: {
name: 'name', label: '名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
displayName: {
name: 'displayName', label: '显示名称', value: '', editor: function () {
return new snakerflow.editors.textEditor();
}
},
processName: {
name: 'processName', label: '子流程名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
preInterceptors: {
name: 'preInterceptors', label: '前置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
postInterceptors: {
name: 'postInterceptors', label: '后置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
}
}
},
decision: {
showType: 'image',
type: 'decision',
name: {text: '<<decision>>'},
text: {text: 'decision'},
img: {src: 'images/48/gateway_exclusive.png', width: 48, height: 48},
props: {
name: {
name: 'name', label: '名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
expr: {
name: 'expr', label: '决策表达式', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
handleClass: {
name: 'handleClass', label: '处理类名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
preInterceptors: {
name: 'preInterceptors', label: '前置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
postInterceptors: {
name: 'postInterceptors', label: '后置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
}
}
},
fork: {
showType: 'image',
type: 'fork',
name: {text: '<<fork>>'},
text: {text: 'fork'},
img: {src: 'images/48/gateway_parallel.png', width: 48, height: 48},
props: {
name: {
name: 'name', label: '名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
preInterceptors: {
name: 'preInterceptors', label: '前置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
postInterceptors: {
name: 'postInterceptors', label: '后置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
}
}
},
join: {
showType: 'image',
type: 'join',
name: {text: '<<join>>'},
text: {text: 'join'},
img: {src: 'images/48/gateway_parallel.png', width: 48, height: 48},
props: {
name: {
name: 'name', label: '名称', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
preInterceptors: {
name: 'preInterceptors', label: '前置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
},
postInterceptors: {
name: 'postInterceptors', label: '后置拦截器', value: '', editor: function () {
return new snakerflow.editors.inputEditor();
}
}
}
}
});
})(jQuery);
\ No newline at end of file
function expandAll() {
var divs = document.all.tags("div");
for (var i = 0; i < divs.length; i++) {
var idvalue = divs[i].id;
if (idvalue.lastIndexOf("DIV") > 0) {
divs[i].style.display = "block";
}
}
}
function expandNode(base, divId) {
var div = document.getElementById(divId+"_DIV");
if (div.style.display == "none"){
div.style.display = "block";
document.all[divId+"_img"].src = base + "/styles/images/flowopen.gif";
}else{
div.style.display = "none";
document.all[divId+"_img"].src = base + "/styles/images/flowclose.gif";
}
}
function collapseAll() {
var divs = document.all.tags("div");
for (var i = 0; i < divs.length; i++ ) {
var idvalue = divs[i].id;
if (idvalue.lastIndexOf("DIV") > 0) {
divs[i].style.display = "none";
}
}
}
function currentNode() {
collapseAll();
document.getElementById("${task.taskName}_DIV").style.display = "block";
}
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册