refactor(dms): 优化异步线程获取sa-token上下文

- mobile的保养实体类和接口移除不必要的日期格式化方法
master
zch 3 days ago
parent 1f3eeedfc0
commit 2b74ae610c

@ -119,20 +119,20 @@ public class DmsMobileController extends BaseController {
* @param mobileInstance Mobile * @param mobileInstance Mobile
* @param voInstance VO * @param voInstance VO
*/ */
private void formatMaintTimeFields(DmsBillsMaintInstanceMobile mobileInstance, DmsBillsMaintInstanceVo voInstance) { // private void formatMaintTimeFields(DmsBillsMaintInstanceMobile mobileInstance, DmsBillsMaintInstanceVo voInstance) {
if (voInstance.getPlanBeginTime() != null) { // if (voInstance.getPlanBeginTime() != null) {
mobileInstance.setPlanBeginTime(DATE_FORMAT.format(voInstance.getPlanBeginTime())); // mobileInstance.setPlanBeginTime(DATE_FORMAT.format(voInstance.getPlanBeginTime()));
} // }
if (voInstance.getRealBeginTime() != null) { // if (voInstance.getRealBeginTime() != null) {
mobileInstance.setRealBeginTime(DATE_FORMAT.format(voInstance.getRealBeginTime())); // mobileInstance.setRealBeginTime(DATE_FORMAT.format(voInstance.getRealBeginTime()));
} // }
if (voInstance.getPlanEndTime() != null) { // if (voInstance.getPlanEndTime() != null) {
mobileInstance.setPlanEndTime(DATE_FORMAT.format(voInstance.getPlanEndTime())); // mobileInstance.setPlanEndTime(DATE_FORMAT.format(voInstance.getPlanEndTime()));
} // }
if (voInstance.getRealEndTime() != null) { // if (voInstance.getRealEndTime() != null) {
mobileInstance.setRealEndTime(DATE_FORMAT.format(voInstance.getRealEndTime())); // mobileInstance.setRealEndTime(DATE_FORMAT.format(voInstance.getRealEndTime()));
} // }
} // }
/** /**
* (PDA) * (PDA)
@ -142,7 +142,7 @@ public class DmsMobileController extends BaseController {
@GetMapping(value = "/dict/type/{dictType}") @GetMapping(value = "/dict/type/{dictType}")
public AjaxResult getDictType(@PathVariable String dictType) { public AjaxResult getDictType(@PathVariable String dictType) {
List<RemoteDictDataVo> data = remoteDictService.selectDictDataByType(dictType); List<RemoteDictDataVo> data = remoteDictService.selectDictDataByType(dictType);
// 手动转换只映射PDA端需要的字段 // 手动转换只映射PDA端需要的字段
List<Dict> dictList = new ArrayList<>(); List<Dict> dictList = new ArrayList<>();
if (data != null) { if (data != null) {
@ -156,7 +156,7 @@ public class DmsMobileController extends BaseController {
dictList.add(dict); dictList.add(dict);
} }
} }
return AjaxResult.success(dictList); return AjaxResult.success(dictList);
} }
@ -505,7 +505,7 @@ public class DmsMobileController extends BaseController {
DmsBillsMaintInstanceMobile mobileInstance = MapstructUtils.convert(newestMaintInstance, DmsBillsMaintInstanceMobile.class); DmsBillsMaintInstanceMobile mobileInstance = MapstructUtils.convert(newestMaintInstance, DmsBillsMaintInstanceMobile.class);
// 手动格式化时间字段确保PDA客户端兼容性 // 手动格式化时间字段确保PDA客户端兼容性
formatMaintTimeFields(mobileInstance, newestMaintInstance); // formatMaintTimeFields(mobileInstance, newestMaintInstance);
return AjaxResult.success(mobileInstance); return AjaxResult.success(mobileInstance);
} }
@ -519,8 +519,8 @@ public class DmsMobileController extends BaseController {
@PostMapping("/startMaint") @PostMapping("/startMaint")
@RepeatSubmit @RepeatSubmit
public AjaxResult startMaint(@RequestBody DmsBillsMaintDetail dmsBillsMaintDetail) { public AjaxResult startMaint(@RequestBody DmsBillsMaintDetail dmsBillsMaintDetail) {
dmsBillsMaintInstanceService.startMaint(dmsBillsMaintDetail); DmsBillsMaintDetail result = dmsBillsMaintInstanceService.startMaint(dmsBillsMaintDetail);
return AjaxResult.success(); return AjaxResult.success(result);
} }
/** /**

@ -72,29 +72,29 @@ public class DmsBillsMaintInstanceMobile implements Serializable {
@ExcelDictFormat(dictType = "maint_level") @ExcelDictFormat(dictType = "maint_level")
private Long maintLevel; private Long maintLevel;
/** // /**
* // * 计划保养时间
*/ // */
@ExcelProperty(value = "计划保养时间") // @ExcelProperty(value = "计划保养时间")
private String planBeginTime; // private String planBeginTime;
//
/** // /**
* // * 实际开始时间
*/ // */
@ExcelProperty(value = "实际开始时间") // @ExcelProperty(value = "实际开始时间")
private String realBeginTime; // private String realBeginTime;
//
/** // /**
* ; // * 计划完成时间;根据计划的时限计算
*/ // */
@ExcelProperty(value = "计划完成时间;根据计划的时限计算") // @ExcelProperty(value = "计划完成时间;根据计划的时限计算")
private String planEndTime; // private String planEndTime;
//
/** // /**
* // * 实际完成时间
*/ // */
@ExcelProperty(value = "实际完成时间") // @ExcelProperty(value = "实际完成时间")
private String realEndTime; // private String realEndTime;
/** /**
* (1 2 3) * (1 2 3)

@ -6,6 +6,7 @@ import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.seata.spring.annotation.GlobalTransactional; import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.constant.DmsConstants; import org.dromara.common.core.constant.DmsConstants;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
@ -31,6 +32,8 @@ import org.dromara.dms.mapper.DmsInstanceFileMapper;
import org.dromara.dms.service.IDmsBillsFaultInstanceService; import org.dromara.dms.service.IDmsBillsFaultInstanceService;
import org.dromara.dms.service.IDmsFaultInstanceActivityService; import org.dromara.dms.service.IDmsFaultInstanceActivityService;
import org.dromara.dms.service.IDmsInstanceFileService; import org.dromara.dms.service.IDmsInstanceFileService;
import org.dromara.resource.api.RemoteFileService;
import org.dromara.resource.api.domain.RemoteFile;
import org.dromara.workflow.api.RemoteWorkflowService; import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteCompleteTask; import org.dromara.workflow.api.domain.RemoteCompleteTask;
import org.dromara.workflow.api.domain.RemoteStartProcess; import org.dromara.workflow.api.domain.RemoteStartProcess;
@ -52,6 +55,7 @@ import java.util.concurrent.CompletableFuture;
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
@Slf4j
public class DmsBillsFaultInstanceServiceImpl implements IDmsBillsFaultInstanceService { public class DmsBillsFaultInstanceServiceImpl implements IDmsBillsFaultInstanceService {
private final DmsBillsFaultInstanceMapper baseMapper; private final DmsBillsFaultInstanceMapper baseMapper;
@ -68,7 +72,8 @@ public class DmsBillsFaultInstanceServiceImpl implements IDmsBillsFaultInstanceS
private final IDmsFaultInstanceActivityService dmsFaultInstanceActivityService; private final IDmsFaultInstanceActivityService dmsFaultInstanceActivityService;
@DubboReference(timeout = 15000, retries = 1)
private final RemoteFileService remoteFileService;
/** /**
* *
@ -375,8 +380,8 @@ public class DmsBillsFaultInstanceServiceImpl implements IDmsBillsFaultInstanceS
for (DmsInstanceFileVo dmsInstanceFile : dmsInstanceFiles){ for (DmsInstanceFileVo dmsInstanceFile : dmsInstanceFiles){
// 获取文件路径 // 获取文件路径
String filePath = dmsInstanceFile.getFilePath(); String filePath = dmsInstanceFile.getFilePath();
// 如果文件路径不包含"7309" // 如果文件路径不包含"9005"
if(!filePath.contains("7309")){ if(!filePath.contains("9005")){
// 如果文件路径包含"https",将其替换为"http" // 如果文件路径包含"https",将其替换为"http"
if(filePath.contains("https")){ if(filePath.contains("https")){
filePath.replaceFirst("https","http"); filePath.replaceFirst("https","http");
@ -384,12 +389,11 @@ public class DmsBillsFaultInstanceServiceImpl implements IDmsBillsFaultInstanceS
// 找到"/statics"的索引位置 // 找到"/statics"的索引位置
int index= filePath.indexOf("/statics"); int index= filePath.indexOf("/statics");
// 修改文件路径为新的地址 // 修改文件路径为新的地址
filePath = "http://172.16.12.100:7309"+filePath.substring(index); filePath = "http://118.25.106.99:9005"+filePath.substring(index);
// 设置新的URL和文件路径 // 设置新的URL和文件路径
dmsInstanceFile.setFilePath(filePath); dmsInstanceFile.setFilePath(filePath);
dmsInstanceFile.setFilePath(filePath);
}else{ }else{
// 如果文件路径包含"7309"直接设置URL为文件路径 // 如果文件路径包含"9005"直接设置URL为文件路径
dmsInstanceFile.setFilePath(dmsInstanceFile.getFilePath()); dmsInstanceFile.setFilePath(dmsInstanceFile.getFilePath());
} }
} }
@ -402,6 +406,7 @@ public class DmsBillsFaultInstanceServiceImpl implements IDmsBillsFaultInstanceS
} }
public void batchInsertInstanceFiles(List<String> fileUrls, Long instanceActivityId) { public void batchInsertInstanceFiles(List<String> fileUrls, Long instanceActivityId) {
// 判断文件URL列表是否不为空且非空 // 判断文件URL列表是否不为空且非空
if (fileUrls != null && !fileUrls.isEmpty()) { if (fileUrls != null && !fileUrls.isEmpty()) {

@ -6,6 +6,8 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.seata.spring.annotation.GlobalTransactional; import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboReference;
import com.alibaba.ttl.TtlRunnable;
import cn.dev33.satoken.stp.StpUtil;
import org.dromara.common.core.constant.DmsConstants; import org.dromara.common.core.constant.DmsConstants;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.DateUtils;
@ -330,16 +332,28 @@ public class DmsBillsMaintInstanceServiceImpl implements IDmsBillsMaintInstanceS
if (StringUtils.isNull(taskId)) { if (StringUtils.isNull(taskId)) {
throw new ServiceException("流程启动失败"); throw new ServiceException("流程启动失败");
}else{ }else{
//TODO:异步线程内执行updateWrokFlow // ** 异步线程上下文传递【核心问题】 **
CompletableFuture.runAsync(() -> { // 在主线程中,用户的登录信息(Token)是存放在一个叫 ThreadLocal 的"线程口袋"里的。
// 当我们使用 CompletableFuture.runAsync() 开启一个异步线程(子线程)时,
// 这个"口袋"里的东西默认是不会被带到子线程去的。
//
// ** 【解决方案】 **
// 1. 【捕获Token】: 在主线程里,我们先用 StpUtil.getTokenValue() 把Token拿出来存好。
final String tokenValue = StpUtil.getTokenValue();
// 2. 【传递与恢复】: 使用 TtlRunnable (TransmittableThreadLocal Runnable) 包装我们的异步任务。
// 它就像一个特殊的"接力棒",能在线程切换时把主线程"口袋"里的东西包括Token传递给子线程。
CompletableFuture.runAsync(TtlRunnable.get(() -> {
try { try {
// 3. 【设置上下文】: 在子线程任务开始时,立刻用 StpUtil.setTokenValue() 把传递过来的Token放进子线程自己的"口袋"。
StpUtil.setTokenValue(tokenValue);
// 4. 【执行业务】: 现在子线程就像登录过一样可以带着Token去调用其他需要权限的服务了。
updateWorkFlow(dmsBillsMaintInstance, taskId); updateWorkFlow(dmsBillsMaintInstance, taskId);
} catch (Exception e) { } catch (Exception e) {
// 简单记录错误,不影响主流程 // 简单记录错误,不影响主流程
System.err.println("异步更新工作流失败getBillsMaintCode: " + dmsBillsMaintInstance.getBillsMaintCode() + ", 错误: " + e.getMessage()); System.err.println("异步更新工作流失败getBillsMaintCode: " + dmsBillsMaintInstance.getBillsMaintCode() + ", 错误: " + e.getMessage());
// 可以考虑记录到失败表,后续补偿处理 // 可以考虑记录到失败表,后续补偿处理
} }
}); }));
} }
// 设置保养明细的实际开始时间为当前时间 // 设置保养明细的实际开始时间为当前时间
@ -452,7 +466,10 @@ public class DmsBillsMaintInstanceServiceImpl implements IDmsBillsMaintInstanceS
//FIXME:工作流相关 //FIXME:工作流相关
RemoteCompleteTask remoteCompleteTask = new RemoteCompleteTask(); RemoteCompleteTask remoteCompleteTask = new RemoteCompleteTask();
remoteCompleteTask.setTaskId(dmsBillsMaintInstance.getWfDefinitionId()); remoteCompleteTask.setTaskId(dmsBillsMaintInstance.getWfDefinitionId());
remoteCompleteTask.setMessage("同意"); remoteCompleteTask.setMessage("自动推进");
List<String> messageTypes = new ArrayList<>() ;
messageTypes.add("system");
remoteCompleteTask.setMessageType(messageTypes);
remoteWorkflowService.completeTask(remoteCompleteTask); remoteWorkflowService.completeTask(remoteCompleteTask);
// 更新保养实例信息 // 更新保养实例信息

Loading…
Cancel
Save