消息优化

This commit is contained in:
zt
2025-08-26 14:58:08 +08:00
parent 508d81bedf
commit 971101d5e8
19 changed files with 249 additions and 60 deletions

View File

@ -324,6 +324,11 @@ management:
sse: sse:
enabled: true enabled: true
path: /resource/sse path: /resource/sse
wait: /task/taskWaiting
copy: /task/taskCopyList
project: /personnel-management/project
violationRecord: /safety-management/ai/violationRecord
--- # websocket --- # websocket
websocket: websocket:

View File

@ -18,4 +18,15 @@ public class SseProperties {
* 路径 * 路径
*/ */
private String path; private String path;
private String wait;
private String copy;
private String project;
private String violationRecord;
} }

View File

@ -135,7 +135,7 @@ public class SseEmitterManager {
broadcastMessage.setMessage(sseMessageDto.getMessage()); broadcastMessage.setMessage(sseMessageDto.getMessage());
broadcastMessage.setUserIds(sseMessageDto.getUserIds()); broadcastMessage.setUserIds(sseMessageDto.getUserIds());
broadcastMessage.setRoute(sseMessageDto.getRoute()); broadcastMessage.setRoute(sseMessageDto.getRoute());
broadcastMessage.setDetailId(sseMessageDto.getDetailId()); broadcastMessage.setProjectId(sseMessageDto.getProjectId());
RedisUtils.publish(SSE_TOPIC, broadcastMessage, consumer -> { RedisUtils.publish(SSE_TOPIC, broadcastMessage, consumer -> {
log.info("SSE发送主题订阅消息topic:{} session keys:{} message:{}", log.info("SSE发送主题订阅消息topic:{} session keys:{} message:{}",
SSE_TOPIC, sseMessageDto.getUserIds(), sseMessageDto.getMessage()); SSE_TOPIC, sseMessageDto.getUserIds(), sseMessageDto.getMessage());

View File

@ -0,0 +1,25 @@
package org.dromara.common.sse.dto;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class SeeMessageContentDto implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 需要发送的消息
*/
private String type;
/**
* 路由
*/
private String content;
}

View File

@ -14,6 +14,10 @@ import java.util.List;
@Data @Data
public class SseMessageDto implements Serializable { public class SseMessageDto implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -35,6 +39,6 @@ public class SseMessageDto implements Serializable {
/** /**
* 详情 * 详情
*/ */
private String detailId; private Long projectId;
} }

View File

@ -1,11 +1,10 @@
package org.dromara.land.controller.listener; package org.dromara.common.utils.listener.excel;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.exception.ExcelDataConvertException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -0,0 +1,54 @@
package org.dromara.common.utils.listener.redis;
import cn.hutool.core.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.sse.core.SseEmitterManager;
import org.dromara.message.domain.MsgNotice;
import org.dromara.message.service.IMsgNoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
/**
* SSE 消息数据库存储监听器
*/
@Slf4j
@Component
public class SseMessageDbListener implements ApplicationRunner, Ordered {
@Autowired
private SseEmitterManager sseEmitterManager;
@Autowired
private IMsgNoticeService noticeService; // 注入你的数据库服务
@Override
public void run(ApplicationArguments args) throws Exception {
sseEmitterManager.subscribeMessage((message) -> {
log.info("SSE主题订阅收到消息session keys={} message={}", message.getUserIds(), message.getMessage());
if (CollUtil.isNotEmpty(message.getUserIds())) {
ArrayList<MsgNotice> noticeList = new ArrayList<>();
for (Long key : message.getUserIds()) {
MsgNotice notice = new MsgNotice();
notice.setContent(message.getMessage());
notice.setProjectId(message.getProjectId());
notice.setRecipientId(key);
noticeList.add(notice);
}
noticeService.saveBatch(noticeList);
}
log.info("SSE消息已存储到数据库: {}", message.getMessage());
});
log.info("初始化SSE消息数据库存储监听器成功");
}
@Override
public int getOrder() {
return 0; // 可以调整顺序
}
}

View File

@ -98,7 +98,7 @@ public class DesPrelimSchemeServiceImpl extends ServiceImpl<DesPrelimSchemeMappe
private LambdaQueryWrapper<DesPrelimScheme> buildQueryWrapper(DesPrelimSchemeBo bo) { private LambdaQueryWrapper<DesPrelimScheme> buildQueryWrapper(DesPrelimSchemeBo bo) {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<DesPrelimScheme> lqw = Wrappers.lambdaQuery(); LambdaQueryWrapper<DesPrelimScheme> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(DesPrelimScheme::getOrderNum); lqw.orderByDesc(DesPrelimScheme::getCreateTime);
lqw.orderByDesc(DesPrelimScheme::getId); lqw.orderByDesc(DesPrelimScheme::getId);
lqw.eq(bo.getProjectId() != null, DesPrelimScheme::getProjectId, bo.getProjectId()); lqw.eq(bo.getProjectId() != null, DesPrelimScheme::getProjectId, bo.getProjectId());
lqw.eq(bo.getOssId()!= null, DesPrelimScheme::getOssId, bo.getOssId()); lqw.eq(bo.getOssId()!= null, DesPrelimScheme::getOssId, bo.getOssId());
@ -207,38 +207,38 @@ public class DesPrelimSchemeServiceImpl extends ServiceImpl<DesPrelimSchemeMappe
} }
this.updateById(prelimScheme); this.updateById(prelimScheme);
//状态为已完成发送消息 //状态为已完成发送消息
if (BusinessStatusEnum.FINISH.getStatus().equals(processEvent.getStatus())) { // if (BusinessStatusEnum.FINISH.getStatus().equals(processEvent.getStatus())) {
//发送消息 // //发送消息
MsgConfig msgConfig = msgConfigService.getOne( // MsgConfig msgConfig = msgConfigService.getOne(
new LambdaQueryWrapper<MsgConfig>(). // new LambdaQueryWrapper<MsgConfig>().
eq(MsgConfig::getProjectId, prelimScheme.getProjectId()). // eq(MsgConfig::getProjectId, prelimScheme.getProjectId()).
eq(MsgConfig::getMsgKey, "prelimScheme") // eq(MsgConfig::getMsgKey, "prelimScheme")
); // );
if (msgConfig != null) { // if (msgConfig != null) {
String userId = msgConfig.getUserId(); // String userId = msgConfig.getUserId();
List<Long> userIdList = Arrays.stream(userId.split(",")) // List<Long> userIdList = Arrays.stream(userId.split(","))
.map(String::trim) // .map(String::trim)
.map(s -> { // .map(s -> {
try { // try {
return Long.valueOf(s); // return Long.valueOf(s);
} catch (NumberFormatException e) { // } catch (NumberFormatException e) {
// 处理转换失败的情况 // // 处理转换失败的情况
return null; // 或者根据需求处理 // return null; // 或者根据需求处理
} // }
}) // })
.filter(Objects::nonNull) // 过滤掉转换失败的null值 // .filter(Objects::nonNull) // 过滤掉转换失败的null值
.collect(Collectors.toList()); // .collect(Collectors.toList());
//发送消息 // //发送消息
SendMsgDto sendMsgDto = new SendMsgDto(); // SendMsgDto sendMsgDto = new SendMsgDto();
sendMsgDto.setProjectId(prelimScheme.getProjectId()); // sendMsgDto.setProjectId(prelimScheme.getProjectId());
sendMsgDto.setRecipientIds(userIdList); // sendMsgDto.setRecipientIds(userIdList);
sendMsgDto.setSenderId(0L); // sendMsgDto.setSenderId(0L);
sendMsgDto.setConfigId(msgConfig.getId()); // sendMsgDto.setConfigId(msgConfig.getId());
sendMsgDto.setDetailId(prelimScheme.getId().toString()); // sendMsgDto.setDetailId(prelimScheme.getId().toString());
sendMsgDto.setContent(msgConfig.getMsgContent()); // sendMsgDto.setContent(msgConfig.getMsgContent());
msgNoticeService.sendMsg(sendMsgDto); // msgNoticeService.sendMsg(sendMsgDto);
} // }
} // }
} }
/** /**

View File

@ -93,7 +93,7 @@ public class DesSchemeServiceImpl extends ServiceImpl<DesSchemeMapper, DesScheme
private LambdaQueryWrapper<DesScheme> buildQueryWrapper(DesSchemeBo bo) { private LambdaQueryWrapper<DesScheme> buildQueryWrapper(DesSchemeBo bo) {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<DesScheme> lqw = Wrappers.lambdaQuery(); LambdaQueryWrapper<DesScheme> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(DesScheme::getOrderNum); lqw.orderByDesc(DesScheme::getCreateTime);
lqw.orderByDesc(DesScheme::getId); lqw.orderByDesc(DesScheme::getId);
lqw.eq(bo.getProjectId() != null, DesScheme::getProjectId, bo.getProjectId()); lqw.eq(bo.getProjectId() != null, DesScheme::getProjectId, bo.getProjectId());
lqw.eq(bo.getOssId()!= null, DesScheme::getOssId, bo.getOssId()); lqw.eq(bo.getOssId()!= null, DesScheme::getOssId, bo.getOssId());

View File

@ -12,6 +12,8 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.sse.config.SseProperties;
import org.dromara.common.sse.dto.SeeMessageContentDto;
import org.dromara.common.sse.dto.SseMessageDto; import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils; import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.common.utils.JSTUtil; import org.dromara.common.utils.JSTUtil;
@ -46,6 +48,7 @@ import java.util.concurrent.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* @author lilemy * @author lilemy
* @date 2025/4/21 15:53 * @date 2025/4/21 15:53
@ -85,6 +88,9 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan
@Resource @Resource
private FacPhotovoltaicPanelPartsServiceImpl self; // 注入自己 private FacPhotovoltaicPanelPartsServiceImpl self; // 注入自己
@Resource
private SseProperties sseProperties;
/** /**
* 查询光伏板(桩点、立柱、支架)列表 * 查询光伏板(桩点、立柱、支架)列表
* *
@ -153,7 +159,10 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan
log.info("已接收第 {} 批数据,共 {} 批", batchNum, totalBatch); log.info("已接收第 {} 批数据,共 {} 批", batchNum, totalBatch);
Long userId = LoginHelper.getUserId(); Long userId = LoginHelper.getUserId();
SseMessageDto messageDto = new SseMessageDto(); SseMessageDto messageDto = new SseMessageDto();
SeeMessageContentDto contentDto = new SeeMessageContentDto();
contentDto.setType(sseProperties.getProject());
messageDto.setUserIds(List.of(userId)); messageDto.setUserIds(List.of(userId));
messageDto.setProjectId(projectId);
// 如果是最后一批,开始合并 // 如果是最后一批,开始合并
if (batchNum == totalBatch) { if (batchNum == totalBatch) {
List<FacFeatureByPoint> allData = new ArrayList<>(); List<FacFeatureByPoint> allData = new ArrayList<>();
@ -169,14 +178,16 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan
// 设置 redis key防止多次操作 // 设置 redis key防止多次操作
String operationPartsRedisKey = FacRedisKeyConstant.getPartsInOperationByProjectRedisKey(projectId); String operationPartsRedisKey = FacRedisKeyConstant.getPartsInOperationByProjectRedisKey(projectId);
redisTemplate.opsForValue().set(operationPartsRedisKey, true); redisTemplate.opsForValue().set(operationPartsRedisKey, true);
messageDto.setMessage("桩点、立柱、支架数据上传完毕,正在处理中"); contentDto.setContent("桩点、立柱、支架数据上传完毕,正在处理中");
messageDto.setMessage(JSONUtil.toJsonStr(contentDto));
SseMessageUtils.publishMessage(messageDto); SseMessageUtils.publishMessage(messageDto);
scheduledExecutorService.execute(() -> { scheduledExecutorService.execute(() -> {
try { try {
// 合并后的数据处理,如入库 // 合并后的数据处理,如入库
this.saveBatch(projectId, allData, userId); this.saveBatch(projectId, allData, userId);
} catch (Exception e) { } catch (Exception e) {
messageDto.setMessage("桩点、立柱、支架数据处理失败,请联系管理员处理"); contentDto.setContent("桩点、立柱、支架数据处理失败,请联系管理员处理");
messageDto.setMessage(JSONUtil.toJsonStr(contentDto));
SseMessageUtils.publishMessage(messageDto); SseMessageUtils.publishMessage(messageDto);
log.error("桩点、立柱、支架数据处理失败", e); log.error("桩点、立柱、支架数据处理失败", e);
throw new ServiceException("桩点、立柱、支架数据处理失败", HttpStatus.ERROR); throw new ServiceException("桩点、立柱、支架数据处理失败", HttpStatus.ERROR);
@ -188,7 +199,8 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan
} }
redisTemplate.delete(operationPartsRedisKey); redisTemplate.delete(operationPartsRedisKey);
} }
messageDto.setMessage("桩点、立柱、支架数据处理完毕"); contentDto.setContent("桩点、立柱、支架数据处理完毕");
messageDto.setMessage(JSONUtil.toJsonStr(contentDto));
SseMessageUtils.publishMessage(messageDto); SseMessageUtils.publishMessage(messageDto);
}); });
return true; return true;

View File

@ -14,6 +14,8 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.sse.config.SseProperties;
import org.dromara.common.sse.dto.SeeMessageContentDto;
import org.dromara.common.sse.dto.SseMessageDto; import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils; import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.common.utils.JSTUtil; import org.dromara.common.utils.JSTUtil;
@ -83,6 +85,9 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
@Resource @Resource
private FacPhotovoltaicPanelServiceImpl self; // 注入自己 private FacPhotovoltaicPanelServiceImpl self; // 注入自己
@Resource
private SseProperties sseProperties;
/** /**
* 查询设施-光伏板 * 查询设施-光伏板
* *
@ -214,7 +219,10 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
log.info("已接收第 {} 批数据,共 {} 批", batchNum, totalBatch); log.info("已接收第 {} 批数据,共 {} 批", batchNum, totalBatch);
Long userId = LoginHelper.getUserId(); Long userId = LoginHelper.getUserId();
SseMessageDto messageDto = new SseMessageDto(); SseMessageDto messageDto = new SseMessageDto();
SeeMessageContentDto contentDto = new SeeMessageContentDto();
contentDto.setType(sseProperties.getProject());
messageDto.setUserIds(List.of(userId)); messageDto.setUserIds(List.of(userId));
messageDto.setProjectId(projectId);
// 如果是最后一批,开始合并 // 如果是最后一批,开始合并
if (batchNum == totalBatch) { if (batchNum == totalBatch) {
List<FacFeatureByPlane> locationFeatures = new ArrayList<>(); List<FacFeatureByPlane> locationFeatures = new ArrayList<>();
@ -238,7 +246,8 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
// 设置 redis key防止多次操作 // 设置 redis key防止多次操作
String operationPanelRedisKey = FacRedisKeyConstant.getPanelInOperationByProjectRedisKey(projectId); String operationPanelRedisKey = FacRedisKeyConstant.getPanelInOperationByProjectRedisKey(projectId);
redisTemplate.opsForValue().set(operationPanelRedisKey, true); redisTemplate.opsForValue().set(operationPanelRedisKey, true);
messageDto.setMessage("光伏板数据上传完毕,正在处理中"); contentDto.setContent("光伏板数据上传完毕,正在处理中");
messageDto.setMessage(JSONUtil.toJsonStr(contentDto));
SseMessageUtils.publishMessage(messageDto); SseMessageUtils.publishMessage(messageDto);
scheduledExecutorService.execute(() -> { scheduledExecutorService.execute(() -> {
try { try {
@ -388,10 +397,12 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
if (!result) { if (!result) {
throw new ServiceException("更新进度类别失败,数据库异常", HttpStatus.ERROR); throw new ServiceException("更新进度类别失败,数据库异常", HttpStatus.ERROR);
} }
messageDto.setMessage("光伏板数据处理完毕"); contentDto.setContent("光伏板数据处理完毕");
messageDto.setMessage(JSONUtil.toJsonStr(contentDto));
SseMessageUtils.publishMessage(messageDto); SseMessageUtils.publishMessage(messageDto);
} catch (Exception e) { } catch (Exception e) {
messageDto.setMessage("光伏板数据处理失败,请联系管理员处理"); contentDto.setContent("光伏板数据处理失败,请联系管理员处理");
messageDto.setMessage(JSONUtil.toJsonStr(contentDto));
SseMessageUtils.publishMessage(messageDto); SseMessageUtils.publishMessage(messageDto);
log.error("光伏板数据处理失败", e); log.error("光伏板数据处理失败", e);
throw new ServiceException("光伏板数据处理失败", HttpStatus.ERROR); throw new ServiceException("光伏板数据处理失败", HttpStatus.ERROR);

View File

@ -19,12 +19,10 @@ import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
import org.dromara.land.controller.listener.GenericExcelListener; import org.dromara.common.utils.listener.excel.GenericExcelListener;
import org.dromara.land.domain.BusEnterRoad; import org.dromara.land.domain.BusEnterRoad;
import org.dromara.land.domain.BusLandBlock;
import org.dromara.land.domain.bo.BusEnterRoadBo; import org.dromara.land.domain.bo.BusEnterRoadBo;
import org.dromara.land.domain.bo.BusEnterRoadImportBo; import org.dromara.land.domain.bo.BusEnterRoadImportBo;
import org.dromara.land.domain.bo.BusLandBlockImportBo;
import org.dromara.land.domain.vo.BusEnterRoadVo; import org.dromara.land.domain.vo.BusEnterRoadVo;
import org.dromara.land.service.IBusEnterRoadService; import org.dromara.land.service.IBusEnterRoadService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -41,7 +39,6 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**

View File

@ -19,7 +19,7 @@ import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
import org.dromara.land.controller.listener.GenericExcelListener; import org.dromara.common.utils.listener.excel.GenericExcelListener;
import org.dromara.land.domain.BusLandBlock; import org.dromara.land.domain.BusLandBlock;
import org.dromara.land.domain.bo.BusLandBlockBo; import org.dromara.land.domain.bo.BusLandBlockBo;
import org.dromara.land.domain.bo.BusLandBlockImportBo; import org.dromara.land.domain.bo.BusLandBlockImportBo;
@ -32,7 +32,6 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**

View File

@ -200,7 +200,6 @@ public class MsgNoticeServiceImpl extends ServiceImpl<MsgNoticeMapper, MsgNotice
messageDto2.setUserIds(recipientIds); messageDto2.setUserIds(recipientIds);
messageDto2.setMessage(bo.getContent()); messageDto2.setMessage(bo.getContent());
messageDto2.setRoute(byId.getRoute()); messageDto2.setRoute(byId.getRoute());
messageDto2.setDetailId(bo.getDetailId());
Gson gson = new Gson(); Gson gson = new Gson();
String messageDtoJson = gson.toJson(messageDto2); String messageDtoJson = gson.toJson(messageDto2);

View File

@ -19,6 +19,8 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.sse.config.SseProperties;
import org.dromara.common.sse.dto.SeeMessageContentDto;
import org.dromara.common.sse.dto.SseMessageDto; import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils; import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.common.utils.Dxf2JsonUtil; import org.dromara.common.utils.Dxf2JsonUtil;
@ -71,6 +73,9 @@ public class BusProjectFileServiceImpl extends ServiceImpl<BusProjectFileMapper,
@Value("${dxf2GeoJson.file-name}") @Value("${dxf2GeoJson.file-name}")
private String dxf2GeoJsonFileName; private String dxf2GeoJsonFileName;
@Resource
private SseProperties sseProperties;
/** /**
* 查询项目文件存储 * 查询项目文件存储
* *
@ -292,8 +297,12 @@ public class BusProjectFileServiceImpl extends ServiceImpl<BusProjectFileMapper,
projectFileId = null; projectFileId = null;
} }
SseMessageDto messageDto = new SseMessageDto(); SseMessageDto messageDto = new SseMessageDto();
messageDto.setMessage("DXF 文件上传成功,正在转换中......"); SeeMessageContentDto contentDto = new SeeMessageContentDto();
contentDto.setType(sseProperties.getProject());
contentDto.setContent("DXF 文件上传成功,正在转换中......");
messageDto.setMessage(JSONUtil.toJsonStr(contentDto));
messageDto.setUserIds(List.of(userId)); messageDto.setUserIds(List.of(userId));
messageDto.setProjectId(projectId);
SseMessageUtils.publishMessage(messageDto); SseMessageUtils.publishMessage(messageDto);
scheduledExecutorService.execute(() -> { scheduledExecutorService.execute(() -> {
try { try {
@ -311,11 +320,13 @@ public class BusProjectFileServiceImpl extends ServiceImpl<BusProjectFileMapper,
projectFile.setRemark(dxfFilePath); projectFile.setRemark(dxfFilePath);
boolean update = this.saveOrUpdate(projectFile); boolean update = this.saveOrUpdate(projectFile);
if (!update) throw new ServiceException("数据库修改异常"); if (!update) throw new ServiceException("数据库修改异常");
messageDto.setMessage("DXF 文件转换成 GeoJSON 成功"); contentDto.setContent("DXF 文件转换成 GeoJSON 成功");
messageDto.setMessage(JSONUtil.toJsonStr(contentDto));
SseMessageUtils.publishMessage(messageDto); SseMessageUtils.publishMessage(messageDto);
} catch (Exception e) { } catch (Exception e) {
log.error("DXF 转换失败", e); log.error("DXF 转换失败", e);
messageDto.setMessage("DXF 文件转换失败,请联系管理员处理"); contentDto.setContent("DXF 文件转换失败,请联系管理员处理");
messageDto.setMessage(JSONUtil.toJsonStr(contentDto));
SseMessageUtils.publishMessage(messageDto); SseMessageUtils.publishMessage(messageDto);
} finally { } finally {
// 无论成功或失败都释放状态 // 无论成功或失败都释放状态

View File

@ -1,6 +1,7 @@
package org.dromara.safety.service.impl; package org.dromara.safety.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -13,6 +14,8 @@ import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.sse.config.SseProperties;
import org.dromara.common.sse.dto.SeeMessageContentDto;
import org.dromara.common.sse.dto.SseMessageDto; import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils; import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.safety.domain.HseRecognizeRecord; import org.dromara.safety.domain.HseRecognizeRecord;
@ -65,6 +68,9 @@ public class HseViolationRecordServiceImpl extends ServiceImpl<HseViolationRecor
@Resource @Resource
private IHseViolationLevelPostService violationLevelPostService; private IHseViolationLevelPostService violationLevelPostService;
@Resource
private SseProperties sseProperties;
/** /**
* 查询违规记录 * 查询违规记录
* *
@ -193,7 +199,11 @@ public class HseViolationRecordServiceImpl extends ServiceImpl<HseViolationRecor
SseMessageDto messageDto = new SseMessageDto(); SseMessageDto messageDto = new SseMessageDto();
messageDto.setUserIds(new ArrayList<>(userIds)); messageDto.setUserIds(new ArrayList<>(userIds));
for (HseViolationRecord violationRecord : violationRecordList) { for (HseViolationRecord violationRecord : violationRecordList) {
messageDto.setMessage("您有一份重要的违章需要处理!工单号为:" + violationRecord.getId()); SeeMessageContentDto seeMessageContentDto = new SeeMessageContentDto();
seeMessageContentDto.setType(sseProperties.getViolationRecord());
seeMessageContentDto.setContent("您有一份重要的违章需要处理!工单号为:" + violationRecord.getId());
messageDto.setMessage(JSONUtil.toJsonStr(seeMessageContentDto));
messageDto.setProjectId(violationRecord.getProjectId());
SseMessageUtils.publishMessage(messageDto); SseMessageUtils.publishMessage(messageDto);
} }
} }

View File

@ -143,13 +143,15 @@ public class WorkflowGlobalListener implements GlobalListener {
List<FlowCopyBo> flowCopyList = (List<FlowCopyBo>) variable.get(FlowConstant.FLOW_COPY_LIST); List<FlowCopyBo> flowCopyList = (List<FlowCopyBo>) variable.get(FlowConstant.FLOW_COPY_LIST);
// 添加抄送人 // 添加抄送人
flwTaskService.setCopy(task, flowCopyList); flwTaskService.setCopy(task, flowCopyList);
//发送抄送消息
flwCommonService.sendCopyMessage(definition.getFlowName(), definition.getFlowCode(), flowCopyList);
} }
if (variable.containsKey(FlowConstant.MESSAGE_TYPE)) { if (variable.containsKey(FlowConstant.MESSAGE_TYPE)) {
List<String> messageType = (List<String>) variable.get(FlowConstant.MESSAGE_TYPE); List<String> messageType = (List<String>) variable.get(FlowConstant.MESSAGE_TYPE);
String notice = (String) variable.get(FlowConstant.MESSAGE_NOTICE); String notice = (String) variable.get(FlowConstant.MESSAGE_NOTICE);
// 消息通知 // 消息通知
if (CollUtil.isNotEmpty(messageType)) { if (CollUtil.isNotEmpty(messageType)) {
flwCommonService.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice); flwCommonService.sendMessage(definition.getFlowName(),definition.getFlowCode(), instance.getId(), messageType, notice);
} }
} }
FlowInstance ins = new FlowInstance(); FlowInstance ins = new FlowInstance();

View File

@ -1,5 +1,7 @@
package org.dromara.workflow.service; package org.dromara.workflow.service;
import org.dromara.workflow.domain.bo.FlowCopyBo;
import java.util.List; import java.util.List;
/** /**
@ -25,7 +27,12 @@ public interface IFlwCommonService {
* @param messageType 消息类型 * @param messageType 消息类型
* @param message 消息内容,为空则发送默认配置的消息内容 * @param message 消息内容,为空则发送默认配置的消息内容
*/ */
void sendMessage(String flowName, Long instId, List<String> messageType, String message); void sendMessage(String flowName,String flowCode, Long instId, List<String> messageType, String message);
/**
* 发送抄送消息
*/
void sendCopyMessage(String flowName, String flowCode, List<FlowCopyBo> flowCopyList);
/** /**
* 申请人节点编码 * 申请人节点编码

View File

@ -2,13 +2,17 @@ package org.dromara.workflow.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.dto.UserDTO; import org.dromara.common.core.domain.dto.UserDTO;
import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mail.utils.MailUtils; import org.dromara.common.mail.utils.MailUtils;
import org.dromara.common.sse.config.SseProperties;
import org.dromara.common.sse.dto.SeeMessageContentDto;
import org.dromara.common.sse.dto.SseMessageDto; import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils; import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.warm.flow.core.entity.Node; import org.dromara.warm.flow.core.entity.Node;
@ -18,6 +22,7 @@ import org.dromara.warm.flow.core.service.NodeService;
import org.dromara.warm.flow.orm.entity.FlowTask; import org.dromara.warm.flow.orm.entity.FlowTask;
import org.dromara.workflow.common.ConditionalOnEnable; import org.dromara.workflow.common.ConditionalOnEnable;
import org.dromara.workflow.common.enums.MessageTypeEnum; import org.dromara.workflow.common.enums.MessageTypeEnum;
import org.dromara.workflow.domain.bo.FlowCopyBo;
import org.dromara.workflow.service.IFlwCommonService; import org.dromara.workflow.service.IFlwCommonService;
import org.dromara.workflow.service.IFlwTaskAssigneeService; import org.dromara.workflow.service.IFlwTaskAssigneeService;
import org.dromara.workflow.service.IFlwTaskService; import org.dromara.workflow.service.IFlwTaskService;
@ -40,6 +45,8 @@ import java.util.stream.Collectors;
public class FlwCommonServiceImpl implements IFlwCommonService { public class FlwCommonServiceImpl implements IFlwCommonService {
private final NodeService nodeService; private final NodeService nodeService;
private final SseProperties properties;
/** /**
* 构建工作流用户 * 构建工作流用户
* *
@ -68,13 +75,14 @@ public class FlwCommonServiceImpl implements IFlwCommonService {
* @param message 消息内容,为空则发送默认配置的消息内容 * @param message 消息内容,为空则发送默认配置的消息内容
*/ */
@Override @Override
public void sendMessage(String flowName, Long instId, List<String> messageType, String message) { public void sendMessage(String flowName,String flowCode, Long instId, List<String> messageType, String message) {
IFlwTaskService flwTaskService = SpringUtils.getBean(IFlwTaskService.class); IFlwTaskService flwTaskService = SpringUtils.getBean(IFlwTaskService.class);
List<UserDTO> userList = new ArrayList<>(); List<UserDTO> userList = new ArrayList<>();
List<FlowTask> list = flwTaskService.selectByInstId(instId); List<FlowTask> list = flwTaskService.selectByInstId(instId);
if (StringUtils.isBlank(message)) { if (StringUtils.isBlank(message)) {
message = "有新的【" + flowName + "】单据已经提交至您,请您及时处理。"; message = "有新的【" + flowName + "】单据已经提交至您,请您及时处理。";
} }
for (Task task : list) { for (Task task : list) {
List<UserDTO> users = flwTaskService.currentTaskAllUser(task.getId()); List<UserDTO> users = flwTaskService.currentTaskAllUser(task.getId());
if (CollUtil.isNotEmpty(users)) { if (CollUtil.isNotEmpty(users)) {
@ -88,8 +96,20 @@ public class FlwCommonServiceImpl implements IFlwCommonService {
switch (messageTypeEnum) { switch (messageTypeEnum) {
case SYSTEM_MESSAGE: case SYSTEM_MESSAGE:
SseMessageDto dto = new SseMessageDto(); SseMessageDto dto = new SseMessageDto();
SeeMessageContentDto contentDto = new SeeMessageContentDto();
dto.setUserIds(StreamUtils.toList(userList, UserDTO::getUserId).stream().distinct().collect(Collectors.toList())); dto.setUserIds(StreamUtils.toList(userList, UserDTO::getUserId).stream().distinct().collect(Collectors.toList()));
dto.setMessage(message); contentDto.setType(properties.getWait());
contentDto.setContent(message);
dto.setMessage(JSONUtil.toJsonStr(contentDto));
String[] parts = flowCode.split("_");
String projectCode = parts.length > 0 ? parts[0] : "0";
try {
Long projectId = Long.valueOf(projectCode);
dto.setProjectId(projectId);
} catch (NumberFormatException e) {
log.warn("项目编码转换为Long类型失败: {}, 使用默认值0", projectCode);
dto.setProjectId(0L);
}
SseMessageUtils.publishMessage(dto); SseMessageUtils.publishMessage(dto);
break; break;
case EMAIL_MESSAGE: case EMAIL_MESSAGE:
@ -107,6 +127,29 @@ public class FlwCommonServiceImpl implements IFlwCommonService {
} }
@Override
public void sendCopyMessage(String flowName, String flowCode, List<FlowCopyBo> flowCopyList) {
if(CollUtil.isEmpty(flowCopyList)){
return;
}
SseMessageDto dto = new SseMessageDto();
SeeMessageContentDto contentDto = new SeeMessageContentDto();
dto.setUserIds(StreamUtils.toList(flowCopyList, FlowCopyBo::getUserId).stream().distinct().collect(Collectors.toList()));
contentDto.setType(properties.getCopy());
contentDto.setContent("有新的【" + flowName + "】单据已经提交至您,请您及时查看。");
dto.setMessage(JSONUtil.toJsonStr(contentDto));
String[] parts = flowCode.split("_");
String projectCode = parts.length > 0 ? parts[0] : "0";
try {
Long projectId = Long.valueOf(projectCode);
dto.setProjectId(projectId);
} catch (NumberFormatException e) {
log.warn("项目编码转换为Long类型失败: {}, 使用默认值0", projectCode);
dto.setProjectId(0L);
}
SseMessageUtils.publishMessage(dto);
}
/** /**
* 申请人节点编码 * 申请人节点编码
* *