Ver a proveniência

增加:工作流相关

master
郑根木 há 2 anos
ascendente
cometimento
e63f0f51a9
15 ficheiros alterados com 465 adições e 151 eliminações
  1. +25
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java
  2. +34
    -12
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java
  3. +2
    -2
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java
  4. +32
    -22
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcHelper.java
  5. +30
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcLoadHandler.java
  6. +91
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcSaveHandler.java
  7. +7
    -65
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java
  8. +10
    -6
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/AbstractFlowHandler.java
  9. +13
    -13
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowHelper.java
  10. +171
    -20
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowInstance.java
  11. +15
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowLoadHandler.java
  12. +20
    -8
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowService.java
  13. +1
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskEntity.java
  14. +5
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/dict/DictCache.java
  15. +9
    -1
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/EntityHelper.java

+ 25
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java Ver ficheiro

@@ -12,6 +12,8 @@ import cc.smtweb.framework.core.mvc.service.AbstractTreeHandler;
import cc.smtweb.framework.core.mvc.service.TreeHelper;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.system.bpm.web.design.flow.ModelProc;
import cc.smtweb.system.bpm.web.design.flow.ModelProcCache;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormCache;

@@ -21,11 +23,12 @@ import java.util.*;
* Created by Akmm at 2022/3/21 18:22
*/
public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity> {
//查询类型:0-目录;1-表定义;2-页面;3-控件;23-页面和控件
//查询类型:0-目录;1-表定义;2-页面;3-控件;4-流程定义 23-页面和控件
private final static int TYPE_CATALOG = 0;
private final static int TYPE_TABLE = 1;
private final static int TYPE_PAGE = 2;
private final static int TYPE_WIDGET = 3;
private final static int TYPE_PROC = 4;
private final static int TYPE_FORM = 23;

private long prj_id;//所属项目
@@ -72,6 +75,11 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
List<ModelTable> l = tabledao.queryWhere(" tb_prj_id in (" + sqlPrjId + ") and (tb_name like ? or tb_title like ?) order by tb_name", text, text);
listRet.addAll(l);
break;
case TYPE_PROC:
EntityDao<ModelProc> procDao = DbEngine.getInstance().findDao(ModelProc.class);
List<ModelProc> lp = procDao.queryWhere(" tb_prj_id in (" + sqlPrjId + ") and (prc_name like ? or prc_code like ?) order by prc_name", text, text);
listRet.addAll(lp);
break;
case TYPE_PAGE:
case TYPE_WIDGET:
case TYPE_FORM:
@@ -106,6 +114,9 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
case TYPE_TABLE:
addTableChildren(listRet, id);
break;
case TYPE_PROC:
addProcChildren(listRet, id);
break;
case TYPE_PAGE:
case TYPE_WIDGET:
case TYPE_FORM:
@@ -136,6 +147,9 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
case TYPE_TABLE:
addTableChildren(listRet, mc.getId());
break;
case TYPE_PROC:
addProcChildren(listRet, mc.getId());
break;
case TYPE_PAGE:
case TYPE_WIDGET:
case TYPE_FORM:
@@ -158,6 +172,14 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
listRet.addAll(set);
}

//增加工作流
private void addProcChildren(List<DefaultEntity> listRet, long mcid) {
Collection<ModelProc> set = ModelProcCache.getInstance().getProcByMc(mcid, (o1, o2) -> CommUtil.chineseCompare(o1.getName(), o2.getName()));
if (set == null || set.isEmpty()) return;

listRet.addAll(set);
}

//添加页面,将子页面单独清出来
private void addForm(List<DefaultEntity> listRet, List<ModelForm> lf, boolean exc_widget) {
for (ModelForm mf : lf) {
@@ -221,6 +243,8 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
node.put("type", TYPE_CATALOG);
} else if (bean instanceof ModelTable) {
node.put("type", TYPE_TABLE);
} else if (bean instanceof ModelProc) {
node.put("type", TYPE_PROC);
} else if (bean instanceof ModelForm) {
final ModelForm form = (ModelForm) bean;
node.put("type", form.getType() + 2);


+ 34
- 12
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java Ver ficheiro

@@ -1,25 +1,47 @@
package cc.smtweb.system.bpm.web.design.flow;

import cc.smtweb.framework.core.common.IntEnum;
import cc.smtweb.framework.core.common.StrEnum;

/**
* Created by Akmm at 2022/5/24 9:04
* 工作流常量及枚举定义
*/
public interface FlowConst {
//操作方式
class OperatorType {
public static final int VIEW = 0;//查看
public static final int NEW = 1;//新增
public static final int EDIT = 2;//编辑
}
//流程按钮
class Button {
public static final String DISUSE = "disuse";// 作废
public static final String LOG = "log";// 流程历史
public static final String WORD = "word";// 导出Word
public static final String EXCEL = "excel";// 导出Excel
public static final String HANDLE = "handle";// 办理,签收
public static final String SUBMIT = "submit";// 提交
public static final String RETAKE = "retake";// 取回
public static final String REJECT = "reject";// 驳回
public static final String ADD = "add";// 新增
public static final String DEL = "del";// 删除
public static final String SAVE = "save";// 保存
class Button extends StrEnum {
public static Button instance = new Button();
// 作废
public static StrEnumBean DISUSE = instance.addEnum("disuse", "作废");
//办理,签收
public static StrEnumBean HANDLE = instance.addEnum("handle", "签收");
//提交
public static StrEnumBean SUBMIT = instance.addEnum("submit", "提交");
//取回
public static StrEnumBean RETAKE = instance.addEnum("retake", "取回");
//驳回
public static StrEnumBean REJECT = instance.addEnum("reject", "驳回");
//新增
public static StrEnumBean ADD = instance.addEnum("add", "新增");
//删除
public static StrEnumBean DEL = instance.addEnum("del", "删除");
//保存
public static StrEnumBean SAVE = instance.addEnum("save", "保存");

//导出Excel
public static StrEnumBean EXCEL = instance.addEnum("excel", "导出Excel");
//导出Word
public static StrEnumBean WORD = instance.addEnum("word", "导出Word");
//流程历史
public static StrEnumBean LOG = instance.addEnum("log", "流程历史");

}
/**
* 活动类型 1-开始任务 2-用户任务 3-条件分支 4-并行开始 5-并行结束 6-脚本任务 9-结束任务


+ 2
- 2
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java Ver ficheiro

@@ -45,11 +45,11 @@ public class ModelProcCache extends AbstractCache<ModelProc> {
return getByKey(mk, key.toUpperCase());
}

public final Set<ModelProc> getFormsByMc(long mcId) {
public final Set<ModelProc> getProcByMc(long mcId) {
return getListByKey(mc, String.valueOf(mcId));
}

public final List<ModelProc> getFormsByMc(long mcId, Comparator<ModelProc> comparator) {
public final List<ModelProc> getProcByMc(long mcId, Comparator<ModelProc> comparator) {
Set<ModelProc> set = getListByKey(mc, String.valueOf(mcId));
if (set == null || set.isEmpty()) return null;
List<ModelProc> list = new ArrayList<>(set);


+ 32
- 22
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcHelper.java Ver ficheiro

@@ -3,6 +3,7 @@ package cc.smtweb.system.bpm.web.design.flow;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.system.bpm.web.design.flow.define.Activity;
import cc.smtweb.system.bpm.web.design.flow.define.ProcInfo;
import cc.smtweb.system.bpm.web.design.flow.define.Trans;
import cc.smtweb.system.bpm.web.sys.base.billFlow.BillFlow;
import cc.smtweb.system.bpm.web.sys.base.billFlow.BillFlowCache;
@@ -18,6 +19,14 @@ import java.util.Set;
* 工作流定义辅助类
*/
public class ModelProcHelper {
public static ModelProc getFromCache(long proc_id) {
return ModelProcCache.getInstance().get(proc_id);
}
public static ProcInfo getProcFromCache(long proc_id) {
ModelProc proc = getFromCache(proc_id);
if (proc == null) return null;
return proc.getProcInfo();
}
/**
* 获取配置的工作流程定义
*
@@ -25,7 +34,7 @@ public class ModelProcHelper {
* @param user_id
* @return
*/
public static ModelProc getBillProc(int bill_type, long user_id) throws Exception {
public static ModelProc getBillProc(int bill_type, long user_id) {
Set<BillFlow> list = BillFlowCache.getInstance().getByBillType(bill_type);
if (CommUtil.isEmpty(list)) {
@@ -40,7 +49,7 @@ public class ModelProcHelper {
}
}

return ModelProcCache.getInstance().get(pcid);
return getFromCache(pcid);
}

/**
@@ -49,12 +58,12 @@ public class ModelProcHelper {
* @param proc_id
* @return
*/
public static Activity getFirstActivity(String proc_id) {
ModelProc proc = ModelProcCache.getInstance().get(proc_id);
public static Activity getFirstActivity(long proc_id) {
ProcInfo proc = getProcFromCache(proc_id);
if (proc == null) return null;
Activity start = null;
//先找开始节点
List<Activity> list = proc.getProcInfo().getActivities();
List<Activity> list = proc.getActivities();
for (Activity act : list) {
if (act.getType() == FlowConst.ActivityType.START.value) {
start = act;
@@ -64,9 +73,9 @@ public class ModelProcHelper {
if (start == null) return null;

//开始节点出去的第一个节点就是制单节点
for (Trans trans : proc.getProcInfo().getTrans()) {
for (Trans trans : proc.getTrans()) {
if (start.getId().equals(trans.getSrc())) {
return proc.getProcInfo().findActivity(trans.getDst());
return proc.findActivity(trans.getDst());
}
}
return null;
@@ -78,20 +87,21 @@ public class ModelProcHelper {
* @param act_id
* @return
*/
public static Activity getNextActivity(String act_id) throws BizException {
/*Activity act = ActivityBuffer.getInstance().get(act_id);
public static Activity getNextActivity(long proc_id, String act_id) throws BizException {
ProcInfo proc = getProcFromCache(proc_id);
if (proc == null) return null;
Activity act = proc.findActivity(act_id);
if (act == null) {
throw new BizException("未找到指定的活动节点定义!");
}
List<Trans> list = TransBuffer.getInstance().getListByProcId(act.getProcId());
List<Trans> list = proc.getTrans();
for (Trans t : list) {
if (act_id.equals(t.getSrcAct())) {
act = ActivityBuffer.getInstance().get(t.getDstAct());
if (act_id.equals(t.getSrc())) {
act = proc.findActivity(t.getDst());
return act;
}
}
*/
return null;
}

@@ -101,23 +111,23 @@ public class ModelProcHelper {
* @param act_id
* @return
*/
public static List<Trans> getNextTrans(String act_id) throws BizException {
/*Activity act = ActivityBuffer.getInstance().get(act_id);
public static List<Trans> getNextTrans(long proc_id, String act_id) throws BizException {
ProcInfo proc = getProcFromCache(proc_id);
if (proc == null) return null;
Activity act = proc.findActivity(act_id);
if (act == null) {
throw new BizException("未找到指定的活动节点定义!");
}

List<Trans> listRet = new ArrayList<>();
List<Trans> list = TransBuffer.getInstance().getListByProcId(act.getProcId());
List<Trans> list = proc.getTrans();
for (Trans t : list) {
if (act_id.equals(t.getSrcAct())) {
if (act_id.equals(t.getSrc())) {
listRet.add(t);
}
}
listRet.sort(Comparator.comparingInt(Trans::getTransSeq));
listRet.sort(Comparator.comparingInt(Trans::getSeq));
return listRet;
*/
return null;
}

/**
@@ -128,7 +138,7 @@ public class ModelProcHelper {
* @param key 属性名
* @return
*/
public static String getPropStr(String proc_id, String ele_id, String key) {
/*public static String getPropStr(String proc_id, String ele_id, String key) {
// return PropertyEntityBuffer.getInstance().getPropValue(proc_id, ele_id, key);
return null;
}
@@ -141,5 +151,5 @@ public class ModelProcHelper {
public static int getPropInt(String proc_id, String ele_id, String key) {
// return UtilPub.getIntIgnoreErr(getPropStr(proc_id, ele_id, key));
return 0;
}
}*/
}

+ 30
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcLoadHandler.java Ver ficheiro

@@ -0,0 +1,30 @@
package cc.smtweb.system.bpm.web.design.flow;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.mvc.service.DefaultLoadHandler;

/**
* Created by Akmm at 2022/5/9 16:17
*/
public class ModelProcLoadHandler extends DefaultLoadHandler<ModelProc> {
public ModelProcLoadHandler() {
super(ModelProc.ENTITY_NAME);
}

@Override
protected ModelProc loadComp(long id) {
ModelProc bean = super.loadComp(id);
bean.getData().remove("prc_content");
return bean;
}


//页面设计 - 加载页面model定义
public R loadModel() {
long id = params.readLong("id");
ModelProc bean = super.loadComp(id);
if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id);
return R.success(bean.getContent());
}
}

+ 91
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcSaveHandler.java Ver ficheiro

@@ -0,0 +1,91 @@
package cc.smtweb.system.bpm.web.design.flow;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.jdbc.AbsDbWorker;
import cc.smtweb.framework.core.db.vo.ModelField;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.mvc.service.DefaultSaveHandler;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

/**
* Created by Akmm at 2022/5/9 17:05
* 页面定义保存,注意不要覆盖content和dataset
*/
public class ModelProcSaveHandler extends DefaultSaveHandler<ModelProc> {
//自动生成的模块子页面,暂存,便于维护缓存
private List<ModelProc> listFormChild;

public ModelProcSaveHandler() {
super(ModelProc.ENTITY_NAME);
}

@Override
protected void updateBean(EntityDao<ModelProc> dao) {
dao.updateEntityEx(bean, "prc_content");
}

@Override
protected void insertBean(EntityDao<ModelProc> dao) {
super.insertBean(dao);
}


@Override
protected void saveSuccess() {
ModelProcCache.getInstance().put(bean);
if (listFormChild != null) {
for (ModelProc page : listFormChild) {
ModelProcCache.getInstance().put(page);
}
}
}

@Override
protected void saveFailed() {
ModelProcCache.getInstance().reset(bean);
if (listFormChild != null) {
for (ModelProc page : listFormChild) {
ModelProcCache.getInstance().reset(page);
}
}
}

public R saveModel() {
long id = params.readLong("id");
String data = params.readString("data");
bean = loadComp(id);
if (StringUtils.isEmpty(data)) {
throw new BizException("没有待保存的数据!");
}
bean.setContent(data);
DbEngine.getInstance().doTrans(new AbsDbWorker() {
@Override
public void work() {
EntityDao<ModelProc> dao = DbEngine.getInstance().findDao(tableName);

ModelTable table = ModelTableCache.getInstance().getByName(tableName);
ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value);
if (field != null) bean.put(field.getName(), us.getUserId());
dao.updateEntity(bean, "prc_content");
}

@Override
public void doAfterDbCommit() {
saveSuccess();
}

@Override
public void doAfterDbRollback() {
saveFailed();
}
});
return R.success();
}
}

+ 7
- 65
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java Ver ficheiro

@@ -3,23 +3,12 @@ package cc.smtweb.system.bpm.web.design.flow;
import cc.smtweb.framework.core.annotation.SwBody;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.mvc.service.AbstractCompService;
import cc.smtweb.framework.core.mvc.service.AbstractHandler;
import cc.smtweb.framework.core.mvc.service.DefaultDelHandler;
import cc.smtweb.framework.core.mvc.service.DefaultListHandler;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.SqlUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormLoadHandler;
import cc.smtweb.system.bpm.web.design.form.ModelFormSaveHandler;
import org.apache.commons.lang3.StringUtils;

import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

/**
* Created by Akmm at 2022/3/22 9:12
@@ -30,73 +19,26 @@ public class ModelProcService extends AbstractCompService {
protected AbstractHandler createHandler(String type) {
switch (type) {
case TYPE_LOAD:
return new ModelFormLoadHandler();
return new ModelProcLoadHandler();
case TYPE_SAVE:
return new ModelFormSaveHandler();
return new ModelProcSaveHandler();
case TYPE_DEL:
return new DefaultDelHandler<ModelForm>(ModelForm.ENTITY_NAME);
return new DefaultDelHandler<ModelProc>(ModelProc.ENTITY_NAME);
case TYPE_LIST:
return new DefaultListHandler<ModelForm>(ModelForm.ENTITY_NAME);
return new DefaultListHandler<ModelProc>(ModelProc.ENTITY_NAME);

}
return null;
}

//保存数据集
public R saveDataset(@SwBody SwMap params, UserSession us) {
return pageHandler(params, us, TYPE_SAVE, handler -> ((ModelFormSaveHandler)handler).saveDataset());
}

//加载数据集
public R loadDataset(@SwBody SwMap params, UserSession us) {
return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadDataset());
}

//保存页面模型
public R saveModel(@SwBody SwMap params, UserSession us) {
return pageHandler(params, us, TYPE_SAVE, handler -> ((ModelFormSaveHandler)handler).saveModel());
return pageHandler(params, us, TYPE_SAVE, handler -> ((ModelProcSaveHandler)handler).saveModel());
}

//加载页面模型
public R loadModel(@SwBody SwMap params, UserSession us) {
return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadModel());
}

//加载引擎用页面模型
public R model(@SwBody SwMap params, UserSession us) {
return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadForm());
}

//获取页面使用的控件的filter信息
public R loadWidgetFilter(@SwBody SwMap params, UserSession us) {
return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadWidgetFilter());
}

//获取自定义sql的字段信息,去库里查
public R loadSqlFields(@SwBody SwMap params, UserSession us) {
try {
String sql = params.readString("sql");
if (StringUtils.isEmpty(sql)) return R.error("没有传入的sql!");
sql = sql.trim().toLowerCase();
if (!sql.startsWith("select ")) return R.error("非查询类sql,禁止执行!");
if (sql.contains(";")) return R.error("sql内禁止出现分号!");
sql = SqlUtil.replaceTable(sql);
List<SwMap> ret = DbEngine.getInstance().query(sql + " where 1=0", rs -> {
List<SwMap> fields = new ArrayList<>();
ResultSetMetaData metaData = rs.getMetaData();

for (int i = 1, count = metaData.getColumnCount(); i <= count; i++) {
SwMap col = new SwMap(2);
col.put("name", metaData.getColumnLabel(i));
SwEnum.DataTypeBean dtb = SwEnum.DataType.getBySqlType(metaData.getColumnType(i), metaData.getPrecision(i), metaData.getScale(i));
col.put("dataType", dtb.value);
fields.add(col);
}
return fields;
});
return R.success(ret);
} catch (Exception e) {
return R.error("操作失败!", e);
}
return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelProcLoadHandler)handler).loadModel());
}
}

+ 10
- 6
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/AbstractFlowHandler.java Ver ficheiro

@@ -1,6 +1,11 @@
package cc.smtweb.system.bpm.web.engine.flow;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormHelper;
import cc.smtweb.system.bpm.web.engine.dynPage.AbstractDynPageHandler;

/**
@@ -9,11 +14,10 @@ import cc.smtweb.system.bpm.web.engine.dynPage.AbstractDynPageHandler;
* 入参:{pageId, data:}
*/
public class AbstractFlowHandler extends AbstractDynPageHandler {

/**
* 办理签收
*/
public R handle() {
return R.success();
@Override
public void init(SwMap params, UserSession us) {
super.init(params, us);
ModelForm form = ModelFormHelper.getFromCache(pageId);
if (form.getBillType() <= 0L) throw new BizException("此页面非单据页面,不能使用流程服务!");
}
}

+ 13
- 13
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowHelper.java Ver ficheiro

@@ -4,6 +4,7 @@ import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.system.bpm.web.design.flow.FlowConst;
import cc.smtweb.system.bpm.web.design.flow.ModelProcHelper;
import cc.smtweb.system.bpm.web.design.flow.define.Activity;
import cc.smtweb.system.bpm.web.design.flow.define.ProcInfo;
import cc.smtweb.system.bpm.web.design.flow.define.Trans;

import java.util.ArrayList;
@@ -21,7 +22,7 @@ public class FlowHelper {
* @return
*/
public static List<Activity> getNextActivity(FlowInstance flowInstance) throws Exception {
Activity act = ModelProcHelper.getNextActivity(flowInstance.act_inst.getActId());
Activity act = ModelProcHelper.getNextActivity(flowInstance.act_inst.getPrcId(), flowInstance.act_inst.getActId());
if (act == null) {
throw new BizException("未找到可用的活动节点定义!");
}
@@ -37,18 +38,19 @@ public class FlowHelper {
* 递归处理,兼容判断后面加判断,并发后面跟并发
*
* @param act
* @param comp
* @param flowInstance
* @param listRet
* @throws Exception
*/
private static void buildNextActivityRes(Activity act, FlowInstance flowInstance, List<Activity> listRet) throws Exception {
//待返回的结果集
// if (act.getActType() == FlowConst.ActivityType.scriptTask) 自动任务暂不支持
/*if (act.getType() == FlowConst.ActivityType.CONDITION.value) {//条件分支
List<Trans> list = ModelProcHelper.getNextTrans(act.getId());
ProcInfo proc = flowInstance.proc_def.getProcInfo();
if (act.getType() == FlowConst.ActivityType.CONDITION.value) {//条件分支
List<Trans> list = ModelProcHelper.getNextTrans(flowInstance.proc_inst.getPrcId(), act.getId());
for (Trans t : list) {
if (flowInstance.execTrans(t.getExpr())) {
Activity a = ActivityBuffer.getInstance().get(t.getDst());
Activity a = proc.findActivity(t.getDst());
if (a == null) {
throw new BizException("无效的活动节点定义(" + t.getDst() + ")!");
}
@@ -56,22 +58,20 @@ public class FlowHelper {
break;
}
}
} else if (act.getActType() == FlowConst.ActivityType.parallelBegin.value) {//并发分支
List<Trans> list = BillFlowWfHelper.getNextTrans(act.getEntityId());
} else if (act.getType() == FlowConst.ActivityType.PARALLEL.value) {//并发分支
List<Trans> list = ModelProcHelper.getNextTrans(flowInstance.proc_def.getId(), act.getId());
for (Trans t : list) {
if (comp.execTrans(t.getCondExpr())) {
Activity a = ActivityBuffer.getInstance().get(t.getDstAct());
if (flowInstance.execTrans(t.getExpr())) {
Activity a = proc.findActivity(t.getDst());
if (a == null) {
throw new BizException("无效的活动节点定义(" + t.getDstAct() + ")!");
throw new BizException("无效的活动节点定义(" + t.getDst() + ")!");
}
buildNextActivityRes(a, comp, listRet);
buildNextActivityRes(a, flowInstance, listRet);
}
}
} else {
listRet.add(act);
}
*/
}

}

+ 171
- 20
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowInstance.java Ver ficheiro

@@ -1,10 +1,26 @@
package cc.smtweb.system.bpm.web.engine.flow;

import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityHelper;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.NumberUtil;
import cc.smtweb.system.bpm.web.design.flow.FlowConst;
import cc.smtweb.system.bpm.web.design.flow.ModelProc;
import cc.smtweb.system.bpm.web.design.flow.ModelProcHelper;
import cc.smtweb.system.bpm.web.design.flow.define.Activity;
import cc.smtweb.system.bpm.web.engine.flow.define.ProcinstEntity;
import cc.smtweb.system.bpm.web.engine.flow.define.TaskEntity;
import cc.smtweb.system.bpm.web.sys.base.dict.DictCache;
import cc.smtweb.system.bpm.web.sys.user.dept.Dept;
import cc.smtweb.system.bpm.web.sys.user.dept.DeptCache;
import cc.smtweb.system.bpm.web.sys.user.party.Party;
import cc.smtweb.system.bpm.web.sys.user.party.PartyCache;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@@ -13,6 +29,8 @@ import java.util.Map;
* 单据流程实例组件
*/
public class FlowInstance {
//会话信息
private UserSession us;
//流程定义
public ModelProc proc_def;

@@ -23,43 +41,176 @@ public class FlowInstance {
public TaskEntity act_inst;

//操作类型 新增/编辑/查看
public int opt_mode = 0;//CmEnum.OperatorType.VIEW;
public int opt_mode = FlowConst.OperatorType.VIEW;

//流程执行变量
// public Map<String, String> variables = new HashMap<>();

//当前任务
public List<Map<String, String>> tasks = new ArrayList<>();

public FlowInstance() {
// this.context = context;
public FlowInstance(UserSession us) {
this.us = us;
}

//能否编辑
public boolean canEdit() {
// return opt_mode == CmEnum.OperatorType.NEW || proc_inst.getstatu() == FlowConsts.InstanceStatu.BEGIN.value;
//新增状态可以编辑
if (opt_mode == FlowConst.OperatorType.NEW || proc_inst.getStatu() == FlowConst.InstanceStatu.BEGIN.value)
return true;
return false;
}

public boolean notMakeCanEdit() {
/*Map<String, String> mapPermisson = MenuHelper.getPermission(context);
boolean othCanEdit = BillFlowWfHelper.getPropBool(proc_def.getEntityId(), FlowConsts.NULL_STR, FlowConsts.ProcProperty.CAN_EDIT_OTHER);
ActivityEntity act = ActivityEntityBuffer.getInstance().get(act_inst.getActId());
return act != null && !act_inst.isMake() && act.getActEdit() && othCanEdit && MenuHelper.hasPermisson(mapPermisson, CmEnum.MenuFuncRight.UPD.value);*/
return false;
/**
* 流程条件
*
* @param expr
* @return
*/
public boolean execTrans(String expr) {
if (StringUtils.isBlank(expr)) return true;
Map<String, Object> mapVar = new HashMap<>();
/*mapVar.putAll(billEntity.getData());
mapVar.put("party_code", PartyEntityBuffer.getInstance().getCodeById(billEntity.getPartyId()));
mapVar.put("party_name", PartyEntityBuffer.getInstance().getNameById(billEntity.getPartyId()));
mapVar.put("dept_code", DepartmentEntityBuffer.getInstance().getCodeById(billEntity.getDeptId()));
mapVar.put("dept_name", DepartmentEntityBuffer.getInstance().getNameById(billEntity.getDeptId()));
mapVar.put("bill_user_code", UserBaseEntityBuffer.getInstance().getCodeById(billEntity.getBillUser()));
mapVar.put("bill_user_name", UserBaseEntityBuffer.getInstance().getNameById(billEntity.getBillUser()));
localBuildExecTrans(mapVar);*/
Object o = NumberUtil.calcExprMapObject(expr, mapVar);
return o != null && (Boolean) o;
}

public boolean isHandleMake() {
// ActivityEntity act = ActivityEntityBuffer.getInstance().get(act_inst.getActId());
// return !act_inst.isMake() && isHandleMakeEx(act);
return false;
/**
* 新建流程实例
*
* @param bill_type
* @throws Exception
*/
public void create(int bill_type) throws Exception {
Party loginParty = PartyCache.getInstance().get(us.getCompanyId());
if (EntityHelper.isEmpty(loginParty)) {
throw new BizException("当前登录人员管理单位信息为空,请检查后保存!");
}

Dept loginDept = DeptCache.getInstance().get(us.getDeptId());
if (EntityHelper.isEmpty(loginDept)) {
loginDept = new Dept();
}

proc_def = ModelProcHelper.getBillProc(bill_type, us.getUserId()); //根据单据分类获取流程定义
if (EntityHelper.isEmpty(proc_def)) {
// throw new BizException("没有找到对应的流程定义,请到【系统设置】-【单据流程分配】为当前单据类型【" + BillTypeCache.getInstance().getName(bill_type) + "】分配工作流程!");
}

Activity start = ModelProcHelper.getFirstActivity(proc_def.getEntityId());
if (start == null) {
throw new BizException("对应的流程没有定义有效的活动步骤!");
}

opt_mode = FlowConst.OperatorType.NEW;

proc_inst = new ProcinstEntity();
proc_inst.init();
proc_inst.setEntityId(DbEngine.getInstance().nextId());
proc_inst.setPartyId(loginParty.getEntityId());
proc_inst.setDeptId(loginDept.getEntityId());
proc_inst.setBillType(bill_type);
proc_inst.setMakeDate(DateUtil.nowDateTimeLong());
proc_inst.setPrcId(proc_def.getEntityId());
proc_inst.setStartTime(DateUtil.nowDateTimeLong());
proc_inst.setUserId(us.getUserId());
proc_inst.setStatu(FlowConst.InstanceStatu.BEGIN.value);

act_inst = new TaskEntity();
act_inst.init();
act_inst.setEntityId(DbEngine.getInstance().nextId());
act_inst.setId(proc_inst.getEntityId());
act_inst.setPrcId(proc_def.getEntityId());
act_inst.setActId(start.getId());
act_inst.setHandler(us.getUserId());
act_inst.setStartTime(DateUtil.nowDateTimeLong());
act_inst.setStatu(FlowConst.ActivityStatu.HANDLE.value);
act_inst.setMake(true);
act_inst.setSign(false);
act_inst.setReject(false);
act_inst.setRetake(false);

proc_inst.setTaskId(act_inst.getEntityId());
}


private boolean isHandleMakeEx(TaskEntity act) {
// if (EntityUtil.isNull(act)) return false;
// return BillFlowWfHelper.getPropInt(proc_inst.getProcDefId(), act.getActId(), FlowConsts.ProcProperty.HANDLER_RANGE) == CmEnum.HandlerRange.MAKE.value;
return false;
/**
* 办理
*
* @throws Exception
*/
public void handler() {
long user_id = us.getUserId();
//校验权限,当前人员有权限干不,没权限直接抛异常
// checkPermission();
if (act_inst.getStatu() != FlowConst.ActivityStatu.WAIT.value) {
throw new BizException("当前任务非待办状态,不能办理失败!");
}

act_inst.setHandler(user_id);
act_inst.setStartTime(DateUtil.nowDateTimeLong());
act_inst.setStatu(FlowConst.ActivityStatu.HANDLE.value);

proc_inst.setTaskId(act_inst.getEntityId());
proc_inst.setStatu(FlowConst.InstanceStatu.RUNING.value);

DbEngine.getInstance().findDao(TaskEntity.ENTITY_NAME).updateEntity(act_inst);
DbEngine.getInstance().findDao(ProcinstEntity.ENTITY_NAME).updateEntity(proc_inst);

buildBillLog(FlowConst.Button.HANDLE.value, act_inst, null);
// comp.transCallback(CmEnum.FlowOptType.RETAKE.value, act_inst, null);
}


/**
* 状态变更,构建日志
*/
protected void buildBillLog(final String flow_opt, TaskEntity srcTask, List<TaskEntity> dstTasks) {
/*LogEntity logEntity = new LogEntity();
logEntity.setSuggestion(context.getDfpRequest().getParams().getStrIgnoreNull("suggestion"));
logEntity.setFlowOpt(flow_opt);

logEntity.setBillId(proc_inst.getBillId());
logEntity.setOptTime(UtilPub.getLastTime());

UserBaseEntity user = UtilLogin.getLoginUser(context.getLoginInfo());
logEntity.setUserId(user.getEntityId());
logEntity.setUserName(user.getName());
logEntity.setLogId(PKGenerator.newId());
logEntity.setSignPicture(UserBaseEntityBuffer.getInstance().getUserCardEntity(user.getUserId()).getSignPicture());

String src = null, dst = null;
String step_name = null;
StringBuilder sbDst = null;
if (srcTask != null) {
src = ActivityEntityBuffer.getInstance().getNameById(srcTask.getActId());
step_name = ActivityEntityBuffer.getInstance().getStepName(srcTask.getActId());
}
if (UtilPub.isNotEmpty(dstTasks)) {
sbDst = new StringBuilder();
for (ActinstEntity a : dstTasks) {
sbDst.append("/").append(ActivityEntityBuffer.getInstance().getNameById(a.getActId()));
}
dst = sbDst.substring(1);
}
if (flow_opt == CmEnum.FlowOptType.RETAKE.value) {
logEntity.setInfo(dst + "->" + src);
logEntity.setStepName(step_name);
} else if (dst != null) {
logEntity.setInfo(src + "->" + dst);
logEntity.setStepName(step_name);
} else if (src != null) {
logEntity.setInfo(src);
logEntity.setStepName(step_name);
} else {
logEntity.setInfo("-");
}
new LogDao().insert(logEntity);
*/
}
}

+ 15
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowLoadHandler.java Ver ficheiro

@@ -0,0 +1,15 @@
package cc.smtweb.system.bpm.web.engine.flow;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.system.bpm.web.engine.dynPage.AbstractDynPageHandler;
import cc.smtweb.system.bpm.web.engine.dynPage.DynPageLoadHandler;

/**
* Created by Akmm at 2022/4/21 17:53
* 保存指定数据集操作
* 入参:{pageId, data:}
*/
public class FlowLoadHandler extends DynPageLoadHandler {


}

+ 20
- 8
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowService.java Ver ficheiro

@@ -6,16 +6,28 @@ import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.mvc.service.AbstractCompService;
import cc.smtweb.framework.core.mvc.service.AbstractHandler;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.system.bpm.web.engine.dynPage.DynPageDelHandler;
import cc.smtweb.system.bpm.web.engine.dynPage.DynPageLoadHandler;
import cc.smtweb.system.bpm.web.engine.dynPage.DynPageSaveHandler;
import cc.smtweb.system.bpm.web.engine.dynPage.DynPageService;

/**
* Created by Akmm at 2022/5/24 14:21
* 工作流
*/
public class FlowService extends AbstractCompService {
public class FlowService extends DynPageService {
public final static String TYPE_FLOW = "flow";

@Override
protected AbstractHandler createHandler(String type) {
switch (type) {
case TYPE_LOAD:
return new DynPageLoadHandler();
case TYPE_SAVE:
return new DynPageSaveHandler();
case TYPE_DEL:
return new DynPageDelHandler();
}
return null;
}

@@ -33,7 +45,7 @@ public class FlowService extends AbstractCompService {
*
* @throws Exception
*/
public void handle(@SwBody SwMap params, UserSession us) throws Exception {
public void handle(@SwBody SwMap params, UserSession us) {
flowHandler(params, us, FlowHandler::handle);
}

@@ -42,7 +54,7 @@ public class FlowService extends AbstractCompService {
*
* @throws Exception
*/
public void submit(@SwBody SwMap params, UserSession us) throws Exception {
public void submit(@SwBody SwMap params, UserSession us) {
flowHandler(params, us, FlowHandler::handle);
}

@@ -52,7 +64,7 @@ public class FlowService extends AbstractCompService {
*
* @throws Exception
*/
public void checkSubmit(@SwBody SwMap params, UserSession us) throws Exception {
public void checkSubmit(@SwBody SwMap params, UserSession us) {

}

@@ -62,7 +74,7 @@ public class FlowService extends AbstractCompService {
*
* @throws Exception
*/
public void disuse(@SwBody SwMap params, UserSession us) throws Exception {
public void disuse(@SwBody SwMap params, UserSession us) {

}

@@ -72,7 +84,7 @@ public class FlowService extends AbstractCompService {
*
* @throws Exception
*/
public void retake(@SwBody SwMap params, UserSession us) throws Exception {
public void retake(@SwBody SwMap params, UserSession us) {

}

@@ -81,12 +93,12 @@ public class FlowService extends AbstractCompService {
*
* @throws Exception
*/
public void reject(@SwBody SwMap params, UserSession us) throws Exception {
public void reject(@SwBody SwMap params, UserSession us) {

}


public void rejectToMake(@SwBody SwMap params, UserSession us) throws Exception {
public void rejectToMake(@SwBody SwMap params, UserSession us) {

}



+ 1
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskEntity.java Ver ficheiro

@@ -147,7 +147,7 @@ public class TaskEntity extends DefaultEntity {
return getBool("tsk_is_retake");
}

public void setIsRetake(boolean tskIsRetake) {
public void setRetake(boolean tskIsRetake) {
setBool("tsk_is_retake", tskIsRetake);
}



+ 5
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/dict/DictCache.java Ver ficheiro

@@ -31,4 +31,9 @@ public class DictCache extends AbstractEntityCache<Dict> {
public final Dict getByCode(String key) {
return getByKey(mk_code, key);
}

public final String getName(long id) {
Dict bean = get(id);
return bean != null ? bean.getName() : String.valueOf(id);
}
}

+ 9
- 1
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/EntityHelper.java Ver ficheiro

@@ -3,6 +3,7 @@ package cc.smtweb.framework.core.db;
import cc.smtweb.framework.core.cache.AbstractCache;
import cc.smtweb.framework.core.cache.CacheManager;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.db.impl.DefaultEntity;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.framework.core.common.SwMap;
@@ -268,5 +269,12 @@ public class EntityHelper {
return table.getSchemaTableName();
}


/**
* bean是否为空
* @param bean
* @return
*/
public static boolean isEmpty(DefaultEntity bean) {
return bean == null || bean.isEmpty() || bean.getEntityId() <= 0L;
}
}

Carregando…
Cancelar
Guardar