Commit e729697c authored by 赵啸非's avatar 赵啸非

一件事统一办

parent c0e4f6c4
package com.mortals.xhx.common.pdu.flow;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* 工作流定义前端实体类
*
* @author: finegirl
* @date: 2021/7/31 23:38
*/
@Getter
@Setter
@ApiModel("工作流定义前端实体类")
public class DefinitionVoPdu implements Serializable {
@ApiModelProperty("流程定义ID")
private String deployId;
@ApiModelProperty("状态")
private Integer state;
}
package com.mortals.xhx.common.pdu.flow;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class FlowTaskNotifyPdu implements Serializable {
/**
* 用户审核列表(一个或者多个)
*/
private List<String> userNameList;
/**
* taskId
*/
private String taskId;
/**
* taskName
*/
private String taskName;
/**
* 租户Id
*/
private String tenantId;
}
package com.mortals.xhx.utils;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.mortals.framework.util.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Random;
/**
* 二维码工具类
*
*/
public class QRCodeUtil {
@SuppressWarnings("unused")
private static Log logger = LogFactory.getLog(QRCodeUtil.class);
private static final String CHARSET = "utf-8";
private static final String FORMAT = "JPG";
// 二维码尺寸
private static final int QRCODE_SIZE = 300;
// LOGO宽度
private static final int LOGO_WIDTH = 60;
// LOGO高度
private static final int LOGO_HEIGHT = 60;
private static BufferedImage createImage(String content, String logoPath, boolean needCompress) throws Exception {
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
if (logoPath == null || "".equals(logoPath)) {
return image;
}
// 插入图片
QRCodeUtil.insertImage(image, logoPath, needCompress);
return image;
}
/**
* 插入LOGO
*
* @param source
* 二维码图片
* @param logoPath
* LOGO图片地址
* @param needCompress
* 是否压缩
* @throws Exception
*/
private static void insertImage(BufferedImage source, String logoPath, boolean needCompress) throws Exception {
File file = new File(logoPath);
if (!file.exists()) {
throw new Exception("logo file not found.");
}
Image src = ImageIO.read(new File(logoPath));
int width = src.getWidth(null);
int height = src.getHeight(null);
if (needCompress) { // 压缩LOGO
if (width > LOGO_WIDTH) {
width = LOGO_WIDTH;
}
if (height > LOGO_HEIGHT) {
height = LOGO_HEIGHT;
}
Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.drawImage(image, 0, 0, null); // 绘制缩小后的图
g.dispose();
src = image;
}
// 插入LOGO
Graphics2D graph = source.createGraphics();
int x = (QRCODE_SIZE - width) / 2;
int y = (QRCODE_SIZE - height) / 2;
graph.drawImage(src, x, y, width, height, null);
Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
graph.setStroke(new BasicStroke(3f));
graph.draw(shape);
graph.dispose();
}
/**
* 生成二维码(内嵌LOGO) 二维码文件名随机,文件名可能会有重复
*
* @param content
* 内容
* @param logoPath
* LOGO地址
* @param destPath
* 存放目录
* @param needCompress
* 是否压缩LOGO
* @throws Exception
*/
public static String encode(String content, String logoPath, String destPath, boolean needCompress) throws Exception {
BufferedImage image = QRCodeUtil.createImage(content, logoPath, needCompress);
mkdirs(destPath);
String fileName = new Random().nextInt(99999999) + "." + FORMAT.toLowerCase();
ImageIO.write(image, FORMAT, new File(destPath + "/" + fileName));
return fileName;
}
/**
* 生成二维码(内嵌LOGO) 调用者指定二维码文件名
*
* @param content
* 内容
* @param logoPath
* LOGO地址
* @param destPath
* 存放目录
* @param fileName
* 二维码文件名
* @param needCompress
* 是否压缩LOGO
* @throws Exception
*/
public static String encode(String content, String logoPath, String destPath, String fileName, boolean needCompress) throws Exception {
BufferedImage image = QRCodeUtil.createImage(content, logoPath, needCompress);
mkdirs(destPath);
fileName = fileName.substring(0, fileName.indexOf(".") > 0 ? fileName.indexOf(".") : fileName.length()) + "." + FORMAT.toLowerCase();
ImageIO.write(image, FORMAT, new File(destPath + "/" + fileName));
return fileName;
}
/**
* 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir. (mkdir如果父目录不存在则会抛出异常)
*
* @param destPath
* 存放目录
*/
public static void mkdirs(String destPath) {
File file = new File(destPath);
if (!file.exists() && !file.isDirectory()) {
file.mkdirs();
}
}
/**
* 生成二维码
*
* @param content
* 内容
* @param destPath
* 存储地址
* @throws Exception
*/
public static String encode(String content, String destPath) throws Exception {
return QRCodeUtil.encode(content, null, destPath, false);
}
/**
* 生成二维码(内嵌LOGO)
*
* @param content
* 内容
* @param logoPath
* LOGO地址
* @param output
* 输出流
* @param needCompress
* 是否压缩LOGO
* @throws Exception
*/
public static void encode(String content, String logoPath, OutputStream output, boolean needCompress) throws Exception {
BufferedImage image = QRCodeUtil.createImage(content, logoPath, needCompress);
ImageIO.write(image, FORMAT, output);
}
/**
* 生成二维码
*
* @param content
* 内容
* @param output
* 输出流
* @throws Exception
*/
public static void encode(String content, OutputStream output) throws Exception {
QRCodeUtil.encode(content, null, output, false);
}
/**
* 将二维码转换成base64字符串
*
* @param content
* @param logoPath
* @param needCompress
* @return
* @throws Exception
*/
public static String encode(String content, String logoPath, boolean needCompress) throws Exception {
BufferedImage image = QRCodeUtil.createImage(content, logoPath, needCompress);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, FORMAT, outputStream);
return Base64.encode(outputStream.toByteArray());
}
public static byte[] encodeToBytes(String content, String logoPath, boolean needCompress) throws Exception {
BufferedImage image = QRCodeUtil.createImage(content, logoPath, needCompress);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, FORMAT, outputStream);
return outputStream.toByteArray();
}
/**
* 解析二维码
*
* @param file
* 二维码图片
* @return
* @throws Exception
*/
public static String decode(File file) throws Exception {
BufferedImage image;
image = ImageIO.read(file);
if (image == null) {
return null;
}
BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result;
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
result = new MultiFormatReader().decode(bitmap, hints);
String resultStr = result.getText();
return resultStr;
}
/**
* 解析二维码
*
* @param path
* 二维码图片地址
* @return
* @throws Exception
*/
public static String decode(String path) throws Exception {
return QRCodeUtil.decode(new File(path));
}
/**
* 解析二维码
*
* @param inputStream
* 二维码图片
* @return
* @throws Exception
*/
public static String decode(InputStream inputStream) throws Exception {
BufferedImage image = ImageIO.read(inputStream);
if (image == null) {
return null;
}
BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result;
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
result = new MultiFormatReader().decode(bitmap, hints);
String resultStr = result.getText();
return resultStr;
}
public static void main(String[] args) throws Exception {
// String text =
// "https://mp.weixin.qq.com/a/~~qgbFJlgjTPg~wAWUfsCV6ni-VdasDWFqJg~~";
// QRCodeUtil.encode(text, "", "e:\\", "qrcodeTest", true);
// System.out.println(QRCodeUtil.decode("d:\\777.png"));
System.out.println(QRCodeUtil.decode("e:\\4.png"));
// https://mp.weixin.qq.com/a/~~7e4OEtdDP-A~N-WJjuAzvca5sdEzbkQ9hA~~
// https://mp.weixin.qq.com/a/~~hopFMAkydTI~RWT6ZsVRPo0jIZzPgXGVlg~~ 2
// https://mp.weixin.qq.com/a/~~GwiYx6fLcTQ~gglQBO3FfzX6SuWe2z65rg~~ 3
// https://mp.weixin.qq.com/a/~~UjQMf5HyHLM~8SjrWsLXuc-3XtoAgFPEIw~~ 4
// System.out.println(QRCodeUtil.encode(text,null, true).length());
}
}
package com.mortals.xhx.utils.stream.messaging;
/**
* @author karlhoo
*/
public interface ProcessTaskProcessor extends ProcessTaskSink, ProcessTaskSource {
}
package com.mortals.xhx.utils.stream.messaging;
import org.springframework.cloud.stream.annotation.Input;
import org.springframework.messaging.SubscribableChannel;
/**
* @author karlhoo
*/
public interface ProcessTaskSink {
String INPUT = "process-task-input";
@Input(ProcessTaskSink.INPUT)
SubscribableChannel input();
}
package com.mortals.xhx.utils.stream.messaging;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
/**
* @author karlhoo
*/
public interface ProcessTaskSource {
String OUTPUT = "process-task-output";
@Output(ProcessTaskSource.OUTPUT)
MessageChannel output();
}
package com.mortals.xhx.utils.stream.service;
import org.springframework.messaging.MessageChannel;
import org.springframework.validation.annotation.Validated;
/**
* 发送消息到消息中间件
*
* @author karlhoo
*/
@Validated
public interface IMessageService {
/**
* 向指定通道发送消息
*
* @param messageChannel
* @param message
* @return true: 成功
*/
boolean sendMessage( MessageChannel messageChannel, String message);
/**
* 向指定通道发送消息(带messageKey)
*
* @param messageChannel
* @param message
* @param messageKey
* @return true: 成功
*/
boolean sendMessage(MessageChannel messageChannel, String message, String messageKey);
}
package com.mortals.xhx.utils.stream.service.impl;
import com.mortals.xhx.utils.stream.service.IMessageService;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
/**
* @author karlhoo
*/
@CommonsLog
@Component
public class DefaultMessageServiceImpl implements IMessageService {
@Override
public boolean sendMessage(MessageChannel messageChannel, String message) {
return sendMessage(messageChannel, message, null);
}
@Override
public boolean sendMessage(MessageChannel messageChannel, String message, String messageKey) {
return sendMessage(messageChannel, MessageBuilder.withPayload(message).setHeader(KafkaHeaders.MESSAGE_KEY, messageKey == null ? messageKey : messageKey.getBytes()).build());
}
private boolean sendMessage(MessageChannel messageChannel, Message message) {
try {
return messageChannel.send(message);
} catch (Exception e) {
log.error(String.format("提交消息出错 messageChannel: %s, message: %s", messageChannel.toString(), message.getPayload()), e);
return false;
}
}
}
package com.mortals.flowable.common.config;
import com.sun.prism.paint.Color;
import org.flowable.bpmn.model.AssociationDirection;
import org.flowable.image.impl.DefaultProcessDiagramCanvas;
import java.awt.*;
import java.awt.geom.Line2D;
import java.awt.geom.RoundRectangle2D;
/**
* 自定义流程图
*
* @author: finegirl
* @date: 2021/7/31 12:06
* @description:
*/
public class MyDefaultProcessDiagramCanvas extends DefaultProcessDiagramCanvas {
//设置高亮线的颜色 这里我设置成绿色
protected static Color HIGHLIGHT_SEQUENCEFLOW_COLOR = Color.GREEN;
public MyDefaultProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
super(width, height, minX, minY, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
}
public MyDefaultProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType) {
super(width, height, minX, minY, imageType);
}
/**
* 画线颜色设置
*/
@Override
public void drawConnection(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, String connectionType,
AssociationDirection associationDirection, boolean highLighted, double scaleFactor) {
Paint originalPaint = g.getPaint();
Stroke originalStroke = g.getStroke();
g.setPaint(CONNECTION_COLOR);
if (connectionType.equals("association")) {
g.setStroke(ASSOCIATION_STROKE);
} else if (highLighted) {
//设置线的颜色
g.setPaint(originalPaint);
g.setStroke(HIGHLIGHT_FLOW_STROKE);
}
for (int i = 1; i < xPoints.length; i++) {
Integer sourceX = xPoints[i - 1];
Integer sourceY = yPoints[i - 1];
Integer targetX = xPoints[i];
Integer targetY = yPoints[i];
Line2D.Double line = new Line2D.Double(sourceX, sourceY, targetX, targetY);
g.draw(line);
}
if (isDefault) {
Line2D.Double line = new Line2D.Double(xPoints[0], yPoints[0], xPoints[1], yPoints[1]);
drawDefaultSequenceFlowIndicator(line, scaleFactor);
}
if (conditional) {
Line2D.Double line = new Line2D.Double(xPoints[0], yPoints[0], xPoints[1], yPoints[1]);
drawConditionalSequenceFlowIndicator(line, scaleFactor);
}
if (associationDirection == AssociationDirection.ONE || associationDirection == AssociationDirection.BOTH) {
Line2D.Double line = new Line2D.Double(xPoints[xPoints.length - 2], yPoints[xPoints.length - 2], xPoints[xPoints.length - 1], yPoints[xPoints.length - 1]);
drawArrowHead(line, scaleFactor);
}
if (associationDirection == AssociationDirection.BOTH) {
Line2D.Double line = new Line2D.Double(xPoints[1], yPoints[1], xPoints[0], yPoints[0]);
drawArrowHead(line, scaleFactor);
}
g.setPaint(originalPaint);
g.setStroke(originalStroke);
}
/**
* 高亮节点设置
*/
@Override
public void drawHighLight(int x, int y, int width, int height) {
Paint originalPaint = g.getPaint();
Stroke originalStroke = g.getStroke();
//设置高亮节点的颜色
g.setPaint(HIGHLIGHT_COLOR);
g.setStroke(THICK_TASK_BORDER_STROKE);
RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20);
g.draw(rect);
g.setPaint(originalPaint);
g.setStroke(originalStroke);
}
}
package com.mortals.flowable.common.constant;
/**
* 流程常量信息
*
* @author: finegirl
* @date: 2021/7/31 12:04
* @description:
*/
public class ProcessConstants {
/**
* 动态数据
*/
public static final String DATA_TYPE = "dynamic";
/**
* 单个审批人
*/
public static final String USER_TYPE_ASSIGNEE = "assignee";
/**
* 候选人
*/
public static final String USER_TYPE_USERS = "candidateUsers";
/**
* 审批组
*/
public static final String USER_TYPE_ROUPS = "candidateGroups";
/**
* 单个审批人
*/
public static final String PROCESS_APPROVAL = "approval";
/**
* 会签人员
*/
public static final String PROCESS_MULTI_INSTANCE_USER = "userList";
/**
* nameapace
*/
public static final String NAMASPASE = "http://flowable.org/bpmn";
/**
* 会签节点
*/
public static final String PROCESS_MULTI_INSTANCE = "multiInstance";
/**
* 自定义属性 dataType
*/
public static final String PROCESS_CUSTOM_DATA_TYPE = "dataType";
/**
* 自定义属性 userType
*/
public static final String PROCESS_CUSTOM_USER_TYPE = "userType";
/**
* 初始化人员
*/
public static final String PROCESS_INITIATOR = "INITIATOR";
/**
* 流程跳过
*/
public static final String FLOWABLE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED";
}
package com.mortals.flowable.common.enums;
/**
* 流程意见类型
*
* @author: finegirl
* @date: 2021/7/31 12:05
* @description:
*/
public enum FlowComment {
/**
* 说明
*/
NORMAL("1", "正常意见"),
REBACK("2", "退回意见"),
REJECT("3", "驳回意见"),
DELEGATE("4", "委派意见"),
ASSIGN("5", "转办意见"),
STOP("6", "终止流程");
/**
* 类型
*/
private final String type;
/**
* 说明
*/
private final String remark;
FlowComment(String type, String remark) {
this.type = type;
this.remark = remark;
}
public String getType() {
return type;
}
public String getRemark() {
return remark;
}
}
package com.mortals.flowable.factory;
import lombok.Getter;
import org.flowable.engine.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* flowable 引擎注入封装
*
* @author: finegirl
* @date: 2021/7/31 12:20
*/
@Component
@Getter
public class FlowServiceFactory {
@Resource
protected RepositoryService repositoryService;
@Resource
protected RuntimeService runtimeService;
@Resource
protected IdentityService identityService;
@Resource
protected TaskService taskService;
@Resource
protected FormService formService;
@Resource
protected HistoryService historyService;
@Resource
protected ManagementService managementService;
@Qualifier("processEngine")
@Resource
protected ProcessEngine processEngine;
}
package com.mortals.flowable.flow;
import com.greenpineyu.fel.FelEngine;
import com.greenpineyu.fel.FelEngineImpl;
import com.greenpineyu.fel.context.FelContext;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.ProcessDefinition;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class FindNextNodeUtil {
/**
* 获取下一步骤的用户任务
*
* @param repositoryService
* @param map
* @return
*/
public static List<UserTask> getNextUserTasks(RepositoryService repositoryService, org.flowable.task.api.Task task, Map<String, Object> map) {
List<UserTask> data = new ArrayList<>();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
Process mainProcess = bpmnModel.getMainProcess();
Collection<FlowElement> flowElements = mainProcess.getFlowElements();
String key = task.getTaskDefinitionKey();
FlowElement flowElement = bpmnModel.getFlowElement(key);
next(flowElements, flowElement, map, data);
return data;
}
public static void next(Collection<FlowElement> flowElements, FlowElement flowElement, Map<String, Object> map, List<UserTask> nextUser) {
//如果是结束节点
if (flowElement instanceof EndEvent) {
//如果是子任务的结束节点
if (getSubProcess(flowElements, flowElement) != null) {
flowElement = getSubProcess(flowElements, flowElement);
}
}
//获取Task的出线信息--可以拥有多个
List<SequenceFlow> outGoingFlows = null;
if (flowElement instanceof Task) {
outGoingFlows = ((Task) flowElement).getOutgoingFlows();
} else if (flowElement instanceof Gateway) {
outGoingFlows = ((Gateway) flowElement).getOutgoingFlows();
} else if (flowElement instanceof StartEvent) {
outGoingFlows = ((StartEvent) flowElement).getOutgoingFlows();
} else if (flowElement instanceof SubProcess) {
outGoingFlows = ((SubProcess) flowElement).getOutgoingFlows();
} else if (flowElement instanceof CallActivity) {
outGoingFlows = ((CallActivity) flowElement).getOutgoingFlows();
}
if (outGoingFlows != null && outGoingFlows.size() > 0) {
//遍历所有的出线--找到可以正确执行的那一条
for (SequenceFlow sequenceFlow : outGoingFlows) {
//1.有表达式,且为true
//2.无表达式
String expression = sequenceFlow.getConditionExpression();
if (expression == null ||
Boolean.parseBoolean(
String.valueOf(
result(map, expression.substring(expression.lastIndexOf("{") + 1, expression.lastIndexOf("}")))))) {
//出线的下一节点
String nextFlowElementID = sequenceFlow.getTargetRef();
if (checkSubProcess(nextFlowElementID, flowElements, nextUser)) {
continue;
}
//查询下一节点的信息
FlowElement nextFlowElement = getFlowElementById(nextFlowElementID, flowElements);
//调用流程
if (nextFlowElement instanceof CallActivity) {
CallActivity ca = (CallActivity) nextFlowElement;
if (ca.getLoopCharacteristics() != null) {
UserTask userTask = new UserTask();
userTask.setId(ca.getId());
userTask.setId(ca.getId());
userTask.setLoopCharacteristics(ca.getLoopCharacteristics());
userTask.setName(ca.getName());
nextUser.add(userTask);
}
next(flowElements, nextFlowElement, map, nextUser);
}
//用户任务
if (nextFlowElement instanceof UserTask) {
nextUser.add((UserTask) nextFlowElement);
}
//排他网关
else if (nextFlowElement instanceof ExclusiveGateway) {
next(flowElements, nextFlowElement, map, nextUser);
}
//并行网关
else if (nextFlowElement instanceof ParallelGateway) {
next(flowElements, nextFlowElement, map, nextUser);
}
//接收任务
else if (nextFlowElement instanceof ReceiveTask) {
next(flowElements, nextFlowElement, map, nextUser);
}
//服务任务
else if (nextFlowElement instanceof ServiceTask) {
next(flowElements, nextFlowElement, map, nextUser);
}
//子任务的起点
else if (nextFlowElement instanceof StartEvent) {
next(flowElements, nextFlowElement, map, nextUser);
}
//结束节点
else if (nextFlowElement instanceof EndEvent) {
next(flowElements, nextFlowElement, map, nextUser);
}
}
}
}
}
/**
* 判断是否是多实例子流程并且需要设置集合类型变量
*/
public static boolean checkSubProcess(String Id, Collection<FlowElement> flowElements, List<UserTask> nextUser) {
for (FlowElement flowElement1 : flowElements) {
if (flowElement1 instanceof SubProcess && flowElement1.getId().equals(Id)) {
SubProcess sp = (SubProcess) flowElement1;
if (sp.getLoopCharacteristics() != null) {
String inputDataItem = sp.getLoopCharacteristics().getInputDataItem();
UserTask userTask = new UserTask();
userTask.setId(sp.getId());
userTask.setLoopCharacteristics(sp.getLoopCharacteristics());
userTask.setName(sp.getName());
nextUser.add(userTask);
return true;
}
}
}
return false;
}
/**
* 查询一个节点的是否子任务中的节点,如果是,返回子任务
*
* @param flowElements 全流程的节点集合
* @param flowElement 当前节点
* @return
*/
public static FlowElement getSubProcess(Collection<FlowElement> flowElements, FlowElement flowElement) {
for (FlowElement flowElement1 : flowElements) {
if (flowElement1 instanceof SubProcess) {
for (FlowElement flowElement2 : ((SubProcess) flowElement1).getFlowElements()) {
if (flowElement.equals(flowElement2)) {
return flowElement1;
}
}
}
}
return null;
}
/**
* 根据ID查询流程节点对象, 如果是子任务,则返回子任务的开始节点
*
* @param Id 节点ID
* @param flowElements 流程节点集合
* @return
*/
public static FlowElement getFlowElementById(String Id, Collection<FlowElement> flowElements) {
for (FlowElement flowElement : flowElements) {
if (flowElement.getId().equals(Id)) {
//如果是子任务,则查询出子任务的开始节点
if (flowElement instanceof SubProcess) {
return getStartFlowElement(((SubProcess) flowElement).getFlowElements());
}
return flowElement;
}
if (flowElement instanceof SubProcess) {
FlowElement flowElement1 = getFlowElementById(Id, ((SubProcess) flowElement).getFlowElements());
if (flowElement1 != null) {
return flowElement1;
}
}
}
return null;
}
/**
* 返回流程的开始节点
*
* @param flowElements 节点集合
* @description:
*/
public static FlowElement getStartFlowElement(Collection<FlowElement> flowElements) {
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof StartEvent) {
return flowElement;
}
}
return null;
}
/**
* 校验el表达示例
*
* @param map
* @param expression
* @return
*/
public static Object result(Map<String, Object> map, String expression) {
FelEngine fel = new FelEngineImpl();
FelContext ctx = fel.getContext();
for (Map.Entry<String, Object> entry : map.entrySet()) {
ctx.set(entry.getKey(), entry.getValue());
}
Object result = fel.eval(expression);
return result;
}
}
package com.mortals.flowable.flow;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.spring.boot.EngineConfigurationConfigurer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
@Override
public void configure(SpringProcessEngineConfiguration engineConfiguration) {
engineConfiguration.setActivityFontName("宋体");
engineConfiguration.setLabelFontName("宋体");
engineConfiguration.setAnnotationFontName("宋体");
}
}
package com.mortals.flowable.listener;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
/**
*
*
* @author: finegirl
* @date: 2021/7/31 12:19
*/
public class UserTaskListener implements TaskListener{
@Override
public void notify(DelegateTask delegateTask) {
}
}
.org-tree-container {
display: inline-block;
padding: 15px;
background-color: #fff;
}
.org-tree {
// display: inline-block;
display: table;
text-align: center;
&:before, &:after {
content: '';
display: table;
}
&:after {
clear: both;
}
}
.org-tree-node,
.org-tree-node-children {
position: relative;
margin: 0;
padding: 0;
list-style-type: none;
&:before, &:after {
transition: all .35s;
}
}
.org-tree-node-label {
position: relative;
display: inline-block;
.org-tree-node-label-inner {
padding: 10px 15px;
text-align: center;
border-radius: 3px;
box-shadow: 0 1px 5px rgba(0, 0, 0, .15);
}
}
.org-tree-node-btn {
position: absolute;
top: 100%;
left: 50%;
width: 20px;
height: 20px;
z-index: 10;
margin-left: -11px;
margin-top: 9px;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 50%;
box-shadow: 0 0 2px rgba(0, 0, 0, .15);
cursor: pointer;
transition: all .35s ease;
&:hover {
background-color: #e7e8e9;
transform: scale(1.15);
}
&:before, &:after {
content: '';
position: absolute;
}
&:before {
top: 50%;
left: 4px;
right: 4px;
height: 0;
border-top: 1px solid #ccc;
}
&:after {
top: 4px;
left: 50%;
bottom: 4px;
width: 0;
border-left: 1px solid #ccc;
}
&.expanded:after {
border: none;
}
}
.org-tree-node {
padding-top: 20px;
display: table-cell;
vertical-align: top;
&.is-leaf, &.collapsed {
padding-left: 10px;
padding-right: 10px;
}
&:before, &:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 19px;
}
&:after {
left: 50%;
border-left: 1px solid #ddd;
}
&:not(:first-child):before,
&:not(:last-child):after {
border-top: 1px solid #ddd;
}
}
.collapsable .org-tree-node.collapsed {
padding-bottom: 30px;
.org-tree-node-label:after {
content: '';
position: absolute;
top: 100%;
left: 0;
width: 50%;
height: 20px;
border-right: 1px solid #ddd;
}
}
.org-tree > .org-tree-node {
padding-top: 0;
&:after {
border-left: 0;
}
}
.org-tree-node-children {
padding-top: 20px;
display: table;
&:before {
content: '';
position: absolute;
top: 0;
left: 50%;
width: 0;
height: 20px;
border-left: 1px solid #ddd;
}
&:after {
content: '';
display: table;
clear: both;
}
}
.horizontal {
.org-tree-node {
// display: flex;
// flex-direction: row;
// justify-content: flex-start;
// align-items: center;
display: table-cell;
float: none;
padding-top: 0;
padding-left: 20px;
&.is-leaf, &.collapsed {
padding-top: 10px;
padding-bottom: 10px;
}
&:before, &:after {
width: 19px;
height: 50%;
}
&:after {
top: 50%;
left: 0;
border-left: 0;
}
&:only-child:before {
top: 1px;
border-bottom: 1px solid #ddd;
}
&:not(:first-child):before,
&:not(:last-child):after {
border-top: 0;
border-left: 1px solid #ddd;
}
&:not(:only-child):after {
border-top: 1px solid #ddd;
}
.org-tree-node-inner {
display: table;
}
}
.org-tree-node-label {
display: table-cell;
vertical-align: middle;
}
&.collapsable .org-tree-node.collapsed {
padding-right: 30px;
.org-tree-node-label:after {
top: 0;
left: 100%;
width: 20px;
height: 50%;
border-right: 0;
border-bottom: 1px solid #ddd;
}
}
.org-tree-node-btn {
top: 50%;
left: 100%;
margin-top: -11px;
margin-left: 9px;
}
& > .org-tree-node:only-child:before {
border-bottom: 0;
}
.org-tree-node-children {
// display: flex;
// flex-direction: column;
// justify-content: center;
// align-items: flex-start;
display: table-cell;
padding-top: 0;
padding-left: 20px;
&:before {
top: 50%;
left: 0;
width: 20px;
height: 0;
border-left: 0;
border-top: 1px solid #ddd;
}
&:after {
display: none;
}
& > .org-tree-node {
display: block;
}
}
}
let Socket = ''
let setIntervalWesocketPush = null
/**
* 建立websocket连接
* @param {string} url ws地址
*/
export const createSocket = url => {
Socket && Socket.close()
if (!Socket) {
console.log('建立websocket连接')
Socket = new WebSocket(url)
Socket.onopen = onopenWS
Socket.onmessage = onmessageWS
Socket.onerror = onerrorWS
Socket.onclose = oncloseWS
} else {
console.log('websocket已连接')
}
}
/**打开WS之后发送心跳 */
const onopenWS = () => {
sendPing()
}
/**连接失败重连 */
const onerrorWS = () => {
Socket.close()
clearInterval(setIntervalWesocketPush)
console.log('连接失败重连中')
if (Socket.readyState !== 3) {
Socket = null
createSocket()
}
}
/**WS数据接收统一处理 */
const onmessageWS = e => {
window.dispatchEvent(new CustomEvent('onmessageWS', {
detail: {
data: e.data
}
}))
}
/**
* 发送数据但连接未建立时进行处理等待重发
* @param {any} message 需要发送的数据
*/
const connecting = message => {
setTimeout(() => {
if (Socket.readyState === 0) {
connecting(message)
} else {
Socket.send(JSON.stringify(message))
}
}, 1000)
}
/**
* 发送数据
* @param {any} message 需要发送的数据
*/
export const sendWSPush = message => {
if (Socket !== null && Socket.readyState === 3) {
Socket.close()
createSocket()
} else if (Socket.readyState === 1) {
Socket.send(JSON.stringify(message))
} else if (Socket.readyState === 0) {
connecting(message)
}
}
/**断开重连 */
const oncloseWS = () => {
clearInterval(setIntervalWesocketPush)
console.log('websocket已断开....正在尝试重连')
if (Socket.readyState !== 2) {
Socket = null
createSocket()
}
}
/**发送心跳
* @param {number} time 心跳间隔毫秒 默认5000
* @param {string} ping 心跳名称 默认字符串ping
*/
export const sendPing = (time = 15000, ping = 'ping') => {
let heart={};
let body={};
heart.type="HEART_BEAT_REQUEST";
let msgId=new Date().getMilliseconds();
body.msgId=msgId;
heart.body=body;
clearInterval(setIntervalWesocketPush)
Socket.send(JSON.stringify(heart))
setIntervalWesocketPush = setInterval(() => {
Socket.send(JSON.stringify(heart))
}, time)
}
\ No newline at end of file
.org-tree-container {
display: inline-block;
padding: 15px;
background-color: #fff;
}
.org-tree {
// display: inline-block;
display: table;
text-align: center;
&:before, &:after {
content: '';
display: table;
}
&:after {
clear: both;
}
}
.org-tree-node,
.org-tree-node-children {
position: relative;
margin: 0;
padding: 0;
list-style-type: none;
&:before, &:after {
transition: all .35s;
}
}
.org-tree-node-label {
position: relative;
display: inline-block;
.org-tree-node-label-inner {
padding: 10px 15px;
text-align: center;
border-radius: 3px;
box-shadow: 0 1px 5px rgba(0, 0, 0, .15);
}
}
.org-tree-node-btn {
position: absolute;
top: 100%;
left: 50%;
width: 20px;
height: 20px;
z-index: 10;
margin-left: -11px;
margin-top: 9px;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 50%;
box-shadow: 0 0 2px rgba(0, 0, 0, .15);
cursor: pointer;
transition: all .35s ease;
&:hover {
background-color: #e7e8e9;
transform: scale(1.15);
}
&:before, &:after {
content: '';
position: absolute;
}
&:before {
top: 50%;
left: 4px;
right: 4px;
height: 0;
border-top: 1px solid #ccc;
}
&:after {
top: 4px;
left: 50%;
bottom: 4px;
width: 0;
border-left: 1px solid #ccc;
}
&.expanded:after {
border: none;
}
}
.org-tree-node {
padding-top: 20px;
display: table-cell;
vertical-align: top;
&.is-leaf, &.collapsed {
padding-left: 10px;
padding-right: 10px;
}
&:before, &:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 19px;
}
&:after {
left: 50%;
border-left: 1px solid #ddd;
}
&:not(:first-child):before,
&:not(:last-child):after {
border-top: 1px solid #ddd;
}
}
.collapsable .org-tree-node.collapsed {
padding-bottom: 30px;
.org-tree-node-label:after {
content: '';
position: absolute;
top: 100%;
left: 0;
width: 50%;
height: 20px;
border-right: 1px solid #ddd;
}
}
.org-tree > .org-tree-node {
padding-top: 0;
&:after {
border-left: 0;
}
}
.org-tree-node-children {
padding-top: 20px;
display: table;
&:before {
content: '';
position: absolute;
top: 0;
left: 50%;
width: 0;
height: 20px;
border-left: 1px solid #ddd;
}
&:after {
content: '';
display: table;
clear: both;
}
}
.horizontal {
.org-tree-node {
// display: flex;
// flex-direction: row;
// justify-content: flex-start;
// align-items: center;
display: table-cell;
float: none;
padding-top: 0;
padding-left: 20px;
&.is-leaf, &.collapsed {
padding-top: 10px;
padding-bottom: 10px;
}
&:before, &:after {
width: 19px;
height: 50%;
}
&:after {
top: 50%;
left: 0;
border-left: 0;
}
&:only-child:before {
top: 1px;
border-bottom: 1px solid #ddd;
}
&:not(:first-child):before,
&:not(:last-child):after {
border-top: 0;
border-left: 1px solid #ddd;
}
&:not(:only-child):after {
border-top: 1px solid #ddd;
}
.org-tree-node-inner {
display: table;
}
}
.org-tree-node-label {
display: table-cell;
vertical-align: middle;
}
&.collapsable .org-tree-node.collapsed {
padding-right: 30px;
.org-tree-node-label:after {
top: 0;
left: 100%;
width: 20px;
height: 50%;
border-right: 0;
border-bottom: 1px solid #ddd;
}
}
.org-tree-node-btn {
top: 50%;
left: 100%;
margin-top: -11px;
margin-left: 9px;
}
& > .org-tree-node:only-child:before {
border-bottom: 0;
}
.org-tree-node-children {
// display: flex;
// flex-direction: column;
// justify-content: center;
// align-items: flex-start;
display: table-cell;
padding-top: 0;
padding-left: 20px;
&:before {
top: 50%;
left: 0;
width: 20px;
height: 0;
border-left: 0;
border-top: 1px solid #ddd;
}
&:after {
display: none;
}
& > .org-tree-node {
display: block;
}
}
}
<template>
<div class="page">
<LayoutTable :data="tableData" :config="tableConfig" notSearch />
</div>
</template>
<script>
import table from "@/assets/mixins/table";
export default {
mixins: [table],
created() {
const { basicsId } = this.$route.query;
this.config.addQuery = { basicsId: basicsId };
},
methods: {
beforeRender(data) {
return data;
},
formterApplyStr(arrs) {
let temp = [];
for (let i = 0; i < arrs.length; i++) {
let str = "";
str += i + 1 + ": " + arrs[i].content + "\n";
temp.push(str);
}
return temp.join("");
},
},
data() {
return {
config: {
search: [],
columns: [
{ type: "selection", width: 60 },
{ label: "模板标题", prop: "title", width: 200 },
{
label: "申请条件",
prop: "content",
formatter: (row) => {
let content = this.formterApplyStr(JSON.parse(row.content));
return <span style="white-space: pre-wrap">{content}</span>;
},
},
{
label: "操作",
width: 180,
formatter: (row) => {
return (
<div>
<el-button
type="primary"
icon="el-icon-edit"
round
size="mini"
onClick={() => {
this.toEdit(row);
}}
>
编辑
</el-button>
</div>
);
},
},
],
},
};
},
};
</script>
\ No newline at end of file
<template>
<layout-form>
<el-dialog
:title="applyDialog.title"
:visible.sync="applyDialog.visible"
width="800px"
append-to-body
>
<!--表单添加-->
<el-form label-width="80px">
<div>
<el-button size="mini" plain type="success" @click="addListRow()"
>新增申请条件</el-button
>
<el-table
:data="dynamicForm.options"
border
style="width: 100%; margin-top: 15px"
>
<el-table-column label="内容" align="center">
<template slot-scope="scope">
<el-form-item
label-width="0"
:prop="'options.' + scope.$index + '.content'"
>
<el-input
type="textarea"
v-model="scope.row.content"
placeholder="请输入内容"
></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="操作" width="160" align="center">
<template slot-scope="scope">
<el-form-item label-width="0">
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handTableDelete(scope.$index, scope.row)"
>删除</el-button
>
</el-form-item>
</template>
</el-table-column>
</el-table>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="applyConfirm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
<el-form
:model="form"
:loading="loading"
:rules="rules"
size="small"
style="width: 100%"
label-width="120px"
ref="form"
>
<el-row>
<Field
span="14"
label="模板标题"
prop="title"
v-model="form.title"
placeholder="请输入模板标题"
/>
<el-col span="12">
<el-form-item label="申请条件" class="my-form-field">
<el-button @click.prevent="handEditApply(form.content)"
>编辑申请条件</el-button
>
<br />
<span style="white-space: pre-wrap">{{ content }}</span>
</el-form-item>
</el-col>
</el-row>
<form-buttons @submit="submitForm" />
</el-form>
</layout-form>
</template>
<script>
import form from "@/assets/mixins/form";
export default {
mixins: [form],
created() {
const { basicsId } = this.$route.query;
this.form.basicsId = basicsId;
},
methods: {
beforeRender(data) {
console.log("渲染前", data);
if (data.entity.content && data.entity.content.length > 0) {
this.dynamicForm.options = JSON.parse(data.entity.content);
this.content = this.formterApplyStr(this.dynamicForm.options);
}
return data;
},
handTableDelete(index, val) {
this.dynamicForm.options.splice(index, 1);
},
handEditApply(val) {
this.applyDialog.visible = true;
},
applyConfirm() {
//确定 组装qa
this.content = this.formterApplyStr(this.dynamicForm.options);
this.form.content = JSON.stringify(this.dynamicForm.options);
this.applyDialog.visible = false;
},
formterApplyStr(arrs) {
let temp = [];
for (let i=0; i < arrs.length; i++) {
let str = "";
str += (i+1) + ": " + arrs[i].content + "\n";
temp.push(str);
}
return temp.join("");
},
cancel() {
this.applyDialog.visible = false;
},
addListRow() {
this.dynamicForm.options.push({
content: "",
});
},
},
data() {
return {
applyDialog: {
visible: false,
title: "申请条件",
},
content: "",
dynamicForm: {
options: [],
},
rules: {
title: [
{ required: true, message: "请输入申请条件", trigger: "blur" },
{ max: 64, message: "最多只能录入64个字符", trigger: "blur" },
],
content: [
{ required: true, message: "请输入申请条件", trigger: "blur" },
{ max: 65535, message: "最多只能录入65535个字符", trigger: "blur" },
],
},
};
},
};
</script>
\ No newline at end of file
<template>
<div class="page">
<LayoutTable :data='tableData' :config='tableConfig' />
</div>
</template>
<script>
import table from "@/assets/mixins/table";
export default {
mixins: [table],
data() {
return {
config: {
search: [
],
columns: [
{type: "selection", width: 60},
{label: "变更时间", prop: "updatetime", formatter: this.formatterDate},
{label: "变更用户loginName", prop: "updateuser"},
{
label: "操作",
width: 180,
formatter: row => {
return (
<div><el-button type="primary" icon="el-icon-edit" round size='mini' onClick={()=>{this.toEdit(row)}}>编辑</el-button></div>
);
}
}
]
}
};
}
};
</script>
\ No newline at end of file
<template>
<layout-form>
<el-form :model="form" :loading="loading" :rules="rules" size='small' style="width:100%" label-width='120px' ref="form">
<el-row>
<Field label="一件事基础表 one_basics id" prop="basicsId" v-model="form.basicsId" placeholder="请输入一件事基础表 one_basics id"/>
<Field label="材料id " prop="oneDatumIds" v-model="form.oneDatumIds" placeholder="请输入材料id "/>
<Field label="变更时间" prop="updateTime" v-model="form.updateTime" placeholder="请输入变更时间"/>
<Field label="变更用户loginName" prop="updateUser" v-model="form.updateUser" placeholder="请输入变更用户loginName"/>
</el-row>
<form-buttons @submit='submitForm'/>
</el-form>
</layout-form>
</template>
<script>
import form from "@/assets/mixins/form";
export default {
mixins: [form],
data() {
return {
rules: {
updatetime:[{required: true, message: '请输入变更时间', trigger: 'blur'},],
updateUser:[{required: true, message: '请输入变更用户loginName', trigger: 'blur'},
{max: 50, message: '最多只能录入50个字符', trigger: 'blur'}],
}
};
}
};
</script>
\ No newline at end of file
This diff is collapsed.
<template>
<div class="page">
<LayoutTable :data="tableData" :config="tableConfig" notDel notSearch />
</div>
</template>
<script>
import table from "@/assets/mixins/table";
export default {
mixins: [table],
created() {
const { basicsId } = this.$route.query;
this.config.addQuery = { basicsId: basicsId };
},
methods: {
beforeRender(data) {
return data;
},
},
data() {
return {
config: {
search: [],
columns: [
{ label: "模板标题", prop: "title" },
{ label: "办理机构", prop: "jointInfoShow" },
{ label: "法定时限", prop: "legalTimeLimitShow" },
{ label: "承诺时限", prop: "promiseTimeLimitShow" },
{ label: "收费金额", prop: "charges" },
{ label: "办公时间", prop: "handleTimeShow" },
{ label: "办公地址", prop: "handlePlaceShow" },
{ label: "咨询电话", prop: "cousultingTelephoneShow" },
{ label: "投诉电话", prop: "supervisoryTelephoneShow" },
{ label: "结果信息", prop: "resultInfo" },
{
label: "操作",
width: 180,
formatter: (row) => {
return (
<div>
<el-button
type="primary"
icon="el-icon-edit"
round
size="mini"
onClick={() => {
this.toEdit(row);
}}
>
编辑
</el-button>
</div>
);
},
},
],
},
};
},
};
</script>
This diff is collapsed.
<template>
<div class="page">
<LayoutTable :data="tableData" :config="tableConfig" />
<!-- 查看二维码弹窗 -->
<el-dialog title="一次办二维码" :visible.sync="qrCodeDialog.visible" width="350px">
<img :src="qrCodeDialog.qrCode" />
<p style="word-wrap: break-word">{{ qrCodeDialog.qrCodeUrl }}</p>
</el-dialog>
</div>
</template>
<script>
import table from "@/assets/mixins/table";
export default {
name: "basics",
components: {},
mixins: [table],
created() {},
methods: {
async viewQrCode(id) {
try {
const { qrCode, qrCodeUrl } = await this.$post("/basics/viewQrCode", {
"entity.id": id,
});
this.qrCodeDialog.qrCode = qrCode;
this.qrCodeDialog.qrCodeUrl = qrCodeUrl;
this.qrCodeDialog.visible = true;
} catch (error) {
this.$message.error(error.message);
}
},
handPlatform(row) {
this.$router.push({
path: "/basics/index",
query: { basicsId: row.id },
});
},
async handAddBaseInfo(row) {
try {
this.$router.push({
path: "/basics/info/list",
query: {
basicsId: row.id
},
});
} catch (error) {
this.$message.error(error.message);
}
},
async handAddApplyCondition(row) {
try {
this.$router.push({
path: "/accept/list",
query: {
basicsId: row.id
},
});
} catch (error) {
this.$message.error(error.message);
}
},
async handAddFlow(row) {
try {
this.$router.push({
path: "/flowlimit/list",
query: {
basicsId: row.id
},
});
} catch (error) {
this.$message.error(error.message);
}
},
},
data() {
return {
qrCodeDialog: {
visible: false,
qrCode: "",
qrCodeUrl: "",
},
config: {
search: [],
columns: [
{ type: "selection", width: 60 },
{ label: "一件事标题", prop: "tname" },
{
label: "二维码",
prop: "qrcode",
formatter: (row) => {
return (
<el-button
type='text'
onClick={() => {
this.viewQrCode(row.id);
}}>
二维码
</el-button>
);
},
},
{
label: "创建时间",
prop: "createTime",
formatter: this.formatterDate,
},
{
label: "操作",
width: 320,
formatter: (row) => {
return (
<div>
<el-row>
<el-button
size='mini'
icon='el-icon-edit'
size='mini'
onClick={() => {
this.toEdit(row);
}}>
编辑
</el-button>
<span> </span>
<el-button
size='mini'
icon='el-icon-edit-outline'
size='mini'
onClick={() => {
this.handPlatform(row);
}}>
事项工作台
</el-button>
<span> </span>
<el-button
size='mini'
icon='el-icon-edit-outline'
size='mini'
onClick={() => {
this.handAddBaseInfo(row);
}}>
基本信息
</el-button>
<span> </span>
</el-row>
<el-row style='margin-top:10px'>
<el-button
size='mini'
icon='el-icon-edit-outline'
size='mini'
onClick={() => {
this.handAddApplyCondition(row);
}}>
申请条件
</el-button>
<span> </span>
<el-button
size='mini'
icon='el-icon-edit-outline'
size='mini'
onClick={() => {
this.handAddFlow(row);
}}>
办理流程
</el-button>
<span> </span>
<Confirm message='确定要删除该事件吗?' onConfirm={() => this.toDel(row.id)}>
<el-button size='mini' icon='el-icon-delete' size='mini'>
删除
</el-button>
</Confirm>
<span> </span>
</el-row>
</div>
);
},
},
],
},
};
},
};
</script>
This diff is collapsed.
<template>
<div class="page">
<LayoutTable :data='tableData' :config='tableConfig' />
</div>
</template>
<script>
import table from "@/assets/mixins/table";
export default {
mixins: [table],
data() {
return {
config: {
search: [
],
columns: [
{type: "selection", width: 60},
{label: "分类名称", prop: "name"},
{label: "父级选项id", prop: "optionids"},
{label: "变更时间", prop: "updatetime", formatter: this.formatterDate},
{label: "变更用户loginName", prop: "updateuser"},
{
label: "操作",
width: 180,
formatter: row => {
return (
<div><el-button type="primary" icon="el-icon-edit" round size='mini' onClick={()=>{this.toEdit(row)}}>编辑</el-button></div>
);
}
}
]
}
};
}
};
</script>
\ No newline at end of file
<template>
<div class="page">
<LayoutTable :data='tableData' :config='tableConfig' />
</div>
</template>
<script>
import table from "@/assets/mixins/table";
export default {
mixins: [table],
data() {
return {
config: {
search: [
],
columns: [
{type: "selection", width: 60},
{label: "选项名称", prop: "name"},
{label: "备注", prop: "summary"},
{label: "变更时间", prop: "updatetime", formatter: this.formatterDate},
{label: "变更用户loginName", prop: "updateuser"},
{
label: "操作",
width: 180,
formatter: row => {
return (
<div><el-button type="primary" icon="el-icon-edit" round size='mini' onClick={()=>{this.toEdit(row)}}>编辑</el-button></div>
);
}
}
]
}
};
}
};
</script>
\ No newline at end of file
<template>
<layout-form>
<el-form :model="form" :loading="loading" :rules="rules" size='small' style="width:100%" label-width='120px' ref="form">
<el-row>
<Field label="一件事问题表id" prop="classifyId" v-model="form.classifyId" placeholder="请输入一件事问题表id"/>
<Field label="一件事下个问题id" prop="classifyNextId" v-model="form.classifyNextId" placeholder="请输入一件事下个问题id"/>
<Field label="选项名称" prop="name" v-model="form.name" placeholder="请输入选项名称"/>
<Field label="是否最终节点 0否 1是" prop="isend" v-model="form.isend" placeholder="请输入是否最终节点 0否 1是"/>
<Field label="基本信息模板id" prop="basicsinfoId" v-model="form.basicsinfoId" placeholder="请输入基本信息模板id"/>
<Field label="申请条件id" prop="acceptId" v-model="form.acceptId" placeholder="请输入申请条件id"/>
<Field label="办理流程id" prop="flowlimitId" v-model="form.flowlimitId" placeholder="请输入办理流程id"/>
<Field label="事项关联id" prop="matterId" v-model="form.matterId" placeholder="请输入事项关联id"/>
<Field label="材料id" prop="datumId" v-model="form.datumId" placeholder="请输入材料id"/>
<Field label="备注类型 1常规备注 2终结备注" prop="summaryType" v-model="form.summaryType" placeholder="请输入备注类型 1常规备注 2终结备注"/>
<Field label="备注" prop="summary" v-model="form.summary" placeholder="请输入备注"/>
<Field label="变更时间" prop="updateTime" v-model="form.updateTime" placeholder="请输入变更时间"/>
<Field label="变更用户loginName" prop="updateUser" v-model="form.updateUser" placeholder="请输入变更用户loginName"/>
</el-row>
<form-buttons @submit='submitForm'/>
</el-form>
</layout-form>
</template>
<script>
import form from "@/assets/mixins/form";
export default {
mixins: [form],
data() {
return {
rules: {
name:[
{max: 255, message: '最多只能录入255个字符', trigger: 'blur'}],
summary:[
{max: 256, message: '最多只能录入256个字符', trigger: 'blur'}],
updatetime:[{required: true, message: '请输入变更时间', trigger: 'blur'},],
updateUser:[{required: true, message: '请输入变更用户loginName', trigger: 'blur'},
{max: 50, message: '最多只能录入50个字符', trigger: 'blur'}],
}
};
}
};
</script>
\ No newline at end of file
<template>
<div class="page">
<LayoutTable :data='tableData' :config='tableConfig' />
</div>
</template>
<script>
import table from "@/assets/mixins/table";
export default {
mixins: [table],
data() {
return {
config: {
search: [
],
columns: [
{type: "selection", width: 60},
{label: "基础信息json", prop: "basicsjson"},
{label: "申请条件json", prop: "acceptjson"},
{label: "办理流程json", prop: "flowlimitjson"},
{label: "最终选择的材料id one_datum", prop: "onedatumids"},
{label: "变更时间", prop: "updatetime", formatter: this.formatterDate},
{label: "变更用户loginName", prop: "updateuser"},
{
label: "操作",
width: 180,
formatter: row => {
return (
<div><el-button type="primary" icon="el-icon-edit" round size='mini' onClick={()=>{this.toEdit(row)}}>编辑</el-button></div>
);
}
}
]
}
};
}
};
</script>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -13,6 +13,7 @@ module.exports = {
devServer: {
disableHostCheck: true,
port: 8081,
hot: true,//自动保存
proxy: {
'/m': {
target: 'http://127.0.0.1:17011',
......
package com.mortals.xhx.module.accept.dao;
import com.mortals.framework.dao.ICRUDDao;
import com.mortals.xhx.module.accept.model.AcceptEntity;
/**
* <p>Title: 一件事申请条件</p>
* <p>Description: AcceptDao DAO接口 </p>
* @author
* @version 1.0.0
*/
public interface AcceptDao extends ICRUDDao<AcceptEntity,Long>{
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment