!90 czh-20260724-IM模块统一使用fastjson2
* czh-20260724-IM模块统一使用fastjson2 * czh-20260724-添加bundle到gitignore * czh-20260724-增补意见即时通推送和回显功能
This commit is contained in:
+1
-1
@@ -7,8 +7,8 @@ localDocs
|
||||
## backend
|
||||
**/target
|
||||
**/logs
|
||||
**/yml
|
||||
**/.claude
|
||||
*.bundle
|
||||
|
||||
## front
|
||||
**/*.lock
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package org.jeecg.modules.ksim.client;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.util.RestUtil;
|
||||
import org.jeecg.modules.ksim.config.KsimProperties;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package org.jeecg.modules.ksim.dto;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 即时通 API 通用响应体
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package org.jeecg.modules.ksim.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.ksim.client.KsimApiClient;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package org.jeecg.modules.ksim.token;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.modules.ksim.client.KsimApiClient;
|
||||
|
||||
@@ -47,6 +47,12 @@
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-system-local-api</artifactId>
|
||||
</dependency>
|
||||
<!-- 即时通消息推送模块 -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-module-im</artifactId>
|
||||
<version>${jeecgProjectVersion}</version>
|
||||
</dependency>
|
||||
|
||||
<!--flowable 核心依赖-->
|
||||
<dependency>
|
||||
|
||||
+3
-3
@@ -105,9 +105,9 @@ public class TaskApprovalOpinionController extends JeecgController<TaskApprovalO
|
||||
@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("提交成功!");
|
||||
public Result<Map<String, Object>> supplement(@RequestBody SupplementApprovalOpinionDTO supplementDTO) {
|
||||
Map<String, Object> pushResult = taskApprovalOpinionService.saveSupplementOpinion(supplementDTO);
|
||||
return Result.OK(pushResult);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-10
@@ -5,9 +5,6 @@ import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 增补审批意见提交参数。
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "增补审批意见提交参数")
|
||||
public class SupplementApprovalOpinionDTO implements Serializable {
|
||||
@@ -15,22 +12,18 @@ public class SupplementApprovalOpinionDTO implements Serializable {
|
||||
|
||||
@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")
|
||||
@Schema(description = "事项任务ID")
|
||||
private String taskTaskId;
|
||||
|
||||
@Schema(description = "关联业务ID")
|
||||
private String businessId;
|
||||
|
||||
@Schema(description = "流程编码")
|
||||
private String flowCode;
|
||||
|
||||
@Schema(description = "业务标题")
|
||||
private String bizTitle;
|
||||
@Schema(description = "增补审批意见")
|
||||
private String opinion;
|
||||
}
|
||||
|
||||
+2
-7
@@ -1,15 +1,10 @@
|
||||
package org.jeecg.modules.taskapprovalopinion.service;
|
||||
|
||||
import java.util.Map;
|
||||
import org.jeecg.modules.taskapprovalopinion.entity.TaskApprovalOpinion;
|
||||
import org.jeecg.modules.taskapprovalopinion.dto.SupplementApprovalOpinionDTO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* 审批意见快照 Service。
|
||||
*/
|
||||
public interface ITaskApprovalOpinionService extends IService<TaskApprovalOpinion> {
|
||||
/**
|
||||
* 保存增补审批意见,仅写入 task_approval_opinion。
|
||||
*/
|
||||
void saveSupplementOpinion(SupplementApprovalOpinionDTO supplementDTO);
|
||||
Map<String, Object> saveSupplementOpinion(SupplementApprovalOpinionDTO supplementDTO);
|
||||
}
|
||||
|
||||
+121
-10
@@ -5,12 +5,14 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
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.ksim.service.IKsimMessageService;
|
||||
import org.jeecg.modules.taskapprovalopinion.dto.SupplementApprovalOpinionDTO;
|
||||
import org.jeecg.modules.taskapprovalopinion.entity.TaskApprovalOpinion;
|
||||
import org.jeecg.modules.taskapprovalopinion.mapper.TaskApprovalOpinionMapper;
|
||||
@@ -21,9 +23,14 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 审批意见快照 Service 实现。
|
||||
@@ -43,13 +50,12 @@ public class TaskApprovalOpinionServiceImpl extends ServiceImpl<TaskApprovalOpin
|
||||
private ExtActFlowDataMapper extActFlowDataMapper;
|
||||
@Autowired(required = false)
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
@Autowired
|
||||
private IKsimMessageService ksimMessageService;
|
||||
|
||||
/**
|
||||
* 保存增补审批意见。该入口只写 task_approval_opinion,不触碰 Flowable 原生表或旧流程日志表。
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveSupplementOpinion(SupplementApprovalOpinionDTO supplementDTO) {
|
||||
public Map<String, Object> saveSupplementOpinion(SupplementApprovalOpinionDTO supplementDTO) {
|
||||
if (supplementDTO == null || oConvertUtils.isEmpty(supplementDTO.getProcessInstId())) {
|
||||
throw new JeecgBootException("流程实例ID不能为空");
|
||||
}
|
||||
@@ -88,6 +94,42 @@ public class TaskApprovalOpinionServiceImpl extends ServiceImpl<TaskApprovalOpin
|
||||
|
||||
fillBusinessSnapshot(opinion);
|
||||
save(opinion);
|
||||
|
||||
// --- 所领导增补意见 → 即时通推送 ---
|
||||
Map<String, Object> pushResult = new HashMap<>();
|
||||
try {
|
||||
if (isSuoLeader(loginUser, deptInfo.id)) {
|
||||
String bizTitle = oConvertUtils.isNotEmpty(supplementDTO.getBizTitle())
|
||||
? supplementDTO.getBizTitle()
|
||||
: getBizTitle(opinion.getTaskTaskId(), opinion.getProcessInstId());
|
||||
String content = "所领导" + (oConvertUtils.isNotEmpty(loginUser.getRealname()) ? loginUser.getRealname() : loginUser.getUsername())
|
||||
+ "增补意见:" + opinionText;
|
||||
List<String> handlerNames = getDistinctHandlerNames(opinion.getProcessInstId(), loginUser.getUsername());
|
||||
pushResult.put("pushed", !handlerNames.isEmpty());
|
||||
pushResult.put("toUsers", handlerNames);
|
||||
pushResult.put("content", content);
|
||||
pushResult.put("title", bizTitle);
|
||||
if (!handlerNames.isEmpty()) {
|
||||
Result<String> sendResult = ksimMessageService.sendBatch("Account", handlerNames, bizTitle, content,
|
||||
null, null, null, null, null);
|
||||
if (sendResult != null && sendResult.isSuccess()) {
|
||||
log.info("【增补意见-即时通推送】已发送, processInstId: {}, toUserCount: {}, toUsers: {}, title: {}, content: {}",
|
||||
opinion.getProcessInstId(), handlerNames.size(), handlerNames, bizTitle, content);
|
||||
} else {
|
||||
log.warn("【增补意见-即时通推送】发送失败, reason: {}",
|
||||
sendResult != null ? sendResult.getMessage() : "null");
|
||||
pushResult.put("pushed", false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pushResult.put("pushed", false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("【增补意见-即时通推送】失败,不影响增补意见保存, error: {}", e.getMessage());
|
||||
pushResult.put("pushed", false);
|
||||
pushResult.put("error", e.getMessage());
|
||||
}
|
||||
return pushResult;
|
||||
}
|
||||
|
||||
private LoginUser getCurrentLoginUser() {
|
||||
@@ -98,9 +140,6 @@ public class TaskApprovalOpinionServiceImpl extends ServiceImpl<TaskApprovalOpin
|
||||
throw new JeecgBootException("未获取到当前登录用户");
|
||||
}
|
||||
|
||||
/**
|
||||
* 优先记录当前登录部门,避免多部门用户写入第一个所属部门导致审批历史筛选不准。
|
||||
*/
|
||||
private ApprovalDeptInfo resolveCurrentApprovalDept(LoginUser user, String username) {
|
||||
String deptId = user != null ? user.getOrgId() : null;
|
||||
String deptCode = user != null ? user.getOrgCode() : null;
|
||||
@@ -165,9 +204,6 @@ public class TaskApprovalOpinionServiceImpl extends ServiceImpl<TaskApprovalOpin
|
||||
return flowDataList.isEmpty() ? null : flowDataList.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* task_task 属于业务侧表,这里只做可选字段补齐,补齐失败不影响增补意见保存。
|
||||
*/
|
||||
private void fillTaskTaskFields(TaskApprovalOpinion opinion) {
|
||||
if (jdbcTemplate == null || oConvertUtils.isEmpty(opinion.getTaskTaskId())) {
|
||||
return;
|
||||
@@ -203,6 +239,81 @@ public class TaskApprovalOpinionServiceImpl extends ServiceImpl<TaskApprovalOpin
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isSuoLeader(LoginUser user, String deptId) {
|
||||
if (oConvertUtils.isEmpty(deptId)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (jdbcTemplate == null) {
|
||||
return false;
|
||||
}
|
||||
List<Map<String, Object>> rows = jdbcTemplate.queryForList(
|
||||
"select depart_type from sys_depart where id = ?", deptId);
|
||||
if (!rows.isEmpty()) {
|
||||
Object val = rows.get(0).get("depart_type");
|
||||
return val != null && "1".equals(String.valueOf(val));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("查询部门类型失败, deptId={}", deptId, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getBizTitle(String taskTaskId, String processInstId) {
|
||||
if (jdbcTemplate != null && oConvertUtils.isNotEmpty(taskTaskId)) {
|
||||
try {
|
||||
List<Map<String, Object>> rows = jdbcTemplate.queryForList(
|
||||
"select title from task_task where id = ?", taskTaskId);
|
||||
if (!rows.isEmpty()) {
|
||||
Object val = rows.get(0).get("title");
|
||||
if (val != null && !String.valueOf(val).trim().isEmpty()) {
|
||||
return String.valueOf(val).trim();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("查询 task_task.title 失败, taskTaskId={}", taskTaskId, e);
|
||||
}
|
||||
}
|
||||
if (oConvertUtils.isNotEmpty(processInstId)) {
|
||||
try {
|
||||
ExtActFlowData flowData = queryFlowData(processInstId);
|
||||
if (flowData != null && oConvertUtils.isNotEmpty(flowData.getProcessExpTitle())) {
|
||||
return flowData.getProcessExpTitle().trim();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("查询 flow title 失败, processInstId={}", processInstId, e);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private List<String> getDistinctHandlerNames(String processInstId, String excludeUserName) {
|
||||
if (jdbcTemplate == null || oConvertUtils.isEmpty(processInstId)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
try {
|
||||
List<Map<String, Object>> rows = jdbcTemplate.queryForList(
|
||||
"select distinct op_user_id, op_user_name from task_approval_opinion where process_inst_id = ?",
|
||||
processInstId);
|
||||
Set<String> names = new LinkedHashSet<>();
|
||||
for (Map<String, Object> row : rows) {
|
||||
Object nameVal = row.get("op_user_name");
|
||||
Object idVal = row.get("op_user_id");
|
||||
if (nameVal != null) {
|
||||
String name = String.valueOf(nameVal).trim();
|
||||
String userId = idVal != null ? String.valueOf(idVal).trim() : "";
|
||||
if (!name.isEmpty() && !userId.equals(excludeUserName)) {
|
||||
names.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return names.stream().collect(Collectors.toList());
|
||||
} catch (Exception e) {
|
||||
log.debug("查询经办人失败, processInstId={}", processInstId, e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ApprovalDeptInfo {
|
||||
private final String id;
|
||||
private final String name;
|
||||
|
||||
Reference in New Issue
Block a user