..
This commit is contained in:
@@ -20,6 +20,7 @@ import com.budwk.app.flow.entity.ProcessTask;
|
|||||||
import com.budwk.app.flow.enums.ProcessEventTypeEnum;
|
import com.budwk.app.flow.enums.ProcessEventTypeEnum;
|
||||||
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
|
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
|
||||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||||
|
import com.budwk.app.flow.vo.HighLightVO;
|
||||||
import com.budwk.app.flow.vo.ProcessInstanceVO;
|
import com.budwk.app.flow.vo.ProcessInstanceVO;
|
||||||
import com.budwk.app.flow.vo.ProcessTaskVO;
|
import com.budwk.app.flow.vo.ProcessTaskVO;
|
||||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
@@ -137,11 +138,23 @@ public class FlowCommonController {
|
|||||||
List<ProcessTaskVO> res = new ArrayList<>();
|
List<ProcessTaskVO> res = new ArrayList<>();
|
||||||
processTaskList.forEach(processTask -> {
|
processTaskList.forEach(processTask -> {
|
||||||
ProcessTaskVO vo = BeanUtil.toBean(processTask, ProcessTaskVO.class);
|
ProcessTaskVO vo = BeanUtil.toBean(processTask, ProcessTaskVO.class);
|
||||||
|
if (vo.getTaskState().equals(ProcessTaskStateEnum.FINISHED.getCode()) && StrUtil.isNotBlank(vo.getOperator())) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
res.add(vo);
|
res.add(vo);
|
||||||
});
|
});
|
||||||
return Result.success(res);
|
return Result.success(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("流程图高亮")
|
||||||
|
public Result instanceHighLight(@Param("instanceId") Long instanceId) {
|
||||||
|
HighLightVO highLightVO = flowEngine.processInstanceService().highLight(instanceId);
|
||||||
|
return Result.success(highLightVO);
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckLogin
|
@SaCheckLogin
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
@@ -209,6 +222,7 @@ public class FlowCommonController {
|
|||||||
@At("/executeTask")
|
@At("/executeTask")
|
||||||
@SaCheckLogin
|
@SaCheckLogin
|
||||||
@ApiOperation("执行任务")
|
@ApiOperation("执行任务")
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Result executeTask(@Param("data") String param) {
|
public Result executeTask(@Param("data") String param) {
|
||||||
Dict args = Json.fromJson(Dict.class, param);
|
Dict args = Json.fromJson(Dict.class, param);
|
||||||
Long processTaskId = args.getLong(FlowConst.PROCESS_TASK_ID_KEY);
|
Long processTaskId = args.getLong(FlowConst.PROCESS_TASK_ID_KEY);
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ public class FlowDefineController {
|
|||||||
@Ok("beetl:/platform/flow/define/preview.html")
|
@Ok("beetl:/platform/flow/define/preview.html")
|
||||||
@SaCheckLogin
|
@SaCheckLogin
|
||||||
public void preview(HttpServletRequest request) {
|
public void preview(HttpServletRequest request) {
|
||||||
request.setAttribute("id", request.getParameter("id"));
|
request.setAttribute("defineId", request.getParameter("defineId"));
|
||||||
|
request.setAttribute("instanceId", request.getParameter("instanceId"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ public class FlowDesignController {
|
|||||||
jsonObject.set("instanceViewUrl", processDesign.getInstanceViewUrl());
|
jsonObject.set("instanceViewUrl", processDesign.getInstanceViewUrl());
|
||||||
jsonObject.set("h5InstanceViewUrl", processDesign.getH5InstanceViewUrl());
|
jsonObject.set("h5InstanceViewUrl", processDesign.getH5InstanceViewUrl());
|
||||||
jsonObject.set("icon", processDesign.getIcon());
|
jsonObject.set("icon", processDesign.getIcon());
|
||||||
|
jsonObject.set("description", processDesign.getDescription());
|
||||||
processDesign.setContent(jsonObject);
|
processDesign.setContent(jsonObject);
|
||||||
dao.insert(processDesign);
|
dao.insert(processDesign);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
@@ -143,6 +144,7 @@ public class FlowDesignController {
|
|||||||
jsonObject.set("instanceViewUrl", processDesign.getInstanceViewUrl());
|
jsonObject.set("instanceViewUrl", processDesign.getInstanceViewUrl());
|
||||||
jsonObject.set("h5InstanceViewUrl", processDesign.getH5InstanceViewUrl());
|
jsonObject.set("h5InstanceViewUrl", processDesign.getH5InstanceViewUrl());
|
||||||
jsonObject.set("icon", processDesign.getIcon());
|
jsonObject.set("icon", processDesign.getIcon());
|
||||||
|
jsonObject.set("description", processDesign.getDescription());
|
||||||
processDesign.setContent(jsonObject);
|
processDesign.setContent(jsonObject);
|
||||||
processDesignService.update(processDesign);
|
processDesignService.update(processDesign);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
@@ -161,12 +163,12 @@ public class FlowDesignController {
|
|||||||
jsonObject.set("instanceViewUrl", processDesign.getInstanceViewUrl());
|
jsonObject.set("instanceViewUrl", processDesign.getInstanceViewUrl());
|
||||||
jsonObject.set("h5InstanceViewUrl", processDesign.getH5InstanceViewUrl());
|
jsonObject.set("h5InstanceViewUrl", processDesign.getH5InstanceViewUrl());
|
||||||
jsonObject.set("icon", processDesign.getIcon());
|
jsonObject.set("icon", processDesign.getIcon());
|
||||||
|
jsonObject.set("description", processDesign.getDescription());
|
||||||
processDesign.setContent(jsonObject);
|
processDesign.setContent(jsonObject);
|
||||||
processDesignService.update(processDesign);
|
processDesignService.update(processDesign);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckLogin
|
@SaCheckLogin
|
||||||
@ApiOperation("删除流程设计")
|
@ApiOperation("删除流程设计")
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* 流程模型
|
* 流程模型
|
||||||
|
*
|
||||||
* @author mldong
|
* @author mldong
|
||||||
* @date 2023/4/25
|
* @date 2023/4/25
|
||||||
*/
|
*/
|
||||||
@@ -24,6 +24,8 @@ public class ProcessModel extends BaseModel {
|
|||||||
private String type; // 流程定义分类
|
private String type; // 流程定义分类
|
||||||
private String icon; // 流程定义图标
|
private String icon; // 流程定义图标
|
||||||
private String category; // 流程定义分类
|
private String category; // 流程定义分类
|
||||||
|
private String remark; // 流程备注
|
||||||
|
private String description; // 流程说明
|
||||||
private String instanceUrl; // 启动实例要填写的表单key
|
private String instanceUrl; // 启动实例要填写的表单key
|
||||||
private String h5InstanceUrl; // 启动实例要填写的手机端表单key
|
private String h5InstanceUrl; // 启动实例要填写的手机端表单key
|
||||||
private String instanceViewUrl;
|
private String instanceViewUrl;
|
||||||
@@ -39,6 +41,7 @@ public class ProcessModel extends BaseModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取开始节点
|
* 获取开始节点
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public StartModel getStart() {
|
public StartModel getStart() {
|
||||||
@@ -55,6 +58,7 @@ public class ProcessModel extends BaseModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取process定义的指定节点名称的节点模型
|
* 获取process定义的指定节点名称的节点模型
|
||||||
|
*
|
||||||
* @param nodeName 节点名称
|
* @param nodeName 节点名称
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -69,6 +73,7 @@ public class ProcessModel extends BaseModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取下一个任务节点模型集合
|
* 获取下一个任务节点模型集合
|
||||||
|
*
|
||||||
* @param nodeName
|
* @param nodeName
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -95,6 +100,7 @@ public class ProcessModel extends BaseModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取下一个任务节点的候选人
|
* 获取下一个任务节点的候选人
|
||||||
|
*
|
||||||
* @param nodeName
|
* @param nodeName
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -106,8 +112,10 @@ public class ProcessModel extends BaseModel {
|
|||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据任务模型获取候选人
|
* 根据任务模型获取候选人
|
||||||
|
*
|
||||||
* @param taskModel
|
* @param taskModel
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -134,8 +142,10 @@ public class ProcessModel extends BaseModel {
|
|||||||
// 去重
|
// 去重
|
||||||
return res.stream().distinct().collect(Collectors.toList());
|
return res.stream().distinct().collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据指定的节点类型返回流程定义中所有模型对象
|
* 根据指定的节点类型返回流程定义中所有模型对象
|
||||||
|
*
|
||||||
* @param clazz 节点类型
|
* @param clazz 节点类型
|
||||||
* @param <T> 泛型
|
* @param <T> 泛型
|
||||||
* @return 节点列表
|
* @return 节点列表
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import java.util.List;
|
|||||||
public class LfModel extends BaseModel {
|
public class LfModel extends BaseModel {
|
||||||
private String type; // 流程定义分类
|
private String type; // 流程定义分类
|
||||||
private String category;
|
private String category;
|
||||||
|
private String description; // 流程描述
|
||||||
private String expireTime;// 过期时间(常量或变量)
|
private String expireTime;// 过期时间(常量或变量)
|
||||||
private String instanceUrl; // 启动实例的url,前后端分离后,定义为路由名或或路由地址
|
private String instanceUrl; // 启动实例的url,前后端分离后,定义为路由名或或路由地址
|
||||||
private String h5InstanceUrl;
|
private String h5InstanceUrl;
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
package com.budwk.app.flow.engine.parser;
|
package com.budwk.app.flow.engine.parser;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.io.IoUtil;
|
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.budwk.app.flow.engine.core.ServiceContext;
|
import com.budwk.app.flow.engine.core.ServiceContext;
|
||||||
import com.budwk.app.flow.engine.model.NodeModel;
|
import com.budwk.app.flow.engine.model.NodeModel;
|
||||||
import com.budwk.app.flow.engine.model.ProcessModel;
|
import com.budwk.app.flow.engine.model.ProcessModel;
|
||||||
import com.budwk.app.flow.engine.model.TaskModel;
|
import com.budwk.app.flow.engine.model.TaskModel;
|
||||||
import com.budwk.app.flow.engine.model.TransitionModel;
|
import com.budwk.app.flow.engine.model.TransitionModel;
|
||||||
import com.budwk.app.flow.engine.model.logicflow.*;
|
import com.budwk.app.flow.engine.model.logicflow.LfEdge;
|
||||||
|
import com.budwk.app.flow.engine.model.logicflow.LfModel;
|
||||||
|
import com.budwk.app.flow.engine.model.logicflow.LfNode;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ModelParser {
|
public class ModelParser {
|
||||||
private ModelParser(){}
|
private ModelParser() {
|
||||||
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * 将json定义文件解析成流程模型对象
|
// * 将json定义文件解析成流程模型对象
|
||||||
@@ -79,6 +80,7 @@ public class ModelParser {
|
|||||||
processModel.setDisplayName(lfModel.getDisplayName());
|
processModel.setDisplayName(lfModel.getDisplayName());
|
||||||
processModel.setType(lfModel.getType());
|
processModel.setType(lfModel.getType());
|
||||||
processModel.setCategory(lfModel.getCategory());
|
processModel.setCategory(lfModel.getCategory());
|
||||||
|
processModel.setDescription(lfModel.getDescription());
|
||||||
processModel.setInstanceUrl(lfModel.getInstanceUrl());
|
processModel.setInstanceUrl(lfModel.getInstanceUrl());
|
||||||
processModel.setH5InstanceUrl(lfModel.getH5InstanceUrl());
|
processModel.setH5InstanceUrl(lfModel.getH5InstanceUrl());
|
||||||
processModel.setInstanceViewUrl(lfModel.getInstanceViewUrl());
|
processModel.setInstanceViewUrl(lfModel.getInstanceViewUrl());
|
||||||
|
|||||||
@@ -73,9 +73,14 @@ public class ProcessDefine extends BaseModel {
|
|||||||
@Column
|
@Column
|
||||||
private Integer version;
|
private Integer version;
|
||||||
|
|
||||||
@Comment
|
@Comment("首字母")
|
||||||
@Column
|
@Column
|
||||||
@ColDefine(type = ColType.CHAR)
|
@ColDefine(type = ColType.CHAR)
|
||||||
private Character pinyinName;
|
private Character pinyinName;
|
||||||
|
|
||||||
|
@Comment("流程描述")
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.TEXT)
|
||||||
|
private String description;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ import org.nutz.dao.entity.annotation.*;
|
|||||||
@Comment("流程设计")
|
@Comment("流程设计")
|
||||||
public class ProcessDesign extends BaseModel {
|
public class ProcessDesign extends BaseModel {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Comment("主键")
|
@Comment("主键")
|
||||||
@Id
|
@Id
|
||||||
private Long id;
|
private Long id;
|
||||||
@@ -70,6 +68,11 @@ public class ProcessDesign extends BaseModel {
|
|||||||
@Column
|
@Column
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
@Comment("流程描述")
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.TEXT)
|
||||||
|
private String description;
|
||||||
|
|
||||||
@Comment("流程定义")
|
@Comment("流程定义")
|
||||||
@Column
|
@Column
|
||||||
@ColDefine(type = ColType.MYSQL_JSON)
|
@ColDefine(type = ColType.MYSQL_JSON)
|
||||||
|
|||||||
@@ -219,12 +219,6 @@ public interface ProcessInstanceService extends BaseService<ProcessInstance> {
|
|||||||
* @param actorId
|
* @param actorId
|
||||||
*/
|
*/
|
||||||
void updateCCStatus(Long processInstanceId, String actorId);
|
void updateCCStatus(Long processInstanceId, String actorId);
|
||||||
/**
|
|
||||||
* 自定义分页查询我的抄送
|
|
||||||
* @param param
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
// CommonPage<ProcessInstanceVO> ccInstancePage(ProcessInstancePageParam param);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取流程参与人回显文本数据
|
* 获取流程参与人回显文本数据
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ public class ProcessDefineServiceImpl extends BaseServiceImpl<ProcessDefine> imp
|
|||||||
define.setH5InstanceViewUrl(processModel.getH5InstanceViewUrl());
|
define.setH5InstanceViewUrl(processModel.getH5InstanceViewUrl());
|
||||||
define.setIcon(processModel.getIcon());
|
define.setIcon(processModel.getIcon());
|
||||||
define.setPinyinName(PinyinUtil.getFirstLetter(define.getDisplayName().charAt(0)));
|
define.setPinyinName(PinyinUtil.getFirstLetter(define.getDisplayName().charAt(0)));
|
||||||
|
define.setDescription(processModel.getDescription());
|
||||||
|
|
||||||
define.setState(1);
|
define.setState(1);
|
||||||
define.setContent(JSONUtil.parseObj(defineJsonStr));
|
define.setContent(JSONUtil.parseObj(defineJsonStr));
|
||||||
|
|||||||
@@ -175,8 +175,18 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
|
|||||||
processTask.setTaskType(taskModel.getTaskType().getCode());
|
processTask.setTaskType(taskModel.getTaskType().getCode());
|
||||||
processTask.setFormKey(taskModel.getForm());
|
processTask.setFormKey(taskModel.getForm());
|
||||||
processTask.setProcessInstanceId(execution.getProcessInstanceId());
|
processTask.setProcessInstanceId(execution.getProcessInstanceId());
|
||||||
execution.getArgs().put(FlowConst.IS_FIRST_TASK_NODE, FlowUtil.isFistTaskName(execution.getProcessModel(), taskModel.getName()));
|
|
||||||
// 增加是否为第一个任务节点标识
|
// 增加是否为第一个任务节点标识
|
||||||
|
execution.getArgs().put(FlowConst.IS_FIRST_TASK_NODE, FlowUtil.isFistTaskName(execution.getProcessModel(), taskModel.getName()));
|
||||||
|
//过滤上个任务的表单数据 避免造成污染 每个任务只保存自己的表单数据
|
||||||
|
Dict cleanArgs = Dict.create();
|
||||||
|
execution.getArgs().forEach((k, v) -> {
|
||||||
|
if (!k.startsWith(FlowConst.TASK_FORM_DATA_PREFIX)) {
|
||||||
|
cleanArgs.set(k, v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
execution.setArgs(cleanArgs);
|
||||||
|
|
||||||
processTask.setVariable(JSONUtil.toJsonStr(execution.getArgs()));
|
processTask.setVariable(JSONUtil.toJsonStr(execution.getArgs()));
|
||||||
processTask.setCreatedAt(now);
|
processTask.setCreatedAt(now);
|
||||||
processTask.setUpdatedAt(now);
|
processTask.setUpdatedAt(now);
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ public class ProcessTaskVO extends ProcessTask {
|
|||||||
|
|
||||||
private List<JSONObject> taskActorList;
|
private List<JSONObject> taskActorList;
|
||||||
|
|
||||||
|
// 任务参与者
|
||||||
|
private List<JSONObject> taskOperatorList;
|
||||||
|
|
||||||
// @Schema(description = "当前用户是否可执行")
|
// @Schema(description = "当前用户是否可执行")
|
||||||
private boolean executable;
|
private boolean executable;
|
||||||
// @Schema(description = "节点定义信息")
|
// @Schema(description = "节点定义信息")
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -6,8 +6,6 @@
|
|||||||
<div class="title-section">
|
<div class="title-section">
|
||||||
<h2 class="page-title">{{ pageTitle }}</h2>
|
<h2 class="page-title">{{ pageTitle }}</h2>
|
||||||
<div class="page-breadcrumb">
|
<div class="page-breadcrumb">
|
||||||
<!-- <span>工作流管理</span>-->
|
|
||||||
<!-- <span class="separator">></span>-->
|
|
||||||
<span>{{ isNewApplication ? "发起申请" : "任务处理" }}</span>
|
<span>{{ isNewApplication ? "发起申请" : "任务处理" }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -27,7 +25,7 @@
|
|||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<h3 class="panel-title">流程信息</h3>
|
<h3 class="panel-title">流程信息</h3>
|
||||||
<div class="panel-actions">
|
<div class="panel-actions">
|
||||||
<el-button size="small" type="text" @click="showProcessDiagram" v-if="canShowDiagram">
|
<el-button size="small" type="text" @click="showProcessDiagram" v-if="isNewApplication">
|
||||||
<i class="el-icon-view"></i>
|
<i class="el-icon-view"></i>
|
||||||
查看流程图
|
查看流程图
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -36,14 +34,16 @@
|
|||||||
<div class="panel-content">
|
<div class="panel-content">
|
||||||
<div class="info-table">
|
<div class="info-table">
|
||||||
<!-- 新申请场景 -->
|
<!-- 新申请场景 -->
|
||||||
<template v-if="isNewApplication || (processInstance && processInstance.state === 30)">
|
<template v-if="isNewApplication">
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<div class="info-label">流程名称:</div>
|
<div class="info-label">流程名称:</div>
|
||||||
<div class="info-value">{{ processDefinition.displayName || processDefinition.name }}</div>
|
<div class="info-value">{{ processDefinition.displayName }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<div class="info-label">流程说明:</div>
|
<div class="info-label">流程说明:</div>
|
||||||
<div class="info-value">{{ processDefinition.description }}</div>
|
<div class="info-value">
|
||||||
|
<div v-html="processDefinition.description"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -61,6 +61,12 @@
|
|||||||
<div class="info-label">发起时间:</div>
|
<div class="info-label">发起时间:</div>
|
||||||
<div class="info-value">{{ formatDate(processInstance.createdAt) }}</div>
|
<div class="info-value">{{ formatDate(processInstance.createdAt) }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<div class="info-label">流程进度:</div>
|
||||||
|
<div class="info-value">
|
||||||
|
<span @click="showProcessDiagram" style="color: var(--color-primary); cursor: pointer">查看流程图</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -82,20 +88,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表单处理区域 -->
|
<!-- 表单处理区域 -->
|
||||||
<div
|
<div class="form-panel" v-if="isNewApplication || todoTasks.map((v) => v.id).includes(taskId)">
|
||||||
class="form-panel"
|
|
||||||
v-if="isNewApplication || (processInstance && processInstance.state === 30) || todoTasks.map((v) => v.id).includes(taskId)"
|
|
||||||
>
|
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<h3 class="panel-title">{{ formPanelTitle }}</h3>
|
<h3 class="panel-title">{{ formPanelTitle }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-content">
|
<div class="panel-content">
|
||||||
<!-- 新申请表单 -->
|
<!-- 新申请表单 -->
|
||||||
<div
|
<div v-if="isNewApplication" id="application-form-container" class="form-content">
|
||||||
v-if="isNewApplication || (processInstance && processInstance.state === 30)"
|
|
||||||
id="application-form-container"
|
|
||||||
class="form-content"
|
|
||||||
>
|
|
||||||
<div v-if="pjaxLoading.apply" class="loading-state">
|
<div v-if="pjaxLoading.apply" class="loading-state">
|
||||||
<i class="el-icon-loading"></i>
|
<i class="el-icon-loading"></i>
|
||||||
<span>正在加载申请表单...</span>
|
<span>正在加载申请表单...</span>
|
||||||
@@ -191,6 +190,7 @@ class PjaxSync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建全局实例
|
// 创建全局实例
|
||||||
const pjaxSync = new PjaxSync()
|
const pjaxSync = new PjaxSync()
|
||||||
|
|
||||||
@@ -289,7 +289,7 @@ module.exports = {
|
|||||||
// 表单面板标题
|
// 表单面板标题
|
||||||
formPanelTitle() {
|
formPanelTitle() {
|
||||||
if (this.isNewApplication) {
|
if (this.isNewApplication) {
|
||||||
return "申请表单"
|
return "填写申请"
|
||||||
} else if (this.shouldShowTaskForm) {
|
} else if (this.shouldShowTaskForm) {
|
||||||
return this.currentTask.displayName || "任务表单"
|
return this.currentTask.displayName || "任务表单"
|
||||||
} else if (this.shouldShowHistoryProcess) {
|
} else if (this.shouldShowHistoryProcess) {
|
||||||
@@ -301,9 +301,7 @@ module.exports = {
|
|||||||
|
|
||||||
// 是否显示历史办理过程
|
// 是否显示历史办理过程
|
||||||
shouldShowHistoryProcess() {
|
shouldShowHistoryProcess() {
|
||||||
// debugger
|
return this.instanceId !== null
|
||||||
// return this.businessId && this.isTaskInProgress && !this.isFirstTaskNode
|
|
||||||
return true
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 是否显示任务表单
|
// 是否显示任务表单
|
||||||
@@ -311,11 +309,6 @@ module.exports = {
|
|||||||
return this.taskId != null
|
return this.taskId != null
|
||||||
},
|
},
|
||||||
|
|
||||||
// 是否可以显示流程图
|
|
||||||
canShowDiagram() {
|
|
||||||
return (this.isNewApplication && this.processDefinition.id) || (this.isExistingProcess && this.processInstance.processId)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 判断是否为新申请
|
// 判断是否为新申请
|
||||||
isNewApplication() {
|
isNewApplication() {
|
||||||
return !this.taskId && !this.instanceId && this.defineKey
|
return !this.taskId && !this.instanceId && this.defineKey
|
||||||
@@ -338,10 +331,11 @@ module.exports = {
|
|||||||
|
|
||||||
// 流程图预览URL
|
// 流程图预览URL
|
||||||
processDesignUrl() {
|
processDesignUrl() {
|
||||||
|
debugger
|
||||||
if (this.isNewApplication && this.processDefinition.id) {
|
if (this.isNewApplication && this.processDefinition.id) {
|
||||||
return `/flow/define/preview?id=${this.processDefinition.id}`
|
return `/flow/define/preview?defineId=${this.processDefinition.id}`
|
||||||
} else if (this.isExistingProcess && this.processInstance.processId) {
|
} else if (this.isExistingProcess && this.processInstance.processDefineId) {
|
||||||
return `/flow/define/preview?id=${this.processInstance.processId}`
|
return `/flow/define/preview?defineId=${this.processInstance.processDefineId}&instanceId=${this.instanceId}`
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -474,6 +468,7 @@ module.exports = {
|
|||||||
|
|
||||||
// 显示流程图
|
// 显示流程图
|
||||||
showProcessDiagram() {
|
showProcessDiagram() {
|
||||||
|
debugger
|
||||||
if (this.processDesignUrl) {
|
if (this.processDesignUrl) {
|
||||||
this.designUrl = this.processDesignUrl
|
this.designUrl = this.processDesignUrl
|
||||||
this.designVisible = true
|
this.designVisible = true
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
<!--#
|
|
||||||
layout("/layouts/v4/baseLayout.html"){
|
|
||||||
#-->
|
|
||||||
|
|
||||||
<div id="approvalApp" v-cloak>
|
|
||||||
<snaker-flow
|
|
||||||
:task_id="taskId"
|
|
||||||
:instance_id="instanceId"
|
|
||||||
:business_id="businessId"
|
|
||||||
:pjax_config="{
|
|
||||||
push: false,
|
|
||||||
replace: false,
|
|
||||||
timeout: 10000
|
|
||||||
}"
|
|
||||||
></snaker-flow>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
new Vue({
|
|
||||||
el: "#approvalApp",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
taskId: null,
|
|
||||||
instanceId: null,
|
|
||||||
businessId: null,
|
|
||||||
formConfig: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleTaskSubmitted() {},
|
|
||||||
handleCancel() {
|
|
||||||
window.history.back()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.taskId = new URLSearchParams(window.location.search).get("taskId")
|
|
||||||
this.instanceId = new URLSearchParams(window.location.search).get("instanceId")
|
|
||||||
this.businessId = new URLSearchParams(window.location.search).get("businessId")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!--#
|
|
||||||
}
|
|
||||||
#-->
|
|
||||||
@@ -22,16 +22,13 @@ layout("/layouts/platform.html"){
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<table-tool>
|
<table-tool></table-tool>
|
||||||
</table-tool>
|
|
||||||
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
|
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
|
||||||
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
|
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
|
||||||
<el-table-column prop="displayName" label="流程定义名称"></el-table-column>
|
<el-table-column prop="displayName" label="流程定义名称"></el-table-column>
|
||||||
<el-table-column prop="name" label="流程定义编码"></el-table-column>
|
<el-table-column prop="name" label="流程定义编码"></el-table-column>
|
||||||
<el-table-column prop="categoryName" label="流程分类">
|
<el-table-column prop="categoryName" label="流程分类">
|
||||||
<template slot-scope="{row}">{{categoryOptions.find(item => item.id ===
|
<template slot-scope="{row}">{{categoryOptions.find(item => item.id === row.category)?.categoryName}}</template>
|
||||||
row.category)?.categoryName}}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="version" label="版本号"></el-table-column>
|
<el-table-column prop="version" label="版本号"></el-table-column>
|
||||||
<el-table-column prop="state" label="状态">
|
<el-table-column prop="state" label="状态">
|
||||||
@@ -44,12 +41,9 @@ layout("/layouts/platform.html"){
|
|||||||
<el-table-column label="操作" fixed="right" width="350px">
|
<el-table-column label="操作" fixed="right" width="350px">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<el-button type="primary" size="mini" @click="onView(row)">查看</el-button>
|
<el-button type="primary" size="mini" @click="onView(row)">查看</el-button>
|
||||||
<el-button v-if="row.state===1" type="danger" size="mini" @click="onDisable(row)">停用
|
<el-button v-if="row.state===1" type="danger" size="mini" @click="onDisable(row)">停用</el-button>
|
||||||
</el-button>
|
<el-button v-if="row.state===0" type="primary" size="mini" @click="onEnable(row)">启用</el-button>
|
||||||
<el-button v-if="row.state===0" type="primary" size="mini" @click="onEnable(row)">启用
|
<el-button v-if="row.state===0" type="danger" size="mini" @click="onDelete(row)">删除</el-button>
|
||||||
</el-button>
|
|
||||||
<el-button v-if="row.state===0" type="danger" size="mini" @click="onDelete(row)">删除
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -59,11 +53,9 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<el-dialog title="查看流程图" :visible.sync="designVisible" class="design-dialog" width="80%">
|
<el-dialog title="查看流程图" :visible.sync="designVisible" class="design-dialog" width="80%">
|
||||||
<div style="height: calc(100vh - 150px); width: 100%">
|
<div style="height: calc(100vh - 150px); width: 100%">
|
||||||
<iframe v-if="designVisible" :src="designUrl" frameborder="0" height="100%"
|
<iframe v-if="designVisible" :src="designUrl" frameborder="0" height="100%" style="height: 100%; width: inherit"></iframe>
|
||||||
style="height: 100%; width: inherit"></iframe>
|
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -80,7 +72,7 @@ layout("/layouts/platform.html"){
|
|||||||
methods: {
|
methods: {
|
||||||
onView(row) {
|
onView(row) {
|
||||||
this.designVisible = true
|
this.designVisible = true
|
||||||
this.designUrl = "/flow/define/preview?id=" + row.id
|
this.designUrl = "/flow/define/preview?defineId=" + row.id
|
||||||
},
|
},
|
||||||
|
|
||||||
onDisable(row) {
|
onDisable(row) {
|
||||||
@@ -89,7 +81,7 @@ layout("/layouts/platform.html"){
|
|||||||
cancelButtonText: "取消",
|
cancelButtonText: "取消",
|
||||||
type: "warning"
|
type: "warning"
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$axios.post("/flow/define/disable", { id: row.id }).then(res => {
|
this.$axios.post("/flow/define/disable", { id: row.id }).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.$message.success("停用成功")
|
this.$message.success("停用成功")
|
||||||
this.pageData()
|
this.pageData()
|
||||||
@@ -103,7 +95,7 @@ layout("/layouts/platform.html"){
|
|||||||
cancelButtonText: "取消",
|
cancelButtonText: "取消",
|
||||||
type: "warning"
|
type: "warning"
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$axios.post("/flow/define/enable", { id: row.id }).then(res => {
|
this.$axios.post("/flow/define/enable", { id: row.id }).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.$message.success("启用成功")
|
this.$message.success("启用成功")
|
||||||
this.pageData()
|
this.pageData()
|
||||||
|
|||||||
@@ -16,50 +16,332 @@
|
|||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/style/index.css" />
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/style/index.css" />
|
||||||
<script src="/assets/platform/plugins/snaker/SnakerflowDesigner.umd.js"></script>
|
<script src="/assets/platform/plugins/snaker/SnakerflowDesigner.umd.js"></script>
|
||||||
<style>
|
<style>
|
||||||
#app {
|
#snaker-flow-preview {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.approval-card {
|
||||||
|
position: absolute;
|
||||||
|
width: 320px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #d9e3f0;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||||
|
z-index: 1000;
|
||||||
|
font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||||
|
transform: translate(10px, 10px);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-container {
|
||||||
|
border-bottom: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-header {
|
||||||
|
display: flex;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
padding: 8px 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-right: 1px solid #e8e8e8;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
background: #fafafa;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active {
|
||||||
|
background: #fff;
|
||||||
|
color: #333;
|
||||||
|
border-bottom: 2px solid #1890ff;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item:hover {
|
||||||
|
background: #f0f0f0;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片标题栏(OA风格顶部色条) */
|
||||||
|
.approval-card .card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: #1a73e8;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.approval-card .card-header h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.approval-card .card-header button {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
border: none;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.approval-card .card-header button:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片内容区域 */
|
||||||
|
.approval-card .card-body {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 信息行样式 */
|
||||||
|
.approval-card .info-row {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.approval-card .info-label {
|
||||||
|
width: 80px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.approval-card .info-value {
|
||||||
|
flex: 1;
|
||||||
|
color: #333;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!* 分隔线 *!*/
|
||||||
|
/*.approval-card .divider {*/
|
||||||
|
/* height: 1px;*/
|
||||||
|
/* background: #f0f0f0;*/
|
||||||
|
/* margin: 12px 0;*/
|
||||||
|
/*}*/
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div id="snaker-flow-preview">
|
||||||
<snaker-flow-designer ref="designer"
|
<snaker-flow-designer
|
||||||
|
ref="designer"
|
||||||
v-model="flowData"
|
v-model="flowData"
|
||||||
:show-doc="false"
|
:show-doc="false"
|
||||||
:viewer="true"
|
:viewer="true"
|
||||||
node-render-type="html"
|
node-render-type="html"
|
||||||
:wf-config="{
|
:high-light="highLight"
|
||||||
showHelp: false,
|
|
||||||
}"
|
|
||||||
:config="{
|
|
||||||
grid:{ size: 25,visible: true,type: 'dot',config:{color: '#ababab',thickness: 1}}
|
|
||||||
}"
|
|
||||||
></snaker-flow-designer>
|
></snaker-flow-designer>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="showApprovalCard"
|
||||||
|
class="approval-card"
|
||||||
|
:style="{
|
||||||
|
left: cardPosition.x+'px',
|
||||||
|
top: cardPosition.y+'px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<h3>详情</h3>
|
||||||
|
<button @click="closeCard">×</button>
|
||||||
|
</div>
|
||||||
|
<!-- Tab切换 -->
|
||||||
|
<div class="tab-container" v-if="approvalInfos.length > 1">
|
||||||
|
<div class="tab-header">
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in approvalInfos"
|
||||||
|
:key="index"
|
||||||
|
class="tab-item"
|
||||||
|
:class="{active: activeTabIndex === index}"
|
||||||
|
@click="activeTabIndex = index"
|
||||||
|
>
|
||||||
|
记录{{index + 1}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div v-for="(approvalInfo, index) in approvalInfos" :key="index" v-show="activeTabIndex === index">
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">节点类型:</span>
|
||||||
|
<span class="info-value">{{approvalInfo.displayName}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">审批人:</span>
|
||||||
|
<span class="info-value" v-if="currentNode.id === 'startTask'">
|
||||||
|
{{approvalInfo.ext?.initiatorName}}({{approvalInfo.ext?.initiatorAccount}})
|
||||||
|
</span>
|
||||||
|
<span class="info-value" v-else>{{approvalInfo.taskFormData.userName}}({{approvalInfo.taskFormData?.loginName}})</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">审核状态:</span>
|
||||||
|
<span class="info-value">{{getTaskStateText(approvalInfo.taskState)}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">提交结果:</span>
|
||||||
|
<span class="info-value">{{getSubmitTypeText(approvalInfo.ext.submitType)}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">提交意见:</span>
|
||||||
|
<span class="info-value">{{approvalInfo.taskFormData.opinion}}</span>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="divider"></div>-->
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">提交时间:</span>
|
||||||
|
<span class="info-value">{{approvalInfo.finishTime}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
Vue.use(SnakerflowDesigner.default)
|
Vue.use(SnakerflowDesigner.default)
|
||||||
new Vue({
|
new Vue({
|
||||||
el: "#app",
|
el: "#snaker-flow-preview",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
id: "${id!}",
|
// 流程定义ID
|
||||||
flowData: {}
|
defineId: "${defineId!}",
|
||||||
|
// 流程实例ID
|
||||||
|
instanceId: "${instanceId!}",
|
||||||
|
// 流程定义数据
|
||||||
|
flowData: {},
|
||||||
|
// 高亮数据
|
||||||
|
highLight: {},
|
||||||
|
// 历史审批记录
|
||||||
|
hisApproval: [],
|
||||||
|
// 展示已审核信息
|
||||||
|
showApprovalCard: false,
|
||||||
|
// 审批信息卡片位置
|
||||||
|
cardPosition: { x: 0, y: 0 },
|
||||||
|
// 当前节点
|
||||||
|
currentNode: [],
|
||||||
|
// 审批信息数组
|
||||||
|
approvalInfos: [],
|
||||||
|
// 当前选中的tab索引
|
||||||
|
activeTabIndex: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
// approvalInfo() {
|
||||||
|
// if (this.currentNode) {
|
||||||
|
// return this.hisApproval.find((item) => item.taskName === this.currentNode.id)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getDetail() {
|
getDetail() {
|
||||||
$.get("/flow/define/detail", { id: this.id }).then((res) => {
|
$.get("/flow/define/detail", { id: this.defineId }).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.flowData = res.data.content
|
this.flowData = res.data.content
|
||||||
|
this.initNodeEvent()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
getHighLight() {
|
||||||
|
$.get("/flow/common/instanceHighLight", { instanceId: this.instanceId }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.highLight = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getHisApproval() {
|
||||||
|
$.get("/flow/common/approvalRecord", { instanceId: this.instanceId }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.hisApproval = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
initNodeEvent() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
console.log(this.$refs.designer.lf.graphModel.eventCenter)
|
||||||
|
this.$refs.designer.lf.graphModel.eventCenter.on("node:click", ({ e, data }) => {
|
||||||
|
console.log(data)
|
||||||
|
console.log(e)
|
||||||
|
|
||||||
|
// 获取点击位置(考虑页面滚动情况)
|
||||||
|
const scrollX = window.scrollX || window.pageXOffset
|
||||||
|
const scrollY = window.scrollY || window.pageYOffset
|
||||||
|
|
||||||
|
this.cardPosition = {
|
||||||
|
x: e.clientX + scrollX,
|
||||||
|
y: e.clientY + scrollY
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type !== "snaker:task") return
|
||||||
|
|
||||||
|
const approvalInfos = this.hisApproval.filter((item) => item.taskName === data.id && item.taskState === 20)
|
||||||
|
|
||||||
|
if (approvalInfos && approvalInfos.length > 0) {
|
||||||
|
this.approvalInfos = approvalInfos
|
||||||
|
this.currentNode = data
|
||||||
|
this.activeTabIndex = 0
|
||||||
|
this.showApprovalCard = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$refs.designer.lf.graphModel.eventCenter.on("blank:click", (args) => {
|
||||||
|
this.closeCard()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
closeCard() {
|
||||||
|
this.showApprovalCard = false
|
||||||
|
this.activeTabIndex = 0
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取任务状态文本
|
||||||
|
getTaskStateText(taskState) {
|
||||||
|
const stateMap = {
|
||||||
|
10: "进行中",
|
||||||
|
20: "已完成",
|
||||||
|
30: "已撤回"
|
||||||
|
}
|
||||||
|
return stateMap[taskState] || taskState
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取提交结果文本
|
||||||
|
getSubmitTypeText(submitType) {
|
||||||
|
const typeMap = {
|
||||||
|
0: "发起申请",
|
||||||
|
1: "同意申请",
|
||||||
|
2: "拒绝申请",
|
||||||
|
3: "退回上一步",
|
||||||
|
4: "跳转",
|
||||||
|
5: "重新提交",
|
||||||
|
6: "退回发起人",
|
||||||
|
20: "拒绝申请"
|
||||||
|
}
|
||||||
|
return typeMap[submitType] || submitType
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.id) {
|
if (this.defineId) {
|
||||||
this.getDetail()
|
this.getDetail()
|
||||||
}
|
}
|
||||||
|
if (this.instanceId) {
|
||||||
|
this.getHighLight()
|
||||||
|
this.getHisApproval()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-card>
|
</el-card>
|
||||||
</guava>
|
</guava>
|
||||||
|
|
||||||
<el-dialog :title="formData.id ? '编辑' : '新增'" :visible.sync="dialogVisible" width="800px">
|
<el-dialog :title="formData.id ? '编辑' : '新增'" :visible.sync="dialogVisible" width="70%">
|
||||||
<el-form :model="formData" ref="formRef" label-width="120px">
|
<el-form :model="formData" ref="formRef" label-width="120px">
|
||||||
<el-form-item label="流程定义名称" prop="displayName"
|
<el-form-item label="流程定义名称" prop="displayName"
|
||||||
:rules="{ required: true, message: '请输入流程定义名称', trigger: 'blur' }">
|
:rules="{ required: true, message: '请输入流程定义名称', trigger: 'blur' }">
|
||||||
@@ -87,6 +87,9 @@ layout("/layouts/platform.html"){
|
|||||||
<el-input maxlength="100" placeholder="图标" v-model="formData.icon"></el-input>
|
<el-input maxlength="100" placeholder="图标" v-model="formData.icon"></el-input>
|
||||||
<i :class="formData.icon" v-if="formData.icon"></i>
|
<i :class="formData.icon" v-if="formData.icon"></i>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="说明" prop="description">
|
||||||
|
<text-editor v-model="formData.description"></text-editor>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
|
||||||
<title>流程设计器</title>
|
|
||||||
<script src="/assets/platform/plugins/vue/vue.js"></script>
|
|
||||||
<script src="/assets/platform/plugins/jquery/jquery.js"></script>
|
|
||||||
<script src="/assets/platform/plugins/element-ui/lib/index.js"></script>
|
|
||||||
<link rel="stylesheet" href="https://cdn.staticfile.net/element-ui/2.15.14/theme-chalk/index.css" />
|
|
||||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/index.css" />
|
|
||||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/override.css" />
|
|
||||||
<!-- 引入 core 包和对应 css-->
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/logic-flow.js"></script>
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/style/index.css" />
|
|
||||||
<script src="/assets/platform/plugins/snaker/SnakerflowDesigner.umd.js"></script>
|
|
||||||
<style>
|
|
||||||
#app {
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app">
|
|
||||||
<snaker-flow-designer ref="designer"
|
|
||||||
v-model="flowData"
|
|
||||||
@on-save="handleSave"
|
|
||||||
:show-doc="false"
|
|
||||||
node-render-type="html"
|
|
||||||
:extendPropertyKeys="[
|
|
||||||
'candidateUsers',
|
|
||||||
'candidateGroups',
|
|
||||||
'candidateHandler',
|
|
||||||
'assigneeText',
|
|
||||||
]"
|
|
||||||
></snaker-flow-designer>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
Vue.use(SnakerflowDesigner.default)
|
|
||||||
new Vue({
|
|
||||||
el: "#app",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
id: "${id!}",
|
|
||||||
flowData: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleSave(val) {
|
|
||||||
console.log(val)
|
|
||||||
const data = {
|
|
||||||
processDesignId: this.id,
|
|
||||||
...val.json
|
|
||||||
}
|
|
||||||
$.post("/flow/design/updateDesign", { json: JSON.stringify(data) }).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
window.parent.postMessage("success")
|
|
||||||
} else {
|
|
||||||
window.parent.postMessage("error")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getDetail() {
|
|
||||||
$.get("/flow/design/detail", { id: this.id }).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
this.flowData = res.data.jsonObject
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (this.id) {
|
|
||||||
this.getDetail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</html>
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>流程状态</title>
|
|
||||||
<link rel="stylesheet" href="/assets/platform/plugins/snaker/snaker.css" type="text/css" media="all"/>
|
|
||||||
<link rel="stylesheet" href="/assets/platform/plugins/snaker/style.css" type="text/css" media="all"/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table class="properties_all" align="center" border="1" cellpadding="0" cellspacing="0" style="margin-top: 0px">
|
|
||||||
<div id="snakerflow"
|
|
||||||
style="border: 1px solid #d2dde2; margin-top:10px; margin-left:10px; margin-bottom:10px; width:98%;">
|
|
||||||
</div>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<script src="/assets/platform/plugins/jquery/jquery.js"></script>
|
|
||||||
<script src="/assets/platform/plugins/snaker/raphael-min.js" type="text/javascript"></script>
|
|
||||||
<script src="/assets/platform/plugins/snaker/jquery-ui-1.8.4.custom/js/jquery.min.js" type="text/javascript"></script>
|
|
||||||
<script src="/assets/platform/plugins/snaker/jquery-ui-1.8.4.custom/js/jquery-ui.min.js" type="text/javascript"></script>
|
|
||||||
<script src="/assets/platform/plugins/snaker/dialog.js" type="text/javascript"></script>
|
|
||||||
<script src="/assets/platform/plugins/snaker/snaker.designer.js" type="text/javascript"></script>
|
|
||||||
<script src="/assets/platform/plugins/snaker/snaker.model.js" charset="utf-8" type="text/javascript"></script>
|
|
||||||
<script src="/assets/platform/plugins/snaker/snaker.editors.js" type="text/javascript"></script>
|
|
||||||
<script>
|
|
||||||
|
|
||||||
const orderId = "${orderId!}"
|
|
||||||
const processId = "${processId!}"
|
|
||||||
|
|
||||||
$(function(){
|
|
||||||
$.post("/snakerflow/define/process/json", { processId, orderId }).then(res => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
display(res.data.process, res.data.state)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
function display(process, state) {
|
|
||||||
/** view*/
|
|
||||||
$('#snakerflow').snakerflow($.extend(true, {
|
|
||||||
basePath: "/assets/platform/plugins/snaker/",
|
|
||||||
// ctxPath: easyAdmin.GetAdminServerUrl(),
|
|
||||||
// token: easyAdmin.GetTokenQueryString(),
|
|
||||||
orderId: orderId,
|
|
||||||
restore: eval("(" + process + ")"),
|
|
||||||
editable: false
|
|
||||||
}, eval("(" + state + ")")
|
|
||||||
));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<div id="suggestion-box-view">
|
<div id="suggestion-box-view">
|
||||||
<!-- <el-form ref="formRef" label-width="0" label-suffix=":" class="flow-task-form">-->
|
<!-- <el-form ref="formRef" label-width="0" label-suffix=":" class="flow-task-form">-->
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border class="flow-task-form">
|
||||||
<el-descriptions-item label="姓名">{{viewData.userName}}</el-descriptions-item>
|
<el-descriptions-item label="姓名">{{viewData.userName}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item>
|
<el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="单位">{{viewData.unitName}}</el-descriptions-item>
|
<el-descriptions-item label="单位">{{viewData.unitName}}</el-descriptions-item>
|
||||||
|
|||||||
Reference in New Issue
Block a user