@@ -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); | |||
@@ -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-结束任务 | |||
@@ -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); | |||
@@ -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; | |||
} | |||
}*/ | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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("此页面非单据页面,不能使用流程服务!"); | |||
} | |||
} |
@@ -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); | |||
} | |||
*/ | |||
} | |||
} |
@@ -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); | |||
*/ | |||
} | |||
} |
@@ -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 { | |||
} |
@@ -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) { | |||
} | |||
@@ -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); | |||
} | |||
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |