yxk-20260715
在流程详情弹窗中新增 增补审批意见 tab,仅从 我的待阅、我的已阅、我的已办 三类入口打开时显示。 用户提交后只写入 task_approval_opinion,不写 Flowable 原生历史/评论表,也不写旧流程日志表。 提交成功后刷新 审批历史,新增意见可在审批历史中看到。
This commit is contained in:
+15
@@ -14,6 +14,7 @@ import org.jeecg.common.api.vo.Result;
|
|||||||
import org.jeecg.common.system.query.QueryGenerator;
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.taskapprovalopinion.dto.SupplementApprovalOpinionDTO;
|
||||||
import org.jeecg.modules.taskapprovalopinion.entity.TaskApprovalOpinion;
|
import org.jeecg.modules.taskapprovalopinion.entity.TaskApprovalOpinion;
|
||||||
import org.jeecg.modules.taskapprovalopinion.service.ITaskApprovalOpinionService;
|
import org.jeecg.modules.taskapprovalopinion.service.ITaskApprovalOpinionService;
|
||||||
|
|
||||||
@@ -95,6 +96,20 @@ public class TaskApprovalOpinionController extends JeecgController<TaskApprovalO
|
|||||||
return Result.OK("添加成功!");
|
return Result.OK("添加成功!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增补审批意见,只写入 task_approval_opinion。
|
||||||
|
*
|
||||||
|
* @param supplementDTO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@AutoLog(value = "task_approval_opinion-增补审批意见")
|
||||||
|
@Operation(summary="task_approval_opinion-增补审批意见")
|
||||||
|
@PostMapping(value = "/supplement")
|
||||||
|
public Result<String> supplement(@RequestBody SupplementApprovalOpinionDTO supplementDTO) {
|
||||||
|
taskApprovalOpinionService.saveSupplementOpinion(supplementDTO);
|
||||||
|
return Result.OK("提交成功!");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
*
|
*
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
package org.jeecg.modules.taskapprovalopinion.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增补审批意见提交参数。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "增补审批意见提交参数")
|
||||||
|
public class SupplementApprovalOpinionDTO implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "流程实例ID")
|
||||||
|
private String processInstId;
|
||||||
|
|
||||||
|
@Schema(description = "Flowable任务ID")
|
||||||
|
private String flowTaskId;
|
||||||
|
|
||||||
|
@Schema(description = "流程节点Key")
|
||||||
|
private String taskDefKey;
|
||||||
|
|
||||||
|
@Schema(description = "事项任务ID,对应task_task.id")
|
||||||
|
private String taskTaskId;
|
||||||
|
|
||||||
|
@Schema(description = "关联业务ID")
|
||||||
|
private String businessId;
|
||||||
|
|
||||||
|
@Schema(description = "流程编码")
|
||||||
|
private String flowCode;
|
||||||
|
|
||||||
|
@Schema(description = "增补审批意见")
|
||||||
|
private String opinion;
|
||||||
|
}
|
||||||
+5
@@ -1,10 +1,15 @@
|
|||||||
package org.jeecg.modules.taskapprovalopinion.service;
|
package org.jeecg.modules.taskapprovalopinion.service;
|
||||||
|
|
||||||
import org.jeecg.modules.taskapprovalopinion.entity.TaskApprovalOpinion;
|
import org.jeecg.modules.taskapprovalopinion.entity.TaskApprovalOpinion;
|
||||||
|
import org.jeecg.modules.taskapprovalopinion.dto.SupplementApprovalOpinionDTO;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审批意见快照 Service。
|
* 审批意见快照 Service。
|
||||||
*/
|
*/
|
||||||
public interface ITaskApprovalOpinionService extends IService<TaskApprovalOpinion> {
|
public interface ITaskApprovalOpinionService extends IService<TaskApprovalOpinion> {
|
||||||
|
/**
|
||||||
|
* 保存增补审批意见,仅写入 task_approval_opinion。
|
||||||
|
*/
|
||||||
|
void saveSupplementOpinion(SupplementApprovalOpinionDTO supplementDTO);
|
||||||
}
|
}
|
||||||
|
|||||||
+203
@@ -1,14 +1,217 @@
|
|||||||
package org.jeecg.modules.taskapprovalopinion.service.impl;
|
package org.jeecg.modules.taskapprovalopinion.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.jeecg.common.exception.JeecgBootException;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.extbpm.process.entity.ExtActFlowData;
|
||||||
|
import org.jeecg.modules.extbpm.process.mapper.ExtActFlowDataMapper;
|
||||||
|
import org.jeecg.modules.taskapprovalopinion.dto.SupplementApprovalOpinionDTO;
|
||||||
import org.jeecg.modules.taskapprovalopinion.entity.TaskApprovalOpinion;
|
import org.jeecg.modules.taskapprovalopinion.entity.TaskApprovalOpinion;
|
||||||
import org.jeecg.modules.taskapprovalopinion.mapper.TaskApprovalOpinionMapper;
|
import org.jeecg.modules.taskapprovalopinion.mapper.TaskApprovalOpinionMapper;
|
||||||
import org.jeecg.modules.taskapprovalopinion.service.ITaskApprovalOpinionService;
|
import org.jeecg.modules.taskapprovalopinion.service.ITaskApprovalOpinionService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审批意见快照 Service 实现。
|
* 审批意见快照 Service 实现。
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class TaskApprovalOpinionServiceImpl extends ServiceImpl<TaskApprovalOpinionMapper, TaskApprovalOpinion> implements ITaskApprovalOpinionService {
|
public class TaskApprovalOpinionServiceImpl extends ServiceImpl<TaskApprovalOpinionMapper, TaskApprovalOpinion> implements ITaskApprovalOpinionService {
|
||||||
|
private static final String RECORD_TYPE_SUPPLEMENT = "SUPPLEMENT";
|
||||||
|
private static final String SUPPLEMENT_TASK_NAME = "增补审批意见";
|
||||||
|
private static final String SUPPLEMENT_ACTION_TYPE = "增补";
|
||||||
|
private static final String SUPPLEMENT_ACTION_RESULT = "增补审批意见";
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseAPI;
|
||||||
|
@Autowired
|
||||||
|
private ExtActFlowDataMapper extActFlowDataMapper;
|
||||||
|
@Autowired(required = false)
|
||||||
|
private JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存增补审批意见。该入口只写 task_approval_opinion,不触碰 Flowable 原生表或旧流程日志表。
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void saveSupplementOpinion(SupplementApprovalOpinionDTO supplementDTO) {
|
||||||
|
if (supplementDTO == null || oConvertUtils.isEmpty(supplementDTO.getProcessInstId())) {
|
||||||
|
throw new JeecgBootException("流程实例ID不能为空");
|
||||||
|
}
|
||||||
|
String opinionText = supplementDTO.getOpinion() == null ? null : supplementDTO.getOpinion().trim();
|
||||||
|
if (oConvertUtils.isEmpty(opinionText)) {
|
||||||
|
throw new JeecgBootException("增补审批意见不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginUser loginUser = getCurrentLoginUser();
|
||||||
|
Date now = new Date();
|
||||||
|
ApprovalDeptInfo deptInfo = resolveCurrentApprovalDept(loginUser, loginUser.getUsername());
|
||||||
|
|
||||||
|
TaskApprovalOpinion opinion = new TaskApprovalOpinion();
|
||||||
|
opinion.setRecordType(RECORD_TYPE_SUPPLEMENT);
|
||||||
|
opinion.setTaskTaskId(supplementDTO.getTaskTaskId());
|
||||||
|
opinion.setBusinessId(supplementDTO.getBusinessId());
|
||||||
|
opinion.setFlowCode(supplementDTO.getFlowCode());
|
||||||
|
opinion.setProcessInstId(supplementDTO.getProcessInstId());
|
||||||
|
opinion.setFlowTaskId(supplementDTO.getFlowTaskId());
|
||||||
|
opinion.setTaskDefKey(supplementDTO.getTaskDefKey());
|
||||||
|
opinion.setTaskName(SUPPLEMENT_TASK_NAME);
|
||||||
|
opinion.setActionType(SUPPLEMENT_ACTION_TYPE);
|
||||||
|
opinion.setActionResult(SUPPLEMENT_ACTION_RESULT);
|
||||||
|
opinion.setOpinion(opinionText);
|
||||||
|
opinion.setOpUserId(loginUser.getUsername());
|
||||||
|
opinion.setOpUserName(oConvertUtils.isNotEmpty(loginUser.getRealname()) ? loginUser.getRealname() : loginUser.getUsername());
|
||||||
|
opinion.setOpDeptId(deptInfo.id);
|
||||||
|
opinion.setOpDeptName(deptInfo.name);
|
||||||
|
opinion.setOpDeptCode(deptInfo.code);
|
||||||
|
opinion.setStartTime(now);
|
||||||
|
opinion.setOpTime(now);
|
||||||
|
opinion.setDelFlag("0");
|
||||||
|
opinion.setCreateBy(loginUser.getUsername());
|
||||||
|
opinion.setCreateTime(now);
|
||||||
|
opinion.setSysOrgCode(deptInfo.code);
|
||||||
|
|
||||||
|
fillBusinessSnapshot(opinion);
|
||||||
|
save(opinion);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoginUser getCurrentLoginUser() {
|
||||||
|
Object principal = SecurityUtils.getSubject().getPrincipal();
|
||||||
|
if (principal instanceof LoginUser) {
|
||||||
|
return (LoginUser) principal;
|
||||||
|
}
|
||||||
|
throw new JeecgBootException("未获取到当前登录用户");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优先记录当前登录部门,避免多部门用户写入第一个所属部门导致审批历史筛选不准。
|
||||||
|
*/
|
||||||
|
private ApprovalDeptInfo resolveCurrentApprovalDept(LoginUser user, String username) {
|
||||||
|
String deptId = user != null ? user.getOrgId() : null;
|
||||||
|
String deptCode = user != null ? user.getOrgCode() : null;
|
||||||
|
String deptName = null;
|
||||||
|
|
||||||
|
if (oConvertUtils.isNotEmpty(deptCode)) {
|
||||||
|
try {
|
||||||
|
List<JSONObject> departs = sysBaseAPI.queryDepartsByOrgcodes(deptCode);
|
||||||
|
if (departs != null && !departs.isEmpty()) {
|
||||||
|
JSONObject depart = departs.get(0);
|
||||||
|
if (oConvertUtils.isEmpty(deptId)) {
|
||||||
|
deptId = depart.getString("id");
|
||||||
|
}
|
||||||
|
deptName = depart.getString("departName");
|
||||||
|
if (oConvertUtils.isEmpty(deptName)) {
|
||||||
|
deptName = depart.getString("depart_name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("获取当前登录部门失败, username={}, orgCode={}", username, deptCode, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oConvertUtils.isEmpty(deptName) && oConvertUtils.isNotEmpty(username)) {
|
||||||
|
deptName = resolveDeptName(username);
|
||||||
|
}
|
||||||
|
return new ApprovalDeptInfo(deptId, deptName, deptCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveDeptName(String username) {
|
||||||
|
try {
|
||||||
|
List<String> names = sysBaseAPI.getDepartNamesByUsername(username);
|
||||||
|
if (names != null && !names.isEmpty()) {
|
||||||
|
return names.get(0);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("获取部门名称失败, username={}", username, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillBusinessSnapshot(TaskApprovalOpinion opinion) {
|
||||||
|
ExtActFlowData flowData = queryFlowData(opinion.getProcessInstId());
|
||||||
|
if (flowData != null) {
|
||||||
|
if (oConvertUtils.isEmpty(opinion.getTaskTaskId())) {
|
||||||
|
opinion.setTaskTaskId(flowData.getFormDataId());
|
||||||
|
}
|
||||||
|
if (oConvertUtils.isEmpty(opinion.getFlowCode())) {
|
||||||
|
opinion.setFlowCode(flowData.getRelationCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fillTaskTaskFields(opinion);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExtActFlowData queryFlowData(String processInstanceId) {
|
||||||
|
if (oConvertUtils.isEmpty(processInstanceId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<ExtActFlowData> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(ExtActFlowData::getProcessInstId, processInstanceId);
|
||||||
|
List<ExtActFlowData> flowDataList = extActFlowDataMapper.selectList(queryWrapper);
|
||||||
|
return flowDataList.isEmpty() ? null : flowDataList.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task_task 属于业务侧表,这里只做可选字段补齐,补齐失败不影响增补意见保存。
|
||||||
|
*/
|
||||||
|
private void fillTaskTaskFields(TaskApprovalOpinion opinion) {
|
||||||
|
if (jdbcTemplate == null || oConvertUtils.isEmpty(opinion.getTaskTaskId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<Map<String, Object>> rows = jdbcTemplate.queryForList(
|
||||||
|
"select business_id, flow_code, sys_org_code from task_task where id = ?",
|
||||||
|
opinion.getTaskTaskId());
|
||||||
|
if (rows.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<String, Object> row = rows.get(0);
|
||||||
|
if (oConvertUtils.isEmpty(opinion.getBusinessId())) {
|
||||||
|
opinion.setBusinessId(getStringValue(row, "business_id"));
|
||||||
|
}
|
||||||
|
if (oConvertUtils.isEmpty(opinion.getFlowCode())) {
|
||||||
|
opinion.setFlowCode(getStringValue(row, "flow_code"));
|
||||||
|
}
|
||||||
|
if (oConvertUtils.isEmpty(opinion.getSysOrgCode())) {
|
||||||
|
opinion.setSysOrgCode(getStringValue(row, "sys_org_code"));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("补全 task_task 业务字段失败,跳过。taskTaskId={}", opinion.getTaskTaskId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStringValue(Map<String, Object> row, String key) {
|
||||||
|
for (Map.Entry<String, Object> entry : row.entrySet()) {
|
||||||
|
if (entry.getKey() != null && entry.getKey().equalsIgnoreCase(key) && entry.getValue() != null) {
|
||||||
|
return String.valueOf(entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ApprovalDeptInfo {
|
||||||
|
private final String id;
|
||||||
|
private final String name;
|
||||||
|
private final String code;
|
||||||
|
|
||||||
|
private ApprovalDeptInfo(String id, String name, String code) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user