1、修改了流程步骤抄送设置为步骤处理人时的异常。
修改文件:src/main/java/cn/tzsoft/roadflow/service/flow/FlowRunService.java

//步骤处理人
JsonNode handlerSteps = JSONUtils.getJsonNode(stepCopyForJsonNode, "handlerSteps");
if (handlerSteps != null) {
for (JsonNode handlerStep : handlerSteps) {
long stepId = NumberUtils.toLong(JSONUtils.getText(handlerStep));
List<FlowTaskModel> flowTaskModels = flowGroupTasks.stream().filter(s -> s.getStepId().equals(stepId) && s.getType() != 5 && s.getType() != 11)
.collect(Collectors.toList());
if (flowTaskModels.isEmpty()) {
continue;
}
FlowTaskModel maxReceiveFlowTaskModel = flowTaskModels.stream()
.max(Comparator.comparing(FlowTaskModel::getReceiveOrder, Comparator.nullsFirst(Integer::compareTo))).orElse(null);
flowTaskModels.stream().filter(s -> s.getReceiveOrder().equals(maxReceiveFlowTaskModel.getReceiveOrder())).forEach(taskModel -> {
stringJoiner.add(userService.getPrefixId(taskModel.getReceiverId(), taskModel.getPartTimeId()));
});
}
}2、修改了流程任务处理后将消息中心对应的消息标记为已读。
修改文件:src/main/java/cn/tzsoft/roadflow/dao/message/MessageDao.java

修改文件:src/main/java/cn/tzsoft/roadflow/service/message/MessageService.java

修改文件:src/main/java/cn/tzsoft/roadflow/service/flow/FlowExecuteService.java

3、应用设计增加了小计合计。
修改文件:src/web/element/src/roadui-pages/app-design/design/list.vue



修改文件:src/web/element/src/roadui-pages/app-design/design/design.js


修改文件:src/web/element/src/roadui-pages/app-design/run/index.vue



修改文件:src/main/java/cn/tzsoft/roadflow/service/appdesign/AppDesignRunService.java



/**
* 得到运行时列表查询数据
*
* @param request HttpServletRequest
* @param isExportExcel 是否是导出excel
* @param selectRowIds 导出excel时选择的行
* @return Pair-ObjectNode{total:总条数,records:记录列表};AppDesignRunModel
*/
public Pair<ObjectNode, AppDesignRunModel> getListData(HttpServletRequest request, boolean isExportExcel, List<String> selectRowIds) {
ObjectMapper objectMapper = JSONUtils.getObjectMapper();
ObjectNode objectNode = objectMapper.createObjectNode();
ArrayNode arrayNode = objectMapper.createArrayNode();
//应用id
Long appDesignId = IdGeneratorUtils.getValue(request.getParameter("appDesignId"));
AppDesignRunModel appDesignRunModel = get(appDesignId);
if (appDesignRunModel == null) {
objectNode.put("total", 0);
objectNode.set("records", arrayNode);
return Pair.of(objectNode, null);
}
//验证应用授权
if (isNotAuth(appDesignRunModel, userService.getLoginUserId(request))) {
objectNode.put("total", 0);
objectNode.set("records", arrayNode);
return Pair.of(objectNode, null);
}
JsonNode attrJsonNode = JSONUtils.parseJsonNode(appDesignRunModel.getAttrSet());
Long connId = JSONUtils.getRefLong(attrJsonNode, "connId", IdGeneratorUtils.MIN_VALUE);
ConnModel connModel = connService.getById(connId);
if (connModel == null) {
objectNode.put("total", 0);
objectNode.set("records", arrayNode);
return Pair.of(objectNode, null);
}
JsonNode leftJsonNode = StringUtils.equals("1", request.getParameter("isLeftQuery")) ? JSONUtils.parseJsonNode(appDesignRunModel.getLeftSet()) : null;//左栏树节点点击的查询
ArrayNode listJsonNode = JSONUtils.parseArrayNode(appDesignRunModel.getListSet());
ArrayNode queryJsonNode = JSONUtils.parseArrayNode(appDesignRunModel.getQuerySet());
int number = NumberUtils.toInt(request.getParameter("number"), 1);
int size = NumberUtils.toInt(request.getParameter("size"), 10);
String order = request.getParameter("order");
if (StringUtils.isBlank(order)) {
//如果排序为空,则使用应用属性中设置的默认排序。
order = JSONUtils.getString(attrJsonNode, "defaultSort");
}
//是否要转换参数类型,pgSql要转换。
boolean isSerializable = MybatisPlusConfig.getDbType(connModel.getType()) == DbType.POSTGRE_SQL;
String fields = "";
String sql = wildcardService.replace(JSONUtils.getString(attrJsonNode, "sqlString"));
int total;
List<LinkedHashMap<String, Object>> records;
boolean isPager = !isExportExcel && JSONUtils.getInt(attrJsonNode, "isPager", 0) == 1;//是否分页,如果是导出不分页
Map<String, Object> paramsMap;
//如果是导出excel又选择了导出列,则只查询选择的列。
if (isExportExcel && selectRowIds != null && !selectRowIds.isEmpty()) {
String selectKey = JSONUtils.getString(attrJsonNode, "selectKey");
paramsMap = new HashMap<>();
Map<String, Object> wheresInMap = new HashMap<>();
if (isSerializable) {
//pgSql要判断主键类型
List<Object> selectRowObjectList = new ArrayList<>();
for (String selectId : selectRowIds) {
selectRowObjectList.add(formService.getObjectValue(selectId));
}
wheresInMap.put(" AND " + (StringUtils.isBlank(selectKey) ? "id" : selectKey), selectRowObjectList);
} else {
wheresInMap.put(" AND " + (StringUtils.isBlank(selectKey) ? "id" : selectKey), selectRowIds);
}
paramsMap.put("wheresIn", wheresInMap);
} else {
paramsMap = getQueryParamsMap(queryJsonNode, leftJsonNode, isSerializable, request);
}
if (isPager) {
//分页查询
PageInfo<LinkedHashMap<String, Object>> pageInfo = connService.getMapPage(connModel, number, size, sql, fields, order, paramsMap);
total = (int) pageInfo.getTotal();
records = pageInfo.getList();
} else {
//不分页查询所有
records = connService.getMapPage(connModel, sql, fields, order, paramsMap);
total = records.size();
}
Map<String, Pair<BigDecimal, String>> subTotalMap = new HashMap<>();//小计Map<字段,Pair<小计值,格式字符串>>
Map<String, Pair<BigDecimal, String>> sumTotalMap = new HashMap<>();//合计Map<字段,Pair<合计值,格式字符串>>
if (listJsonNode != null) {
for (JsonNode fJsonNode : listJsonNode) {
if (JSONUtils.getInt(fJsonNode, "subTotal") == 1) {
subTotalMap.put(JSONUtils.getString(fJsonNode, "fieldName"), Pair.of(BigDecimal.ZERO, JSONUtils.getString(fJsonNode, "showFormat")));
}
if (JSONUtils.getInt(fJsonNode, "sumTotal") == 1) {
sumTotalMap.put(JSONUtils.getString(fJsonNode, "fieldName"), Pair.of(BigDecimal.ZERO, JSONUtils.getString(fJsonNode, "showFormat")));
}
}
}
for (LinkedHashMap<String, Object> linkedHashMap : records) {
ObjectNode rowObjectNode = objectMapper.createObjectNode();
for (Map.Entry<String, Object> entry : linkedHashMap.entrySet()) {
Object obj = entry.getValue();
Object valueObject = obj;
if (MybatisPlusConfig.getDbType(connModel.getType()) == DbType.ORACLE) {
if (obj instanceof Clob) {
valueObject = StringUtils.getClobString((Clob) obj);
} else if (obj instanceof Blob) {
valueObject = StringUtils.getBlobString((Blob) obj);
}
}
String fieldName = entry.getKey();
setListObjectNodeValue(objectMapper, rowObjectNode, listJsonNode, fieldName, valueObject, linkedHashMap);
//计算页小计
if (subTotalMap.size() > 0 && subTotalMap.containsKey(fieldName)) {
subTotalMap.put(fieldName, Pair.of(subTotalMap.get(fieldName).getLeft().add(NumberUtils.toBigDecimal(StringUtils.objectToString(valueObject), BigDecimal.ZERO)), subTotalMap.get(fieldName).getRight()));
}
}
arrayNode.add(rowObjectNode);
}
//组织小计ObjectNode
ObjectNode subTotalObjectNode = objectMapper.createObjectNode();
for (Map.Entry<String, Pair<BigDecimal, String>> entry : subTotalMap.entrySet()) {
subTotalObjectNode.put(entry.getKey(), StringUtils.isBlank(entry.getValue().getRight())
? entry.getValue().getLeft().toPlainString()
: NumberUtils.formatBigDecimal(entry.getValue().getLeft(), entry.getValue().getRight()));
}
//查询合计
ObjectNode sumTotalObjectNode = objectMapper.createObjectNode();
if (sumTotalMap.size() > 0) {
StringJoiner fieldStringJoiner = new StringJoiner(",");
for (Map.Entry<String, Pair<BigDecimal, String>> entry : sumTotalMap.entrySet()) {
fieldStringJoiner.add("SUM(" + entry.getKey() + ") AS " + entry.getKey());
}
List<LinkedHashMap<String, Object>> sumList = null;
try {
sumList = connService.getMapPage(connModel, sql, fieldStringJoiner.toString(), "", paramsMap);
} catch (Exception e) {
logService.add(e);
}
if (sumList != null && sumList.size() > 0) {
for (Map.Entry<String, Pair<BigDecimal, String>> entry : sumTotalMap.entrySet()) {
String sumValue = StringUtils.objectToString(sumList.get(0).get(entry.getKey()));
String showFormat = entry.getValue().getRight();
sumTotalObjectNode.put(entry.getKey(), StringUtils.isBlank(showFormat)
? StringUtils.isBlank(sumValue) ? "0" : sumValue
: NumberUtils.formatBigDecimal(NumberUtils.toBigDecimal(sumValue, BigDecimal.ZERO), showFormat));
}
}
}
objectNode.put("total", total);
objectNode.set("records", arrayNode);
objectNode.set("subTotal", subTotalObjectNode);
objectNode.set("sumTotal", sumTotalObjectNode);
return Pair.of(objectNode, appDesignRunModel);
}4、增加我的发起流程中可以复制重新发起功能。
修改文件:src/web/element/src/roadui-pages/flow/run/my-start.vue

<el-button size="small" :disabled="loading" type="success" @click="copyStart(scope.row)" style="vertical-align:middle;"> <i class="rf_button_icon_in_min icon-edit-line"></i></el-button>

//复制一份表单数据再发起流程
const copyStart = (task) => {
utils.confirm('您确定要复制并发起流程吗?', () => {
loading.value = true;
ajax.post('/flow/flow/copyMyStart?groupId=' + task.groupId).then((res) => {
if (res.code === 0) {
const newTask = res.data;
const menu = {
id: 'flow_run_' + newTask.id,
name: newTask.title,
icon: 'icon-draft-line',
url: '/flow/run/index.vue?flowId=' + newTask.flowId + '&flowVersionId=' + newTask.flowVersionId + '&stepId=' + newTask.stepId + '&taskId=' + newTask.id + '&instanceId=' + newTask.instanceId + '&groupId=' + newTask.groupId,
openMode: 0
};
index_openPage(menu);
} else {
let msg = '操作失败!';
if (res.code === 1) {
msg = '没有找到任务!';
} else if (res.code === 2) {
msg = '未找到流程运行时实体!';
}
utils.msg(msg, false);
}
loading.value = false;
}).catch(() => {
loading.value = false;
});
});
};修改文件:src/main/java/cn/tzsoft/roadflow/controller/roadflowwebapi/flow/FlowController.java

/**
* 复制我的发起流程再次发起流程
*
* @param groupId 任务组id
* @param request HttpServletRequest
* @return ResponseResult
*/
@PostMapping(value = "copyMyStart")
@UserAuthorize
public ResponseResult copyMyStart(Long groupId, HttpServletRequest request) {
List<FlowTaskModel> flowTaskGroupList = flowTaskService.getListByGroupId(groupId, -1);
List<FlowTaskModel> flowTaskFirstList = flowTaskService.getFirstTasks(flowTaskGroupList);
if (flowTaskFirstList.isEmpty()) {
return ResponseResult.error(1);
}
FlowTaskModel flowTaskModel = flowTaskFirstList.get(0);
JsonNode flowJsonNode = flowVersionService.getFlowJsonNodeById(flowTaskModel.getFlowVersionId());
if (flowJsonNode == null) {
return ResponseResult.error(2);
}
JsonNode flowAttrJsonNode = JSONUtils.getJsonNode(flowJsonNode, "attr");
Long startStepId = JSONUtils.getRefLong(flowAttrJsonNode, "startStepId");
JsonNode stepSetJsonNode = flowService.getStepSet(startStepId, flowJsonNode);
JsonNode stepBaseJsonNode = JSONUtils.getJsonNode(stepSetJsonNode, "base");
Long appId = JSONUtils.getRefLong(stepBaseJsonNode, "appId");
JsonNode formTemplateJsonNode = formService.getTemplateByAppId(appId);
JsonNode dbJsonNode = JSONUtils.getJsonNode(formTemplateJsonNode, "db");
JsonNode fieldsJsonNode = JSONUtils.getJsonNode(formTemplateJsonNode, "fields");
JsonNode subTablesJsonNode = JSONUtils.getJsonNode(formTemplateJsonNode, "subTables");
Long formId = JSONUtils.getRefLong(formTemplateJsonNode, "id");
ObjectNode formData = formService.getFormData(dbJsonNode, fieldsJsonNode, flowTaskModel.getInstanceId(), subTablesJsonNode, null, formId, 0);
//清空formData中的流水号,保存数据时重新生成。
JsonNode serialNumberJsonNode = JSONUtils.getJsonNode(formTemplateJsonNode, "serialNumber");
if (serialNumberJsonNode != null) {
for (JsonNode serialJsonNode : serialNumberJsonNode) {
String fieldId = JSONUtils.getString(serialJsonNode, "id");
if (StringUtils.isNotBlank(fieldId)) {
formData.put(fieldId, "");
}
}
}
Pair<Long, String> userPair = userService.getLoginUserIdName(request);
ObjectMapper objectMapper = JSONUtils.getObjectMapper();
ObjectNode paramsObjectNode = objectMapper.createObjectNode();
paramsObjectNode.put("type", "save")
.put("flowId", NumberUtils.longToString(flowTaskModel.getFlowId()))
.put("flowVersionId", NumberUtils.longToString(flowTaskModel.getFlowVersionId()))
.put("stepId", NumberUtils.longToString(startStepId))
.put("taskId", "")
.put("groupId", "")
.put("instanceId", "")
.put("title", flowTaskModel.getTitle())
.put("senderId", NumberUtils.longToString(userPair.getLeft()))
.put("senderName", userPair.getRight());
ObjectNode resultObjectNode = flowExecuteService.execute(paramsObjectNode, formData);
int code = JSONUtils.getInt(resultObjectNode, "code");
if (code != 0) {
return ResponseResult.error(code);
}
JsonNode currentTaskJsonNode = JSONUtils.getJsonNode(resultObjectNode, "currentTask");
return ResponseResult.success(currentTaskJsonNode);
}5、增加了应用设计列显示内容过长是否隐藏设置。
修改文件:src/web/element/src/roadui-pages/app-design/design/list.vue

修改文件:src/web/element/src/roadui-pages/app-design/design/design.js

6、增加了应用设计导出时设置导入转换类型。
表rf_design_export增加字段:

实体类修改:src/main/java/cn/tzsoft/roadflow/model/appdesign/AppDesignExportModel.java

修改文件:src/web/element/src/roadui-pages/app-design/design/export.vue

修改文件:src/web/element/src/roadui-pages/app-design/design/design.js

修改文件:src/main/java/cn/tzsoft/roadflow/controller/roadflowwebapi/appdesign/AppDesignRunController.java


7、修改了HTML富文本编辑器为Tinymce。
安装组件:npm install @tinymce/tinymce-vue@6.0.1
卸载组件:npm uninstall @wangeditor/editor-for-vue
修改文件:src/web/element/src/roadui-components/rf-editor.vue
增加目录及文件:src/web/element/public/tinymce
修改文件:src/web/element/index.html


修改文件:src/web/element/src/roadui-pages/form/design/controls/editor-ctl.vue


修改文件:src/web/element/src/roadui-pages/form/design/design.js

|
联系QQ:493501010电话:136 0832 5512(微信同号)邮箱:road@roadflow.net
Copyright 2014 - 2025 重庆天知软件技术有限公司 版权所有
|