Compare commits
2 Commits
6987a0e790
...
8cf9140f56
| Author | SHA1 | Date | |
|---|---|---|---|
| 8cf9140f56 | |||
| 2f56ca07cb |
+12
@@ -39,6 +39,7 @@ public interface IBusinessProcessClient {
|
||||
String QUERY_BUSINESS_PROCESS_SNAPSHOT = API_PREFIX + "/queryBusinessProcessSnapshot";
|
||||
String QUERY_APPROVED_RECORD_LIST = API_PREFIX + "/queryApprovedRecordsNoAttachments";
|
||||
String GET_CURRENT_NODES = API_PREFIX + "/getCurrentNodes";
|
||||
String GET_PROCESS_INFO = API_PREFIX + "/getProcessInfo";
|
||||
|
||||
/**
|
||||
* 提交业务流程
|
||||
@@ -114,4 +115,15 @@ public interface IBusinessProcessClient {
|
||||
@GetMapping(GET_CURRENT_NODES)
|
||||
FR<Object> getCurrentNodes(@RequestParam("processInstanceId") String processInstanceId,
|
||||
@RequestParam(value = "loginName", required = false) String loginName);
|
||||
|
||||
/**
|
||||
* 获取流程实例详情
|
||||
*
|
||||
* @param processInstanceId 流程实例id
|
||||
* @param loginName MK登录名(手机号)
|
||||
* @return 流程实例详情
|
||||
*/
|
||||
@GetMapping(GET_PROCESS_INFO)
|
||||
FR<Object> getProcessInfo(@RequestParam("processInstanceId") String processInstanceId,
|
||||
@RequestParam(value = "loginName", required = false) String loginName);
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package org.springblade.transport.feign;
|
||||
|
||||
import org.springblade.core.tool.api.FR;
|
||||
import org.springblade.transport.pojo.dto.CustomerProcessNodeSyncDTO;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
/**
|
||||
* 客商档案 Feign接口
|
||||
*/
|
||||
@FeignClient(value = "blade-transport")
|
||||
public interface ICustomerArchiveClient {
|
||||
|
||||
String API_PREFIX = "/feign/client/customerArchive";
|
||||
String SYNC_PROCESS_NODE = API_PREFIX + "/syncProcessNode";
|
||||
|
||||
/**
|
||||
* 按 MK 当前节点同步客商当前节点、当前处理人和审批状态
|
||||
*
|
||||
* @param param 同步参数
|
||||
* @return 是否成功
|
||||
*/
|
||||
@PostMapping(SYNC_PROCESS_NODE)
|
||||
FR<Boolean> syncProcessNode(@RequestBody CustomerProcessNodeSyncDTO param);
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package org.springblade.transport.pojo.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 客商流程当前节点同步参数
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "客商流程当前节点同步参数")
|
||||
public class CustomerProcessNodeSyncDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "客商ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "当前节点")
|
||||
private String currentNode;
|
||||
|
||||
@Schema(description = "当前处理人")
|
||||
private String currentProcessor;
|
||||
|
||||
@Schema(description = "审批状态")
|
||||
private String approvalStatus;
|
||||
}
|
||||
@@ -62,6 +62,10 @@
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-mk-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-transport-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 其他依赖 -->
|
||||
<dependency>
|
||||
|
||||
+8
@@ -86,4 +86,12 @@ public class BusinessProcessClient implements IBusinessProcessClient {
|
||||
@RequestParam(value = "loginName", required = false) String loginName) {
|
||||
return FR.data(businessProcessService.getCurrentNodes(processInstanceId, loginName));
|
||||
}
|
||||
|
||||
@PreAuth(AuthConstant.PERMIT_ALL)
|
||||
@GetMapping(GET_PROCESS_INFO)
|
||||
@Override
|
||||
public FR<Object> getProcessInfo(@RequestParam("processInstanceId") String processInstanceId,
|
||||
@RequestParam(value = "loginName", required = false) String loginName) {
|
||||
return FR.data(businessProcessService.getProcessInfo(processInstanceId, loginName));
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -43,6 +43,15 @@ public interface IBusinessProcessService extends IService<BusinessProcess> {
|
||||
*/
|
||||
List<?> getCurrentNodes(String processInstanceId, String loginName);
|
||||
|
||||
/**
|
||||
* 获取流程实例详情
|
||||
*
|
||||
* @param processInstanceId 流程实例id
|
||||
* @param loginName MK登录名(手机号),可为空,为空时按流程发起人解析
|
||||
* @return 流程实例详情
|
||||
*/
|
||||
Object getProcessInfo(String processInstanceId, String loginName);
|
||||
|
||||
/**
|
||||
* 修改业务流程状态
|
||||
* @param param
|
||||
|
||||
+108
-1
@@ -15,6 +15,7 @@ import org.springblade.process.pojo.enums.ApproveStatusEnum;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.log.utils.AssertUtils;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.api.FR;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.process.convert.ApprovalConvert;
|
||||
import org.springblade.process.convert.BusinessProcessConvert;
|
||||
@@ -41,12 +42,15 @@ import org.springblade.thirdparty.mk.pojo.dto.approval.MKProcessDTO;
|
||||
import org.springblade.thirdparty.mk.pojo.dto.sort.*;
|
||||
import org.springblade.thirdparty.mk.pojo.vo.*;
|
||||
import org.springblade.thirdparty.mk.service.IMKService;
|
||||
import org.springblade.transport.feign.ICustomerArchiveClient;
|
||||
import org.springblade.transport.pojo.dto.CustomerProcessNodeSyncDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 业务流程关联表 服务实现类
|
||||
@@ -64,6 +68,7 @@ public class BusinessProcessServiceImpl extends ServiceImpl<BusinessProcessMappe
|
||||
private final MKProperties mkProperties;
|
||||
private final ApprovalConvert approvalConvert;
|
||||
private final IUserService userService;
|
||||
private final ICustomerArchiveClient customerArchiveClient;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
@@ -163,7 +168,9 @@ public class BusinessProcessServiceImpl extends ServiceImpl<BusinessProcessMappe
|
||||
businessProcess.setProcessInstanceId(processInstanceId);
|
||||
businessProcess.setApproveStatus(ApproveStatusEnum.APPROVING.getValue());
|
||||
this.saveOrUpdate(businessProcess);
|
||||
this.getCurrentNodes(processInstanceId, loginName);
|
||||
List<?> currentNodes = this.getCurrentNodes(processInstanceId, loginName);
|
||||
this.syncCustomerArchiveCurrentNode(param.getFormInstanceId(), currentNodes);
|
||||
this.getProcessInfo(processInstanceId, loginName);
|
||||
return processInstanceId;
|
||||
}
|
||||
|
||||
@@ -193,6 +200,106 @@ public class BusinessProcessServiceImpl extends ServiceImpl<BusinessProcessMappe
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProcessInfo(String processInstanceId, String loginName) {
|
||||
if (StringUtils.isBlank(processInstanceId)) {
|
||||
log.warn("查询流程实例详情失败,processInstanceId为空");
|
||||
return null;
|
||||
}
|
||||
String resolvedLoginName = loginName;
|
||||
if (StringUtils.isBlank(resolvedLoginName)) {
|
||||
BusinessProcess businessProcess = this.getBusinessProcessByProcessInstanceId(processInstanceId);
|
||||
resolvedLoginName = resolvePromoterLoginName(businessProcess, null);
|
||||
}
|
||||
if (StringUtils.isBlank(resolvedLoginName)) {
|
||||
log.warn("查询流程实例详情失败,loginName为空 processInstanceId={}", processInstanceId);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Object processInfo = mkService.getProcessInfo(processInstanceId, resolvedLoginName);
|
||||
log.info("获取流程实例详情 processInstanceId={} loginName={} result={}",
|
||||
processInstanceId, resolvedLoginName, JSON.toJSONString(processInfo));
|
||||
return processInfo;
|
||||
} catch (Exception e) {
|
||||
log.error("查询流程实例详情异常 processInstanceId={} loginName={}", processInstanceId, resolvedLoginName, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void syncCustomerArchiveCurrentNode(String formInstanceId, List<?> currentNodes) {
|
||||
if (StringUtils.isBlank(formInstanceId) || CollectionUtil.isEmpty(currentNodes)) {
|
||||
log.warn("同步客商当前节点跳过,formInstanceId或节点详情为空 formInstanceId={}", formInstanceId);
|
||||
return;
|
||||
}
|
||||
Long customerId;
|
||||
try {
|
||||
customerId = Long.valueOf(formInstanceId);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("同步客商当前节点失败,表单实例id不是数字:{}", formInstanceId);
|
||||
return;
|
||||
}
|
||||
String currentNode = currentNodes.stream()
|
||||
.map(this::readMkNodeName)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.distinct()
|
||||
.collect(Collectors.joining(","));
|
||||
String currentProcessor = currentNodes.stream()
|
||||
.flatMap(this::readMkHandlerNames)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.distinct()
|
||||
.collect(Collectors.joining(","));
|
||||
if (StringUtils.isBlank(currentNode) && StringUtils.isBlank(currentProcessor)) {
|
||||
log.warn("同步客商当前节点跳过,未解析到节点名称或处理人 customerId={}", customerId);
|
||||
return;
|
||||
}
|
||||
CustomerProcessNodeSyncDTO param = new CustomerProcessNodeSyncDTO();
|
||||
param.setId(customerId);
|
||||
param.setCurrentNode(currentNode);
|
||||
param.setCurrentProcessor(currentProcessor);
|
||||
param.setApprovalStatus("reviewing");
|
||||
try {
|
||||
FR<Boolean> result = customerArchiveClient.syncProcessNode(param);
|
||||
log.info("同步客商当前节点完成 customerId={} currentNode={} currentProcessor={} result={}",
|
||||
customerId, currentNode, currentProcessor, JSON.toJSONString(result));
|
||||
} catch (Exception e) {
|
||||
log.error("同步客商当前节点异常 customerId={} currentNode={} currentProcessor={}",
|
||||
customerId, currentNode, currentProcessor, e);
|
||||
}
|
||||
}
|
||||
|
||||
private String readMkNodeName(Object node) {
|
||||
if (node instanceof MKNodeVO vo) {
|
||||
return vo.getNodeName();
|
||||
}
|
||||
if (node instanceof Map<?, ?> map) {
|
||||
Object value = map.get("nodeName");
|
||||
return value == null ? null : String.valueOf(value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Stream<String> readMkHandlerNames(Object node) {
|
||||
List<MKNodeHandlerVO> handlers = null;
|
||||
if (node instanceof MKNodeVO vo) {
|
||||
handlers = vo.getNodeHandlers();
|
||||
} else if (node instanceof Map<?, ?> map && map.get("nodeHandlers") instanceof List<?> list) {
|
||||
return list.stream().map(item -> {
|
||||
if (item instanceof MKNodeHandlerVO handler) {
|
||||
return handler.getHandlerName();
|
||||
}
|
||||
if (item instanceof Map<?, ?> handlerMap) {
|
||||
Object value = handlerMap.get("handlerName");
|
||||
return value == null ? null : String.valueOf(value);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if (CollectionUtil.isEmpty(handlers)) {
|
||||
return Stream.empty();
|
||||
}
|
||||
return handlers.stream().map(MKNodeHandlerVO::getHandlerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从当前登录用户实体读取真实手机号(绕过接口返回脱敏)
|
||||
*/
|
||||
|
||||
+54
-2
@@ -96,7 +96,7 @@ public class CustomerArchivePublicController {
|
||||
*/
|
||||
@PostMapping("/process-message")
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "公开接收流程消息", description = "无需登录,接收后查询当前节点并打印")
|
||||
@Operation(summary = "公开接收流程消息", description = "无需登录,接收后查询当前节点、流程实例详情并同步客商当前节点")
|
||||
public R processMessage(@RequestBody Map<String, Object> body) {
|
||||
log.info("客商公开页收到流程消息:{}", JSON.toJSONString(body));
|
||||
Map<String, Object> formValues = asMap(body == null ? null : body.get("formValues"));
|
||||
@@ -109,16 +109,68 @@ public class CustomerArchivePublicController {
|
||||
log.warn("客商公开页流程消息未找到 processId,跳过查询当前节点");
|
||||
return R.success("ok");
|
||||
}
|
||||
String customerIdText = firstText(asMap(body == null ? null : body.get("formData")), "id");
|
||||
try {
|
||||
FR<Object> result = businessProcessClient.getCurrentNodes(processId, loginName);
|
||||
Object nodeData = result == null ? null : result.getData();
|
||||
log.info("客商公开页流程消息当前节点详情 processId={} loginName={} result={}",
|
||||
processId, loginName, JSON.toJSONString(result == null ? null : result.getData()));
|
||||
processId, loginName, JSON.toJSONString(nodeData));
|
||||
if (StringUtil.isBlank(customerIdText)) {
|
||||
log.warn("客商公开页流程消息未找到客商id,跳过同步当前节点");
|
||||
} else {
|
||||
try {
|
||||
customerArchiveService.syncProcessNodeFromMk(Long.valueOf(customerIdText), nodeData);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("客商公开页流程消息客商id格式不正确:{}", customerIdText);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("客商公开页查询当前节点失败 processId={} loginName={}", processId, loginName, e);
|
||||
}
|
||||
try {
|
||||
FR<Object> processInfoResult = businessProcessClient.getProcessInfo(processId, loginName);
|
||||
Object processInfo = processInfoResult == null ? null : processInfoResult.getData();
|
||||
log.info("客商公开页流程消息流程实例详情 processId={} loginName={} result={}",
|
||||
processId, loginName, JSON.toJSONString(processInfo));
|
||||
if (isProcessFinished(processInfo)) {
|
||||
applyProcessResult(customerIdText, processId, formValues, true);
|
||||
} else if (isProcessRejected(processInfo)) {
|
||||
applyProcessResult(customerIdText, processId, formValues, false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("客商公开页查询流程实例详情失败 processId={} loginName={}", processId, loginName, e);
|
||||
}
|
||||
return R.success("ok");
|
||||
}
|
||||
|
||||
private static boolean isProcessFinished(Object processInfo) {
|
||||
return "30".equals(firstText(asMap(processInfo), "fdProcessStatus"));
|
||||
}
|
||||
|
||||
private static boolean isProcessRejected(Object processInfo) {
|
||||
return "20".equals(firstText(asMap(processInfo), "fdProcessStatus"));
|
||||
}
|
||||
|
||||
private void applyProcessResult(String customerIdText, String processId, Map<String, Object> formValues,
|
||||
boolean approved) {
|
||||
String action = approved ? "审核通过" : "审核驳回";
|
||||
if (StringUtil.isBlank(customerIdText)) {
|
||||
log.warn("流程{}但未找到客商id,跳过同步 processId={}", action, processId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String processorName = firstText(formValues, "mkUserName", "mkLoginName");
|
||||
Long customerId = Long.valueOf(customerIdText);
|
||||
if (approved) {
|
||||
customerArchiveService.approveFromProcess(customerId, processorName);
|
||||
} else {
|
||||
customerArchiveService.rejectFromProcess(customerId, processorName);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("流程{}但客商id格式不正确:{}", action, customerIdText);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, Object> asMap(Object value) {
|
||||
if (!(value instanceof Map<?, ?> map)) {
|
||||
return Collections.emptyMap();
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package org.springblade.transport.feign;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.secure.annotation.PreAuth;
|
||||
import org.springblade.core.secure.constant.AuthConstant;
|
||||
import org.springblade.core.tenant.annotation.TenantIgnore;
|
||||
import org.springblade.core.tool.api.FR;
|
||||
import org.springblade.transport.pojo.dto.CustomerProcessNodeSyncDTO;
|
||||
import org.springblade.transport.service.ICustomerArchiveService;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 客商档案 Feign实现
|
||||
*/
|
||||
@Hidden
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
public class CustomerArchiveClient implements ICustomerArchiveClient {
|
||||
|
||||
private final ICustomerArchiveService customerArchiveService;
|
||||
|
||||
@TenantIgnore
|
||||
@PreAuth(AuthConstant.PERMIT_ALL)
|
||||
@PostMapping(SYNC_PROCESS_NODE)
|
||||
@Override
|
||||
public FR<Boolean> syncProcessNode(@RequestBody CustomerProcessNodeSyncDTO param) {
|
||||
if (param == null) {
|
||||
return FR.data(false);
|
||||
}
|
||||
return FR.data(customerArchiveService.syncProcessNode(
|
||||
param.getId(), param.getCurrentNode(), param.getCurrentProcessor(), param.getApprovalStatus()));
|
||||
}
|
||||
}
|
||||
+38
@@ -100,6 +100,44 @@ public interface ICustomerArchiveService extends BaseService<CustomerArchive> {
|
||||
*/
|
||||
boolean submitApproval(Long id);
|
||||
|
||||
/**
|
||||
* 按 MK 当前节点同步客商当前节点、当前处理人和审批状态
|
||||
*
|
||||
* @param id 客商ID
|
||||
* @param currentNode 当前节点
|
||||
* @param currentProcessor 当前处理人
|
||||
* @param approvalStatus 审批状态,可为空,为空时保持为审核中
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean syncProcessNode(Long id, String currentNode, String currentProcessor, String approvalStatus);
|
||||
|
||||
/**
|
||||
* 按 MK getCurrentNodes 返回结果同步客商当前节点
|
||||
*
|
||||
* @param id 客商ID
|
||||
* @param currentNodes MK 当前节点详情
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean syncProcessNodeFromMk(Long id, Object currentNodes);
|
||||
|
||||
/**
|
||||
* MK 流程结束(fdProcessStatus=30)时将客商置为审核通过
|
||||
*
|
||||
* @param id 客商ID
|
||||
* @param processorName 当前处理人,可为空
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean approveFromProcess(Long id, String processorName);
|
||||
|
||||
/**
|
||||
* MK 流程状态为 20 时将客商置为审核驳回
|
||||
*
|
||||
* @param id 客商ID
|
||||
* @param processorName 当前处理人,可为空
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean rejectFromProcess(Long id, String processorName);
|
||||
|
||||
/**
|
||||
* 撤回审批并恢复草稿状态
|
||||
*
|
||||
|
||||
+165
@@ -29,6 +29,7 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
@@ -85,6 +86,7 @@ import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -101,6 +103,7 @@ import java.util.stream.Collectors;
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveMapper, CustomerArchive> implements ICustomerArchiveService {
|
||||
@@ -214,12 +217,129 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
CustomerArchive before = Objects.requireNonNull(BeanUtil.copyProperties(detail, CustomerArchive.class));
|
||||
CustomerArchive after = copyCustomer(before);
|
||||
after.setApprovalStatus(APPROVAL_REVIEWING);
|
||||
if (Func.isEmpty(after.getCurrentNode()) || Objects.equals(after.getCurrentNode(), "草稿")) {
|
||||
after.setCurrentNode("客商准入审批");
|
||||
after.setCurrentProcessor("待处理");
|
||||
}
|
||||
addChangeRecord(id, "提交客商准入审批", before, after);
|
||||
return updateById(after);
|
||||
}
|
||||
|
||||
@Override
|
||||
@TenantIgnore
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean syncProcessNode(Long id, String currentNode, String currentProcessor, String approvalStatus) {
|
||||
if (Func.isEmpty(id)) {
|
||||
log.warn("同步客商当前节点失败,客商ID为空");
|
||||
return false;
|
||||
}
|
||||
CustomerArchive customer = getById(id);
|
||||
if (customer == null || Objects.equals(customer.getIsDeleted(), 1)) {
|
||||
log.warn("同步客商当前节点失败,客商不存在 id={}", id);
|
||||
return false;
|
||||
}
|
||||
String nextStatus = Func.isEmpty(approvalStatus) ? APPROVAL_REVIEWING : approvalStatus;
|
||||
boolean updated = this.lambdaUpdate()
|
||||
.eq(CustomerArchive::getId, id)
|
||||
.set(Func.isNotEmpty(currentNode), CustomerArchive::getCurrentNode, currentNode)
|
||||
.set(Func.isNotEmpty(currentProcessor), CustomerArchive::getCurrentProcessor, currentProcessor)
|
||||
.set(Func.isNotEmpty(nextStatus), CustomerArchive::getApprovalStatus, nextStatus)
|
||||
.update();
|
||||
log.info("同步客商当前节点 id={} currentNode={} currentProcessor={} approvalStatus={} result={}",
|
||||
id, currentNode, currentProcessor, nextStatus, updated);
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
@TenantIgnore
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean syncProcessNodeFromMk(Long id, Object currentNodes) {
|
||||
if (Func.isEmpty(id) || currentNodes == null) {
|
||||
return false;
|
||||
}
|
||||
List<Map<String, Object>> nodes = normalizeMkNodeList(currentNodes);
|
||||
if (nodes.isEmpty()) {
|
||||
log.warn("同步客商当前节点跳过,节点详情为空 id={}", id);
|
||||
return false;
|
||||
}
|
||||
List<String> nodeNames = new ArrayList<>();
|
||||
List<String> handlerNames = new ArrayList<>();
|
||||
for (Map<String, Object> node : nodes) {
|
||||
String nodeName = Func.toStr(node.get("nodeName"), "").trim();
|
||||
if (Func.isNotEmpty(nodeName)) {
|
||||
nodeNames.add(nodeName);
|
||||
}
|
||||
Object handlers = node.get("nodeHandlers");
|
||||
if (!(handlers instanceof Collection<?> handlerList)) {
|
||||
continue;
|
||||
}
|
||||
for (Object handler : handlerList) {
|
||||
Map<String, Object> handlerMap = asStringObjectMap(handler);
|
||||
String handlerName = Func.toStr(handlerMap.get("handlerName"), "").trim();
|
||||
if (Func.isNotEmpty(handlerName)) {
|
||||
handlerNames.add(handlerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return syncProcessNode(id, joinDistinct(nodeNames), joinDistinct(handlerNames), APPROVAL_REVIEWING);
|
||||
}
|
||||
|
||||
@Override
|
||||
@TenantIgnore
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean approveFromProcess(Long id, String processorName) {
|
||||
if (Func.isEmpty(id)) {
|
||||
log.warn("流程结束审核通过失败,客商ID为空");
|
||||
return false;
|
||||
}
|
||||
CustomerArchive before = getById(id);
|
||||
if (before == null || Objects.equals(before.getIsDeleted(), 1)) {
|
||||
log.warn("流程结束审核通过失败,客商不存在 id={}", id);
|
||||
return false;
|
||||
}
|
||||
if (Objects.equals(before.getApprovalStatus(), APPROVAL_APPROVED)) {
|
||||
log.info("流程结束审核通过跳过,客商已是审核通过 id={}", id);
|
||||
return true;
|
||||
}
|
||||
CustomerArchive after = copyCustomer(before);
|
||||
after.setAccessType(ACCESS_FORMAL);
|
||||
after.setApprovalStatus(APPROVAL_APPROVED);
|
||||
after.setCurrentNode("审核通过");
|
||||
after.setCurrentProcessor(Func.isEmpty(processorName) ? "系统" : processorName.trim());
|
||||
after.setApprovedTime(LocalDateTime.now());
|
||||
addChangeRecord(id, "客商准入审核通过", before, after);
|
||||
boolean updated = updateById(after);
|
||||
log.info("流程结束审核通过 id={} processor={} result={}", id, after.getCurrentProcessor(), updated);
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
@TenantIgnore
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean rejectFromProcess(Long id, String processorName) {
|
||||
if (Func.isEmpty(id)) {
|
||||
log.warn("流程审核驳回失败,客商ID为空");
|
||||
return false;
|
||||
}
|
||||
CustomerArchive before = getById(id);
|
||||
if (before == null || Objects.equals(before.getIsDeleted(), 1)) {
|
||||
log.warn("流程审核驳回失败,客商不存在 id={}", id);
|
||||
return false;
|
||||
}
|
||||
if (Objects.equals(before.getApprovalStatus(), APPROVAL_REJECTED)) {
|
||||
log.info("流程审核驳回跳过,客商已是审核不通过 id={}", id);
|
||||
return true;
|
||||
}
|
||||
CustomerArchive after = copyCustomer(before);
|
||||
after.setApprovalStatus(APPROVAL_REJECTED);
|
||||
after.setCurrentNode("审核不通过");
|
||||
after.setCurrentProcessor(Func.isEmpty(processorName) ? "系统" : processorName.trim());
|
||||
addChangeRecord(id, "客商准入审核不通过", before, after);
|
||||
boolean updated = updateById(after);
|
||||
log.info("流程审核驳回 id={} processor={} result={}", id, after.getCurrentProcessor(), updated);
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean withdrawApproval(Long id) {
|
||||
@@ -1032,6 +1152,51 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
return Objects.requireNonNull(BeanUtil.copyProperties(customer, CustomerArchive.class));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Map<String, Object>> normalizeMkNodeList(Object currentNodes) {
|
||||
Object source = currentNodes;
|
||||
if (source instanceof String text && Func.isNotEmpty(text.trim())) {
|
||||
source = JsonUtil.parse(text, List.class);
|
||||
}
|
||||
if (source instanceof Collection<?> collection) {
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
for (Object item : collection) {
|
||||
Map<String, Object> map = asStringObjectMap(item);
|
||||
if (!map.isEmpty()) {
|
||||
result.add(map);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Map<String, Object> single = asStringObjectMap(source);
|
||||
return single.isEmpty() ? List.of() : List.of(single);
|
||||
}
|
||||
|
||||
private Map<String, Object> asStringObjectMap(Object value) {
|
||||
if (value instanceof Map<?, ?> map) {
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
map.forEach((key, nested) -> {
|
||||
if (key != null) {
|
||||
result.put(String.valueOf(key), nested);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
if (value == null) {
|
||||
return Map.of();
|
||||
}
|
||||
try {
|
||||
Map<String, Object> parsed = JsonUtil.toMap(JsonUtil.toJson(value));
|
||||
return parsed == null ? Map.of() : parsed;
|
||||
} catch (Exception ignored) {
|
||||
return Map.of();
|
||||
}
|
||||
}
|
||||
|
||||
private String joinDistinct(List<String> values) {
|
||||
return values.stream().filter(Func::isNotEmpty).distinct().collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
private void addChangeRecord(Long customerId, String content, CustomerArchive before, CustomerArchive after) {
|
||||
Map<String, Object> beforeSnapshot = customerSnapshot(before);
|
||||
Map<String, Object> afterSnapshot = customerSnapshot(after);
|
||||
|
||||
Vendored
+9
@@ -65,6 +65,15 @@ public interface IMKClient {
|
||||
@PostMapping("${thirdParty.mk.getCurrentNodesUrl:/openapi/sys-lbpm/sysLbpmProcess/openSupport/getCurNodesInfo}")
|
||||
MKResultVO<List<MKNodeVO>> getCurrentNodes(@RequestBody MKCurrentNodesDTO param, @RequestParam("access_token") String accessToken);
|
||||
|
||||
/**
|
||||
* 获取流程实例详情
|
||||
* @param param
|
||||
* @param accessToken
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("${thirdParty.mk.getProcessInfoUrl:/openapi/sys-lbpm/sysLbpmProcess/openSupport/getProcessInfo}")
|
||||
MKResultVO<Object> getProcessInfo(@RequestBody MKCurrentNodesDTO param, @RequestParam("access_token") String accessToken);
|
||||
|
||||
/**
|
||||
* 获取节点处理人信息
|
||||
* @param param
|
||||
|
||||
+8
@@ -66,6 +66,14 @@ public interface IMKService {
|
||||
*/
|
||||
List<MKNodeVO> getCurrentNodes(String processInstanceId, String loginName);
|
||||
|
||||
/**
|
||||
* 获取流程实例详情
|
||||
* @param processInstanceId
|
||||
* @param loginName
|
||||
* @return
|
||||
*/
|
||||
Object getProcessInfo(String processInstanceId, String loginName);
|
||||
|
||||
/**
|
||||
* 获取节点处理人信息
|
||||
* @param processInstanceId
|
||||
|
||||
+15
@@ -246,6 +246,21 @@ public class MKServiceImpl implements IMKService {
|
||||
return nodesResult.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProcessInfo(String processInstanceId, String loginName) {
|
||||
String accessToken = getToken();
|
||||
MKCurrentNodesDTO param = new MKCurrentNodesDTO();
|
||||
param.setProcessInstanceId(processInstanceId);
|
||||
param.setLoginName(loginName);
|
||||
MKResultVO<Object> processInfoResult = client.getProcessInfo(param, accessToken);
|
||||
log.info("调用mk接口 获取流程实例详情 :{}", JSONUtil.toJsonStr(processInfoResult));
|
||||
if (processInfoResult == null || !processInfoResult.isSuccess()) {
|
||||
log.error("调用mk接口 获取流程实例详情异常:{}", JSONUtil.toJsonStr(processInfoResult));
|
||||
return null;
|
||||
}
|
||||
return processInfoResult.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MKAllHandlerVO getNodeHandlers(String processInstanceId, String loginName, String nodeId) {
|
||||
String accessToken = getToken();
|
||||
|
||||
@@ -118,6 +118,7 @@ thirdParty:
|
||||
processExecuteUrl: ${MK_PROCESS_EXECUTE_URL:/openapi/sys-lbpm/sysLbpmProcess/openSupport/execute}
|
||||
processDeleteUrl: ${MK_PROCESS_DELETE_URL:/openapi/sys-lbpm/sysLbpmProcess/openSupport/delete}
|
||||
getCurrentNodesUrl: ${MK_CURRENT_NODES_URL:/openapi/sys-lbpm/sysLbpmProcess/openSupport/getCurNodesInfo}
|
||||
getProcessInfoUrl: ${MK_PROCESS_INFO_URL:/openapi/sys-lbpm/sysLbpmProcess/openSupport/getProcessInfo}
|
||||
getNodeHandlersUrl: ${MK_NODE_HANDLERS_URL:/openapi/sys-lbpm/sysLbpmProcess/openSupport/getNodeHandlerInfos}
|
||||
getManualNodeUrl: ${MK_MANUAL_NODE_URL:/openapi/sys-lbpm/sysLbpmTemplate/openSupport/getManualNode}
|
||||
pushOrgDeptUrl: ${MK_PUSH_ORG_DEPT_URL:/openapi/sys-org/v2/push/orgDept}
|
||||
|
||||
@@ -91,6 +91,7 @@ thirdParty:
|
||||
processExecuteUrl: ${MK_PROCESS_EXECUTE_URL:/openapi/sys-lbpm/sysLbpmProcess/openSupport/execute}
|
||||
processDeleteUrl: ${MK_PROCESS_DELETE_URL:/openapi/sys-lbpm/sysLbpmProcess/openSupport/delete}
|
||||
getCurrentNodesUrl: ${MK_CURRENT_NODES_URL:/openapi/sys-lbpm/sysLbpmProcess/openSupport/getCurNodesInfo}
|
||||
getProcessInfoUrl: ${MK_PROCESS_INFO_URL:/openapi/sys-lbpm/sysLbpmProcess/openSupport/getProcessInfo}
|
||||
getNodeHandlersUrl: ${MK_NODE_HANDLERS_URL:/openapi/sys-lbpm/sysLbpmProcess/openSupport/getNodeHandlerInfos}
|
||||
getManualNodeUrl: ${MK_MANUAL_NODE_URL:/openapi/sys-lbpm/sysLbpmTemplate/openSupport/getManualNode}
|
||||
pushOrgDeptUrl: ${MK_PUSH_ORG_DEPT_URL:/openapi/sys-org/v2/push/orgDept}
|
||||
|
||||
@@ -221,6 +221,8 @@ blade:
|
||||
- /blade-openapi/openApi/mk/process/commonCallback
|
||||
- /openApi/mk/process/commonCallback
|
||||
- /feign/client/businessProcess/getCurrentNodes
|
||||
- /feign/client/businessProcess/getProcessInfo
|
||||
- /feign/client/customerArchive/syncProcessNode
|
||||
#授权认证配置
|
||||
auth:
|
||||
- method: ALL
|
||||
|
||||
Reference in New Issue
Block a user