feat(flowable):优化审批流程与界面显示

- 修改审批状态显示格式,增加“审批状态 :”前缀
- 更新流程监听器中用户名拼接符号为顿号“、”
- 在项目信息页面引入bootstrap-select组件支持多选筛选- 调整项目阶段筛选下拉框为多选模式并移除默认选项
-重置按钮功能增强,支持刷新多选组件状态
- 动态加载行业类型下拉列表内容
-修复订单查询时权限SQL拼接问题
- 增加基于数据权限的查询控制注解- 实现通过businessKey追踪流程图接口-优化角色名称及审批人名称连接符为斜杠“/”和顿号“、”
dev_1.0.0
chenhao 2025-10-16 09:05:01 +08:00
parent 1f578c5b8f
commit 25951a668f
11 changed files with 57 additions and 11 deletions

View File

@ -6,6 +6,8 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.sip.flowable.domain.Todo;
import com.ruoyi.sip.flowable.service.TodoService;
import com.ruoyi.system.domain.ActRuExecution;
import com.ruoyi.system.domain.FlowInfo;
import com.ruoyi.system.domain.TaskInfo;
@ -25,6 +27,7 @@ import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.Task;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
@ -68,6 +71,8 @@ public class FlowMonitorController extends BaseController {
private String prefix = "flowable/monitor";
@Autowired
private TodoService todoService;
@GetMapping("/instance")
public String processList() {
@ -278,6 +283,14 @@ public class FlowMonitorController extends BaseController {
public void traceprocess(@RequestParam String processInstanceId, HttpServletResponse response) throws IOException {
activitiTracingChart.generateFlowChart(processInstanceId, response.getOutputStream());
}
@ApiOperation("流程图进度追踪")
@RequestMapping(value = {"/traceProcessKey"}, method = RequestMethod.GET)
public void traceProcessKey(@RequestParam String businessKey, HttpServletResponse response) throws IOException {
Todo todo = new Todo();
todo.setBusinessKey(businessKey);
Todo todo1 = todoService.selectTodo(todo);
activitiTracingChart.generateFlowChart(todo1.getProcessInstanceId(), response.getOutputStream());
}
@ApiOperation("挂起一个流程实例")
@RequestMapping(value = "/suspend/{processInstanceId}", method = RequestMethod.GET)

View File

@ -45,6 +45,7 @@
}
</style>
<body class="gray-bg">
<th:block th:include="include :: bootstrap-select-css" />
<div class="container-div">
<!-- <div th:replace="layout/product-list::configInfoTable('','','')"></div>-->
<div class="row">
@ -67,7 +68,7 @@
<li>
<label>BG</label>
<select name="bgProperty" class="form-control" th:with="type=${@dict.getType('bg_type')}"
onchange="changeBg()" required>
required>
<option value="">请选择BG</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}"></option>
@ -98,9 +99,8 @@
</li>
<li>
<label>项目阶段:</label>
<select name="projectStage" class="form-control"
<select name="projectStage" class="form-control noselect2 selectpicker" data-width="200px" data-none-selected-text="请选择项目阶段" multiple
th:with="type=${@dict.getType('project_stage')}">
<option value="">请选择项目阶段</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}"></option>
</select>
@ -141,7 +141,7 @@
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i
class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i
<a class="btn btn-warning btn-rounded btn-sm" onclick="reset()"><i
class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
@ -172,6 +172,8 @@
</div>
</div>
<th:block th:include="include :: footer"/>
<th:block th:include="include :: bootstrap-select-js" />
<th:block th:include="include :: bootstrap-table-fixed-columns-js" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('sip:project:edit')}]];
@ -179,6 +181,7 @@
var prefix = ctx + "sip/project";
$(function () {
initIndustryType();
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
@ -368,6 +371,10 @@
})
});
function reset(){
$.form.reset()
$('[name="projectStage"]').selectpicker("refresh");
}
function viewDetail(id){
$.modal.openFull("订单详情", prefix + "/view/"+id)
}
@ -414,6 +421,22 @@
}
}
function initIndustryType(){
let datas = [[${@dict.getType('bg_hysy')}]]
datas.push(...[[${@dict.getType('bg_yys')}]])
let str = ``
datas.forEach((ele) => {
str += `<option value="${ele.dictValue}">${ele.dictLabel}</option> `
})
$('#industryTypeBox').html(`
<select name="industryType" class="form-control" required>
<option value="">请选择行业</option>
${str}
</select>
`)
}
function changeBg() {
if ($('[name="bgProperty"]').val() != 'YYS') {
let datas = [[${@dict.getType('bg_hysy')}]]

View File

@ -556,7 +556,7 @@
log.nextAllApproveUserName} ]]</p>
<span class="vertical-date">
<p> <small>[[${#dates.format(log.approveTime,'yyyy-MM-dd HH:mm:ss')}]]</small> <span
style="margin-left: 20px">[ [[${log.roleName}]] / [[${log.approveStatus==3?'批准':log.approveStatus==2?'驳回':'提交审批'}]]]</span></p>
style="margin-left: 20px">审批状态 : [ [[${log.approveStatus==3?'批准':log.approveStatus==2?'驳回':'提交审批'}]] ]</span></p>
</span>
</div>

View File

@ -26,6 +26,7 @@ public class ProjectInfo extends BaseEntity
/** */
private Long id;
private String ids;
/** 项目编码 */
@Excel(name = "项目编号")

View File

@ -27,6 +27,7 @@ public class ProjectOrderInfo extends BaseEntity {
*
*/
private Long id;
private String ids;
/**
*

View File

@ -196,7 +196,7 @@ public class ProcessListener extends AbstractFlowableEngineEventListener {
if (ObjectUtils.isNotEmpty(taskComments)) {
todo.setApproveOpinion(taskComments.get(0).getFullMessage());
}
todo.setAllApproveUserName(todos.stream().map(Todo::getApproveUserName).collect(Collectors.joining(",")));
todo.setAllApproveUserName(todos.stream().map(Todo::getApproveUserName).collect(Collectors.joining("")));
todoService.insertTodoCompleted(Arrays.asList(todo));
log.error("已办任务插入成功 {}", ObjectUtils.isNotEmpty(todo) ? JSON.toJSONString(todo) : "无数据");

View File

@ -149,12 +149,12 @@ public class TodoServiceImpl implements TodoService {
if (CollUtil.isEmpty(roles)) {
return "";
}
return roles.stream().map(SysRole::getRoleName).collect(Collectors.joining(","));
return roles.stream().map(SysRole::getRoleName).collect(Collectors.joining("/"));
}, (v1, v2) -> v1));
for (int i = 0; i < todoCompletedList.size(); i++) {
Todo todoDto = todoCompletedList.get(i);
String nextApproveUserName=i==0?
todoList.stream().map(Todo::getApproveUserName).collect(Collectors.joining(",")) : todoCompletedList.get(i-1).getAllApproveUserName();
todoList.stream().map(Todo::getApproveUserName).collect(Collectors.joining("")) : todoCompletedList.get(i-1).getAllApproveUserName();
todoDto.setNextAllApproveUserName(nextApproveUserName);
todoDto.setRoleName(userRoleMap.get(Long.parseLong(todoDto.getApproveUser())));
}

View File

@ -9,6 +9,7 @@ import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.ServiceException;
@ -126,6 +127,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
* @return
*/
@Override
@DataScope(deptAlias = "t3", userAlias = "t3")
public List<ProjectInfo> selectProjectInfoList(ProjectInfo projectInfo) {
List<ProjectInfo> projectInfos = projectInfoMapper.selectProjectInfoList(projectInfo);
if (CollUtil.isEmpty(projectInfos)){

View File

@ -23,6 +23,7 @@ import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
@ -230,11 +231,14 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
* @return
*/
@Override
@DataScope(deptAlias = "t5", userAlias = "t5")
public List<ProjectOrderInfo> selectProjectOrderInfoList(ProjectOrderInfo projectOrderInfo) {
SysUser sysUser = getSysUser();
boolean showLog = false;
if (sysUser.getDept() != null && sysUser.getDept().getAncestors().startsWith("0,100,200")) {
StringBuilder authSql = new StringBuilder();
//只查看已审批
authSql.append(" and t1.order_status = '").append(ProjectOrderInfo.OrderStatus.APPROVE_COMPLETE.getCode()).append("'");
if ("总代".equals(sysUser.getDept().getDeptName())) {
//总代
authSql.append(" and ( ");
@ -242,7 +246,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
authSql.append(" )");
} else {
showLog = true;
authSql.append(" and t1.partner_code in (");
authSql.append(" and t1.partner_code in (");
authSql.append(" select partner_code from partner_info where system_user_id = ").append(sysUser.getUserId());
authSql.append(" )");
}

View File

@ -87,6 +87,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectRelationProjectInfoVo"/>
<where>
<if test="projectCode != null and projectCode != ''"> and t1.project_code = #{projectCode}</if>
<if test="ids != null and ids != ''"> and find_in_set(t1.id, #{ids})</if>
<if test="projectName != null and projectName != ''"> and t1.project_name like concat('%', #{projectName}, '%')</if>
<if test="poc != null and poc != ''"> and t1.poc =#{poc}</if>
<if test="customerCode != null and customerCode != ''"> and t1.customer_code = #{customerCode}</if>
@ -96,7 +97,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="industryType != null and industryType != ''"> and t1.industry_type = #{industryType}</if>
<if test="bgProperty != null and bgProperty != ''"> and t1.bg_property = #{bgProperty}</if>
<if test="projectStage != null and projectStage != ''"> and t1.project_stage = #{projectStage}</if>
<if test="projectStage != null and projectStage != ''"> and find_in_set(t1.project_stage , #{projectStage})</if>
<if test="projectGraspDegree != null and projectGraspDegree != ''"> and t1.project_grasp_degree = #{projectGraspDegree}</if>
<if test="hzSupportUser != null and hzSupportUser != ''"> and t1.hz_support_user = #{hzSupportUser}</if>
<if test="hzSupportUserName != null and hzSupportUserName != ''"> and t3.user_name like concat('%', #{hzSupportUserName}, '%')</if>
@ -172,6 +173,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="serverConfiguration != null and serverConfiguration != ''"> and t1.server_configuration = #{serverConfiguration}</if>
<if test="keyProblem != null and keyProblem != ''"> and t1.key_problem = #{keyProblem}</if>
<if test="projectDesc != null and projectDesc != ''"> and t1.project_desc = #{projectDesc}</if>
${params.dataScope}
</where>
order by t1.project_code desc
</select>

View File

@ -208,7 +208,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
)
</if>
${params.authSql}
${params.dataScope}
</select>
<select id="selectProjectOrderInfoById" parameterType="Long" resultMap="ProjectOrderInfoResult">