|
@@ -10,28 +10,24 @@ import com.zksy.base.warning.domain.*;
|
|
|
import com.zksy.base.warning.domain.vo.MobileWarningParticipantVO;
|
|
import com.zksy.base.warning.domain.vo.MobileWarningParticipantVO;
|
|
|
import com.zksy.base.warning.dto.MobileWarningQuery;
|
|
import com.zksy.base.warning.dto.MobileWarningQuery;
|
|
|
import com.zksy.base.warning.mapper.*;
|
|
import com.zksy.base.warning.mapper.*;
|
|
|
-import com.zksy.base.warning.service.EarlyWarningService;
|
|
|
|
|
-import com.zksy.base.warning.service.WarningSupervisionNotifier;
|
|
|
|
|
-import com.zksy.base.warning.service.WarningProcessAttachmentService;
|
|
|
|
|
-import com.zksy.base.warning.service.WarningAccessService;
|
|
|
|
|
-import com.zksy.base.warning.service.WarningParticipantService;
|
|
|
|
|
-import com.zksy.common.core.domain.entity.SysDictData;
|
|
|
|
|
|
|
+import com.zksy.base.warning.service.*;
|
|
|
import com.zksy.common.core.domain.entity.SysUser;
|
|
import com.zksy.common.core.domain.entity.SysUser;
|
|
|
-import com.zksy.system.mapper.SysUserMapper;
|
|
|
|
|
-import com.zksy.common.utils.DictUtils;
|
|
|
|
|
-import com.zksy.common.utils.SecurityUtils;
|
|
|
|
|
import com.zksy.common.exception.ServiceException;
|
|
import com.zksy.common.exception.ServiceException;
|
|
|
import com.zksy.common.sms.SmsProperties;
|
|
import com.zksy.common.sms.SmsProperties;
|
|
|
import com.zksy.common.sms.SmsTemplate;
|
|
import com.zksy.common.sms.SmsTemplate;
|
|
|
-import com.zksy.service.MinioFileStorageService;
|
|
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
|
+import com.zksy.common.utils.SecurityUtils;
|
|
|
|
|
+import com.zksy.common.utils.file.MinioPathUtils;
|
|
|
|
|
+import io.minio.MinioClient;
|
|
|
|
|
+import io.minio.RemoveObjectArgs;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
+import com.zksy.system.mapper.SysUserMapper;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.ObjectProvider;
|
|
import org.springframework.beans.factory.ObjectProvider;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.transaction.support.TransactionSynchronization;
|
|
import org.springframework.transaction.support.TransactionSynchronization;
|
|
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
-import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.ZoneId;
|
|
import java.time.ZoneId;
|
|
@@ -41,15 +37,18 @@ import java.util.concurrent.ThreadLocalRandom;
|
|
|
|
|
|
|
|
@Service
|
|
@Service
|
|
|
@Slf4j
|
|
@Slf4j
|
|
|
-public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, EarlyWarning>
|
|
|
|
|
- implements EarlyWarningService {
|
|
|
|
|
|
|
+public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, EarlyWarning> implements EarlyWarningService {
|
|
|
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private EarlyWarningMapper earlyWarningMapper;
|
|
private EarlyWarningMapper earlyWarningMapper;
|
|
|
- @Autowired private EquipmentBaseMapper equipmentBaseMapper;
|
|
|
|
|
- @Autowired private com.zksy.base.warning.service.WarningItemBindingService itemBinding;
|
|
|
|
|
- @Autowired private WarningReasonMapper warningReasonMapper;
|
|
|
|
|
- @Autowired private com.zksy.base.warning.service.WarningReferenceService reference;
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private EquipmentBaseMapper equipmentBaseMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private com.zksy.base.warning.service.WarningItemBindingService itemBinding;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private WarningReasonMapper warningReasonMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private com.zksy.base.warning.service.WarningReferenceService reference;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private AlarmWarningRelMapper alarmWarningRelMapper;
|
|
private AlarmWarningRelMapper alarmWarningRelMapper;
|
|
|
@Autowired
|
|
@Autowired
|
|
@@ -65,19 +64,22 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private WarningArchiveMapper warningArchiveMapper;
|
|
private WarningArchiveMapper warningArchiveMapper;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
- private MinioFileStorageService minioFileStorageService;
|
|
|
|
|
|
|
+ private MinioClient minioClient;
|
|
|
|
|
+
|
|
|
|
|
+ @Value("${minio.bucket}")
|
|
|
|
|
+ private String minioBucket;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private SysUserMapper sysUserMapper;
|
|
private SysUserMapper sysUserMapper;
|
|
|
- @Autowired private WarningAccessService warningAccess;
|
|
|
|
|
- @Autowired private WarningParticipantService participants;
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private WarningAccessService warningAccess;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private WarningParticipantService participants;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private ObjectProvider<SmsTemplate> smsTemplateProvider;
|
|
private ObjectProvider<SmsTemplate> smsTemplateProvider;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private SmsProperties smsProperties;
|
|
private SmsProperties smsProperties;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private WarningSupervisionNotifier supervisionNotifier;
|
|
private WarningSupervisionNotifier supervisionNotifier;
|
|
|
- @Autowired
|
|
|
|
|
- private WarningProcessAttachmentService processAttachmentService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public IPage<Map<String, Object>> getWarningList(Page<?> page, String warningNo, String warningType, String warningLevel, String status) {
|
|
public IPage<Map<String, Object>> getWarningList(Page<?> page, String warningNo, String warningType, String warningLevel, String status) {
|
|
@@ -110,8 +112,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
if (!isBlank(type) && !Arrays.asList("TODO", "DONE", "NOTICE").contains(type)) {
|
|
if (!isBlank(type) && !Arrays.asList("TODO", "DONE", "NOTICE").contains(type)) {
|
|
|
throw new ServiceException("待办类型只能为 TODO、DONE 或 NOTICE");
|
|
throw new ServiceException("待办类型只能为 TODO、DONE 或 NOTICE");
|
|
|
}
|
|
}
|
|
|
- IPage<Map<String, Object>> result = earlyWarningMapper.selectMyTasks(page, currentUser(),
|
|
|
|
|
- String.valueOf(SecurityUtils.getUserId()), filters, warningAccess.current());
|
|
|
|
|
|
|
+ IPage<Map<String, Object>> result = earlyWarningMapper.selectMyTasks(page, currentUser(), String.valueOf(SecurityUtils.getUserId()), filters, warningAccess.current());
|
|
|
result.getRecords().forEach(this::addWorkflowActions);
|
|
result.getRecords().forEach(this::addWorkflowActions);
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
@@ -145,9 +146,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
throw new ServiceException("预警状态不正确");
|
|
throw new ServiceException("预警状态不正确");
|
|
|
}
|
|
}
|
|
|
Page<Map<String, Object>> page = new Page<>(safeQuery.getPageNum(), safeQuery.getPageSize());
|
|
Page<Map<String, Object>> page = new Page<>(safeQuery.getPageNum(), safeQuery.getPageSize());
|
|
|
- IPage<Map<String, Object>> result = earlyWarningMapper.selectMobileWarnings(page, warningAccess.current(),
|
|
|
|
|
- trimToNull(safeQuery.getKeyword()), trimToNull(safeQuery.getStatus()),
|
|
|
|
|
- trimToNull(safeQuery.getWarningType()), trimToNull(safeQuery.getWarningLevel()), pendingOnly);
|
|
|
|
|
|
|
+ IPage<Map<String, Object>> result = earlyWarningMapper.selectMobileWarnings(page, warningAccess.current(), trimToNull(safeQuery.getKeyword()), trimToNull(safeQuery.getStatus()), trimToNull(safeQuery.getWarningType()), trimToNull(safeQuery.getWarningLevel()), pendingOnly);
|
|
|
result.getRecords().forEach(this::addMobileWorkflowActions);
|
|
result.getRecords().forEach(this::addMobileWorkflowActions);
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
@@ -159,8 +158,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
if (detail == null) throw new ServiceException("预警不存在");
|
|
if (detail == null) throw new ServiceException("预警不存在");
|
|
|
Object basic = detail.get("basicInfo");
|
|
Object basic = detail.get("basicInfo");
|
|
|
if (basic instanceof Map) {
|
|
if (basic instanceof Map) {
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
- Map<String, Object> basicInfo = (Map<String, Object>) basic;
|
|
|
|
|
|
|
+ @SuppressWarnings("unchecked") Map<String, Object> basicInfo = (Map<String, Object>) basic;
|
|
|
addMobileWorkflowActions(basicInfo);
|
|
addMobileWorkflowActions(basicInfo);
|
|
|
}
|
|
}
|
|
|
return detail;
|
|
return detail;
|
|
@@ -173,17 +171,12 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public List<MobileWarningParticipantVO> getMobileWarningParticipants(String warningId, String role) {
|
|
public List<MobileWarningParticipantVO> getMobileWarningParticipants(String warningId, String role) {
|
|
|
- return participants.candidates(warningId, role, null, null).stream()
|
|
|
|
|
- .map(user -> new MobileWarningParticipantVO(user.getUserId(), user.getUserName(),
|
|
|
|
|
- isBlank(user.getNickName()) ? user.getUserName() : user.getNickName(), user.getDeptId(),
|
|
|
|
|
- user.getDeptName()))
|
|
|
|
|
- .collect(java.util.stream.Collectors.toList());
|
|
|
|
|
|
|
+ return participants.candidates(warningId, role, null, null).stream().map(user -> new MobileWarningParticipantVO(user.getUserId(), user.getUserName(), isBlank(user.getNickName()) ? user.getUserName() : user.getNickName(), user.getDeptId(), user.getDeptName())).collect(java.util.stream.Collectors.toList());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void addMobileWorkflowActions(Map<String, Object> row) {
|
|
private void addMobileWorkflowActions(Map<String, Object> row) {
|
|
|
addWorkflowActions(row);
|
|
addWorkflowActions(row);
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
- List<String> actions = new ArrayList<>((List<String>) row.get("availableActions"));
|
|
|
|
|
|
|
+ @SuppressWarnings("unchecked") List<String> actions = new ArrayList<>((List<String>) row.get("availableActions"));
|
|
|
actions.retainAll(Arrays.asList("PUBLISH", "RECEIVE", "START", "HANDLE", "CLEAR", "RETURN"));
|
|
actions.retainAll(Arrays.asList("PUBLISH", "RECEIVE", "START", "HANDLE", "CLEAR", "RETURN"));
|
|
|
row.put("availableActions", actions);
|
|
row.put("availableActions", actions);
|
|
|
}
|
|
}
|
|
@@ -251,7 +244,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public boolean saveWarning(EarlyWarning warning, List<String> alarmIds, List<MultipartFile> files) {
|
|
|
|
|
|
|
+ public boolean saveWarning(EarlyWarning warning, List<String> alarmIds, List<String> attachmentPaths) {
|
|
|
reference.validateType(warning.getWarningType());
|
|
reference.validateType(warning.getWarningType());
|
|
|
bindRequiredDevice(warning);
|
|
bindRequiredDevice(warning);
|
|
|
warning.setWarningId(null);
|
|
warning.setWarningId(null);
|
|
@@ -273,8 +266,8 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
if (alarmIds != null && !alarmIds.isEmpty()) {
|
|
if (alarmIds != null && !alarmIds.isEmpty()) {
|
|
|
linkAlarms(warning.getWarningId(), alarmIds);
|
|
linkAlarms(warning.getWarningId(), alarmIds);
|
|
|
}
|
|
}
|
|
|
- if (files != null && !files.isEmpty()) {
|
|
|
|
|
- saveAttachments(warning.getWarningId(), null, "REPORT", files);
|
|
|
|
|
|
|
+ if (attachmentPaths != null && !attachmentPaths.isEmpty()) {
|
|
|
|
|
+ saveAttachments(warning.getWarningId(), null, "REPORT", attachmentPaths);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
return result;
|
|
return result;
|
|
@@ -285,63 +278,65 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
* 与 zk-api-service 的 AlarmLifecycleSupport.nextWarningNo() 保持同一种子公式。
|
|
* 与 zk-api-service 的 AlarmLifecycleSupport.nextWarningNo() 保持同一种子公式。
|
|
|
*/
|
|
*/
|
|
|
private static String generateWarningNo() {
|
|
private static String generateWarningNo() {
|
|
|
- return "YJ"
|
|
|
|
|
- + LocalDateTime.now(ZoneId.of("Asia/Shanghai")).format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))
|
|
|
|
|
- + String.format(Locale.ROOT, "%04d", ThreadLocalRandom.current().nextInt(10000));
|
|
|
|
|
|
|
+ return "YJ" + LocalDateTime.now(ZoneId.of("Asia/Shanghai")).format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + String.format(Locale.ROOT, "%04d", ThreadLocalRandom.current().nextInt(10000));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 保存附件
|
|
* 保存附件
|
|
|
*/
|
|
*/
|
|
|
- private void saveAttachments(String warningId, List<MultipartFile> files) {
|
|
|
|
|
- saveAttachments(warningId, null, "REPORT", files);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private List<WarningAttachment> saveAttachments(String warningId, String disposalId, String stage, List<MultipartFile> files) {
|
|
|
|
|
|
|
+ private List<WarningAttachment> saveAttachments(String warningId, String disposalId, String stage, List<String> paths) {
|
|
|
List<WarningAttachment> saved = new ArrayList<>();
|
|
List<WarningAttachment> saved = new ArrayList<>();
|
|
|
- try {
|
|
|
|
|
- for (MultipartFile file : files) {
|
|
|
|
|
- validateAttachment(file);
|
|
|
|
|
- String path = minioFileStorageService.uploadFile(file, "warning");
|
|
|
|
|
- if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
|
|
|
|
- TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
|
|
|
|
- @Override public void afterCompletion(int status) {
|
|
|
|
|
- if (status == STATUS_ROLLED_BACK) {
|
|
|
|
|
- try { minioFileStorageService.deleteFile(path); }
|
|
|
|
|
- catch (Exception ignored) { log.warn("预警附件事务回滚后的文件清理失败"); }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- // 上传文件
|
|
|
|
|
- String fileName = file.getOriginalFilename();
|
|
|
|
|
- if (fileName == null || fileName.trim().isEmpty()) {
|
|
|
|
|
- fileName = path.substring(path.lastIndexOf("/") + 1);
|
|
|
|
|
- }
|
|
|
|
|
- // 保存附件信息
|
|
|
|
|
- WarningAttachment attachment = new WarningAttachment();
|
|
|
|
|
- attachment.setWarningId(warningId);
|
|
|
|
|
- attachment.setDisposalId(disposalId);
|
|
|
|
|
- attachment.setAttachmentStage(stage);
|
|
|
|
|
- attachment.setCreateBy(currentUser());
|
|
|
|
|
- attachment.setAttachmentName(("PROCESS".equals(stage) ? "[处理反馈] " : "SUPERVISION".equals(stage) ? "[督办附件] " : "[预警报告] ") + fileName);
|
|
|
|
|
- attachment.setAttachmentUrl(path);
|
|
|
|
|
- // 部分 MIME(如 vnd.openxmlformats-officedocument.*)长度超过 64,写入前按 DB 列宽截断兜底
|
|
|
|
|
- attachment.setAttachmentType(truncateAttachmentType(file.getContentType()));
|
|
|
|
|
- attachment.setAttachmentSize(file.getSize());
|
|
|
|
|
- attachment.setCreateTime(LocalDateTime.now());
|
|
|
|
|
- warningAttachmentMapper.insert(attachment);
|
|
|
|
|
- saved.add(attachment);
|
|
|
|
|
- }
|
|
|
|
|
- return saved;
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- throw new RuntimeException("附件保存失败", e);
|
|
|
|
|
|
|
+ if (paths == null) return saved;
|
|
|
|
|
+ for (String raw : paths) {
|
|
|
|
|
+ if (isBlank(raw)) continue;
|
|
|
|
|
+ String path = validateAttachmentPath(raw);
|
|
|
|
|
+ String fileName = path.substring(path.lastIndexOf("/") + 1);
|
|
|
|
|
+ String extension = fileName.contains(".") ? fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(Locale.ROOT) : "";
|
|
|
|
|
+ WarningAttachment attachment = new WarningAttachment();
|
|
|
|
|
+ attachment.setWarningId(warningId);
|
|
|
|
|
+ attachment.setDisposalId(disposalId);
|
|
|
|
|
+ attachment.setAttachmentStage(stage);
|
|
|
|
|
+ attachment.setCreateBy(currentUser());
|
|
|
|
|
+ attachment.setAttachmentName(("PROCESS".equals(stage) ? "[处理反馈] " : "SUPERVISION".equals(stage) ? "[督办附件] " : "[预警报告] ") + fileName);
|
|
|
|
|
+ attachment.setAttachmentUrl(path);
|
|
|
|
|
+ attachment.setAttachmentType(contentTypeForExtension(extension));
|
|
|
|
|
+ attachment.setAttachmentSize(null);
|
|
|
|
|
+ attachment.setCreateTime(LocalDateTime.now());
|
|
|
|
|
+ warningAttachmentMapper.insert(attachment);
|
|
|
|
|
+ saved.add(attachment);
|
|
|
|
|
+ }
|
|
|
|
|
+ return saved;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static String contentTypeForExtension(String extension) {
|
|
|
|
|
+ switch (extension) {
|
|
|
|
|
+ case "jpg":
|
|
|
|
|
+ case "jpeg":
|
|
|
|
|
+ return "image/jpeg";
|
|
|
|
|
+ case "png":
|
|
|
|
|
+ return "image/png";
|
|
|
|
|
+ case "gif":
|
|
|
|
|
+ return "image/gif";
|
|
|
|
|
+ case "webp":
|
|
|
|
|
+ return "image/webp";
|
|
|
|
|
+ case "pdf":
|
|
|
|
|
+ return "application/pdf";
|
|
|
|
|
+ case "xls":
|
|
|
|
|
+ return "application/vnd.ms-excel";
|
|
|
|
|
+ case "xlsx":
|
|
|
|
|
+ return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
|
|
|
+ case "doc":
|
|
|
|
|
+ return "application/msword";
|
|
|
|
|
+ case "docx":
|
|
|
|
|
+ return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
|
|
|
|
+ default:
|
|
|
|
|
+ return "application/octet-stream";
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public boolean updateWarning(EarlyWarning warning, List<String> alarmIds, List<MultipartFile> files) {
|
|
|
|
|
|
|
+ public boolean updateWarning(EarlyWarning warning, List<String> alarmIds, List<String> attachmentPaths) {
|
|
|
warningAccess.requireVisible(warning.getWarningId());
|
|
warningAccess.requireVisible(warning.getWarningId());
|
|
|
EarlyWarning existing = earlyWarningMapper.selectForUpdate(warning.getWarningId());
|
|
EarlyWarning existing = earlyWarningMapper.selectForUpdate(warning.getWarningId());
|
|
|
WarningWorkflow.requireState(existing, "修改草稿", WarningWorkflow.DRAFT);
|
|
WarningWorkflow.requireState(existing, "修改草稿", WarningWorkflow.DRAFT);
|
|
@@ -364,21 +359,22 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
if (alarmIds != null) {
|
|
if (alarmIds != null) {
|
|
|
linkAlarms(warning.getWarningId(), alarmIds);
|
|
linkAlarms(warning.getWarningId(), alarmIds);
|
|
|
}
|
|
}
|
|
|
- if (files != null && !files.isEmpty()) {
|
|
|
|
|
- saveAttachments(warning.getWarningId(), null, "REPORT", files);
|
|
|
|
|
|
|
+ if (attachmentPaths != null && !attachmentPaths.isEmpty()) {
|
|
|
|
|
+ saveAttachments(warning.getWarningId(), null, "REPORT", attachmentPaths);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /** 人工新增和编辑必须关联台账设备,设备名称以台账为准。 */
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 人工新增和编辑必须关联台账设备,设备名称以台账为准。
|
|
|
|
|
+ */
|
|
|
private void bindRequiredDevice(EarlyWarning warning) {
|
|
private void bindRequiredDevice(EarlyWarning warning) {
|
|
|
if (isBlank(warning.getDeviceCode())) {
|
|
if (isBlank(warning.getDeviceCode())) {
|
|
|
throw new ServiceException("请选择关联设备");
|
|
throw new ServiceException("请选择关联设备");
|
|
|
}
|
|
}
|
|
|
String code = warning.getDeviceCode().trim();
|
|
String code = warning.getDeviceCode().trim();
|
|
|
- EquipmentBase equipment = equipmentBaseMapper.selectOne(new LambdaQueryWrapper<EquipmentBase>()
|
|
|
|
|
- .eq(EquipmentBase::getEquipmentCode, code).last("LIMIT 1"));
|
|
|
|
|
|
|
+ EquipmentBase equipment = equipmentBaseMapper.selectOne(new LambdaQueryWrapper<EquipmentBase>().eq(EquipmentBase::getEquipmentCode, code).last("LIMIT 1"));
|
|
|
if (equipment == null) {
|
|
if (equipment == null) {
|
|
|
throw new ServiceException("关联设备不存在,请重新选择");
|
|
throw new ServiceException("关联设备不存在,请重新选择");
|
|
|
}
|
|
}
|
|
@@ -396,15 +392,22 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
warningAccess.requireVisible(warningId);
|
|
warningAccess.requireVisible(warningId);
|
|
|
WarningWorkflow.requireState(earlyWarningMapper.selectForUpdate(warningId), "删除", WarningWorkflow.DRAFT);
|
|
WarningWorkflow.requireState(earlyWarningMapper.selectForUpdate(warningId), "删除", WarningWorkflow.DRAFT);
|
|
|
// 先查询附件列表,删除物理文件
|
|
// 先查询附件列表,删除物理文件
|
|
|
- List<WarningAttachment> attachments = warningAttachmentMapper.selectList(
|
|
|
|
|
- new LambdaQueryWrapper<WarningAttachment>()
|
|
|
|
|
- .eq(WarningAttachment::getWarningId, warningId)
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ List<WarningAttachment> attachments = warningAttachmentMapper.selectList(new LambdaQueryWrapper<WarningAttachment>().eq(WarningAttachment::getWarningId, warningId));
|
|
|
for (WarningAttachment attachment : attachments) {
|
|
for (WarningAttachment attachment : attachments) {
|
|
|
String attachmentUrl = attachment.getAttachmentUrl();
|
|
String attachmentUrl = attachment.getAttachmentUrl();
|
|
|
if (attachmentUrl != null && !attachmentUrl.isEmpty()) {
|
|
if (attachmentUrl != null && !attachmentUrl.isEmpty()) {
|
|
|
- // 删除minio文件
|
|
|
|
|
- minioFileStorageService.deleteFile(attachmentUrl);
|
|
|
|
|
|
|
+ String objectName = attachmentUrl.trim();
|
|
|
|
|
+ while (objectName.startsWith("/")) {
|
|
|
|
|
+ objectName = objectName.substring(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ minioClient.removeObject(RemoveObjectArgs.builder()
|
|
|
|
|
+ .bucket(minioBucket)
|
|
|
|
|
+ .object(objectName)
|
|
|
|
|
+ .build());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("删除预警附件失败: {}", attachmentUrl, e);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -468,9 +471,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
String assignee = isBlank(requestedHandler) ? warning.getHandler() : requestedHandler.trim();
|
|
String assignee = isBlank(requestedHandler) ? warning.getHandler() : requestedHandler.trim();
|
|
|
// 发布不能再自动指派当前登录用户,处置人必须由发布人明确选择或提前保存。
|
|
// 发布不能再自动指派当前登录用户,处置人必须由发布人明确选择或提前保存。
|
|
|
participants.requireCandidate(warningId, "handler", assignee);
|
|
participants.requireCandidate(warningId, "handler", assignee);
|
|
|
- String reviewer = isBlank(requestedReviewer)
|
|
|
|
|
- ? (isBlank(warning.getReviewer()) ? currentUser() : warning.getReviewer().trim())
|
|
|
|
|
- : requestedReviewer.trim();
|
|
|
|
|
|
|
+ String reviewer = isBlank(requestedReviewer) ? (isBlank(warning.getReviewer()) ? currentUser() : warning.getReviewer().trim()) : requestedReviewer.trim();
|
|
|
participants.requireCandidate(warningId, "reviewer", reviewer);
|
|
participants.requireCandidate(warningId, "reviewer", reviewer);
|
|
|
warning.setReviewer(reviewer);
|
|
warning.setReviewer(reviewer);
|
|
|
|
|
|
|
@@ -486,8 +487,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
boolean result = updateById(warning);
|
|
boolean result = updateById(warning);
|
|
|
|
|
|
|
|
if (result) {
|
|
if (result) {
|
|
|
- addDisposalRecord(warningId, "RELEASE", null, null, currentUser(),
|
|
|
|
|
- "发布预警;处置人:" + assignee + ";核查人:" + reviewer);
|
|
|
|
|
|
|
+ addDisposalRecord(warningId, "RELEASE", null, null, currentUser(), "发布预警;处置人:" + assignee + ";核查人:" + reviewer);
|
|
|
createTodo(warningId, assignee, "接收并处置预警", "TODO", "HANDLE");
|
|
createTodo(warningId, assignee, "接收并处置预警", "TODO", "HANDLE");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -541,13 +541,13 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public boolean submitWarningProcess(String warningId, String processContent, List<MultipartFile> files) {
|
|
|
|
|
- return submitWarningProcess(warningId, processContent, files, Collections.emptyList());
|
|
|
|
|
|
|
+ public boolean submitWarningProcess(String warningId, String processContent, List<String> attachmentPaths) {
|
|
|
|
|
+ return submitWarningProcess(warningId, processContent, attachmentPaths, Collections.emptyList());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public boolean submitWarningProcess(String warningId, String processContent, List<MultipartFile> files, List<String> reasonIds) {
|
|
|
|
|
|
|
+ public boolean submitWarningProcess(String warningId, String processContent, List<String> attachmentPaths, List<String> reasonIds) {
|
|
|
EarlyWarning warning = earlyWarningMapper.selectForUpdate(warningId);
|
|
EarlyWarning warning = earlyWarningMapper.selectForUpdate(warningId);
|
|
|
WarningWorkflow.requireState(warning, "提交处置结果", WarningWorkflow.PROCESSING);
|
|
WarningWorkflow.requireState(warning, "提交处置结果", WarningWorkflow.PROCESSING);
|
|
|
requireHandler(warning);
|
|
requireHandler(warning);
|
|
@@ -569,9 +569,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
List<Map<String, Object>> reasonSnapshot = new ArrayList<>();
|
|
List<Map<String, Object>> reasonSnapshot = new ArrayList<>();
|
|
|
for (String reasonId : selectedIds) {
|
|
for (String reasonId : selectedIds) {
|
|
|
WarningReason reason = warningReasonMapper.selectById(reasonId);
|
|
WarningReason reason = warningReasonMapper.selectById(reasonId);
|
|
|
- if (reason == null || !"0".equals(reason.getStatus())
|
|
|
|
|
- || !Objects.equals(reason.getWarningType(), warning.getWarningType())
|
|
|
|
|
- || !Objects.equals(reason.getWarningLevel(), warning.getWarningLevel())) {
|
|
|
|
|
|
|
+ if (reason == null || !"0".equals(reason.getStatus()) || !Objects.equals(reason.getWarningType(), warning.getWarningType()) || !Objects.equals(reason.getWarningLevel(), warning.getWarningLevel())) {
|
|
|
throw new ServiceException("所选原因已停用或不属于当前预警类型和级别,请重新选择");
|
|
throw new ServiceException("所选原因已停用或不属于当前预警类型和级别,请重新选择");
|
|
|
}
|
|
}
|
|
|
Map<String, Object> entry = new LinkedHashMap<>();
|
|
Map<String, Object> entry = new LinkedHashMap<>();
|
|
@@ -587,8 +585,8 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
disposal.setReasonSnapshot(com.alibaba.fastjson2.JSON.toJSONString(reasonSnapshot));
|
|
disposal.setReasonSnapshot(com.alibaba.fastjson2.JSON.toJSONString(reasonSnapshot));
|
|
|
disposal.setCreateTime(now);
|
|
disposal.setCreateTime(now);
|
|
|
warningDisposalMapper.insert(disposal);
|
|
warningDisposalMapper.insert(disposal);
|
|
|
- if (files != null && !files.isEmpty()) {
|
|
|
|
|
- saveAttachments(warningId, disposal.getDisposalId(), "PROCESS", files);
|
|
|
|
|
|
|
+ if (attachmentPaths != null && !attachmentPaths.isEmpty()) {
|
|
|
|
|
+ saveAttachments(warningId, disposal.getDisposalId(), "PROCESS", attachmentPaths);
|
|
|
}
|
|
}
|
|
|
completeTodo(warningId);
|
|
completeTodo(warningId);
|
|
|
createTodo(warningId, reviewerOf(warning), "核查处置结果", "TODO", "REVIEW");
|
|
createTodo(warningId, reviewerOf(warning), "核查处置结果", "TODO", "REVIEW");
|
|
@@ -597,40 +595,8 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public boolean submitMobileWarningProcess(String warningId, String processContent, List<String> attachmentTokens,
|
|
|
|
|
- List<String> reasonIds) {
|
|
|
|
|
- List<WarningProcessAttachmentService.UploadInfo> uploads =
|
|
|
|
|
- processAttachmentService.resolve(warningId, attachmentTokens);
|
|
|
|
|
- boolean success = submitWarningProcess(warningId, processContent, Collections.emptyList(), reasonIds);
|
|
|
|
|
- if (!success) return false;
|
|
|
|
|
-
|
|
|
|
|
- WarningDisposal disposal = warningDisposalMapper.selectOne(new LambdaQueryWrapper<WarningDisposal>()
|
|
|
|
|
- .eq(WarningDisposal::getWarningId, warningId)
|
|
|
|
|
- .eq(WarningDisposal::getDisposalType, "HANDLE")
|
|
|
|
|
- .orderByDesc(WarningDisposal::getCreateTime)
|
|
|
|
|
- .last("LIMIT 1"));
|
|
|
|
|
- for (WarningProcessAttachmentService.UploadInfo upload : uploads) {
|
|
|
|
|
- WarningAttachment attachment = new WarningAttachment();
|
|
|
|
|
- attachment.setWarningId(warningId);
|
|
|
|
|
- attachment.setDisposalId(disposal == null ? null : disposal.getDisposalId());
|
|
|
|
|
- attachment.setAttachmentStage("PROCESS");
|
|
|
|
|
- attachment.setAttachmentName("[处理反馈] " + (isBlank(upload.getName()) ? "现场图片" : upload.getName()));
|
|
|
|
|
- attachment.setAttachmentUrl(upload.getPath());
|
|
|
|
|
- attachment.setAttachmentType(truncateAttachmentType(upload.getContentType()));
|
|
|
|
|
- attachment.setAttachmentSize(upload.getSize());
|
|
|
|
|
- attachment.setCreateBy(currentUser());
|
|
|
|
|
- attachment.setCreateTime(LocalDateTime.now());
|
|
|
|
|
- warningAttachmentMapper.insert(attachment);
|
|
|
|
|
- }
|
|
|
|
|
- if (!uploads.isEmpty() && TransactionSynchronizationManager.isSynchronizationActive()) {
|
|
|
|
|
- List<String> tokens = new ArrayList<>(attachmentTokens);
|
|
|
|
|
- TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
|
|
|
|
- @Override public void afterCommit() {
|
|
|
|
|
- processAttachmentService.removeTokens(warningId, tokens);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- return true;
|
|
|
|
|
|
|
+ public boolean submitMobileWarningProcess(String warningId, String processContent, List<String> attachments, List<String> reasonIds) {
|
|
|
|
|
+ return submitWarningProcess(warningId, processContent, attachments, reasonIds);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -729,14 +695,13 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public boolean uploadReport(String warningId, List<MultipartFile> files) {
|
|
|
|
|
|
|
+ public boolean uploadReport(String warningId, List<String> attachmentPaths) {
|
|
|
warningAccess.requireVisible(warningId);
|
|
warningAccess.requireVisible(warningId);
|
|
|
EarlyWarning warning = earlyWarningMapper.selectForUpdate(warningId);
|
|
EarlyWarning warning = earlyWarningMapper.selectForUpdate(warningId);
|
|
|
- WarningWorkflow.requireState(warning, "上传报告", WarningWorkflow.DRAFT, WarningWorkflow.PENDING,
|
|
|
|
|
- WarningWorkflow.RECEIVED, WarningWorkflow.PROCESSING, WarningWorkflow.HANDLED);
|
|
|
|
|
- if (files == null || files.isEmpty()) throw new ServiceException("请选择预警报告文件");
|
|
|
|
|
- saveAttachments(warningId, null, "REPORT", files);
|
|
|
|
|
- addDisposalRecord(warningId, "REPORT", null, null, currentUser(), "上传预警报告,共" + files.size() + "个附件");
|
|
|
|
|
|
|
+ WarningWorkflow.requireState(warning, "上传报告", WarningWorkflow.DRAFT, WarningWorkflow.PENDING, WarningWorkflow.RECEIVED, WarningWorkflow.PROCESSING, WarningWorkflow.HANDLED);
|
|
|
|
|
+ if (attachmentPaths == null || attachmentPaths.isEmpty()) throw new ServiceException("请选择预警报告文件");
|
|
|
|
|
+ saveAttachments(warningId, null, "REPORT", attachmentPaths);
|
|
|
|
|
+ addDisposalRecord(warningId, "REPORT", null, null, currentUser(), "上传预警报告,共" + attachmentPaths.size() + "个附件");
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -745,12 +710,9 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
public boolean upgradeWarning(String warningId, String newLevel, String disposalContent) {
|
|
public boolean upgradeWarning(String warningId, String newLevel, String disposalContent) {
|
|
|
warningAccess.requireVisible(warningId);
|
|
warningAccess.requireVisible(warningId);
|
|
|
EarlyWarning warning = earlyWarningMapper.selectForUpdate(warningId);
|
|
EarlyWarning warning = earlyWarningMapper.selectForUpdate(warningId);
|
|
|
- WarningWorkflow.requireState(warning, "升级", WarningWorkflow.PENDING, WarningWorkflow.RECEIVED,
|
|
|
|
|
- WarningWorkflow.PROCESSING, WarningWorkflow.HANDLED);
|
|
|
|
|
|
|
+ WarningWorkflow.requireState(warning, "升级", WarningWorkflow.PENDING, WarningWorkflow.RECEIVED, WarningWorkflow.PROCESSING, WarningWorkflow.HANDLED);
|
|
|
if (isBlank(disposalContent)) throw new ServiceException("请填写会商研判意见和升级依据");
|
|
if (isBlank(disposalContent)) throw new ServiceException("请填写会商研判意见和升级依据");
|
|
|
- if (newLevel == null || !newLevel.matches("[1-4]")
|
|
|
|
|
- || warning.getWarningLevel() == null || !warning.getWarningLevel().matches("[1-4]")
|
|
|
|
|
- || Integer.parseInt(newLevel) >= Integer.parseInt(warning.getWarningLevel())) {
|
|
|
|
|
|
|
+ if (newLevel == null || !newLevel.matches("[1-4]") || warning.getWarningLevel() == null || !warning.getWarningLevel().matches("[1-4]") || Integer.parseInt(newLevel) >= Integer.parseInt(warning.getWarningLevel())) {
|
|
|
throw new ServiceException("只能升级至更严重的级别,一级为最高级");
|
|
throw new ServiceException("只能升级至更严重的级别,一级为最高级");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -795,19 +757,19 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public WarningSupervision supervisionWarning(String warningId, String supervisionUser, String supervisionContent, String notificationType, String notificationContent, MultipartFile attachment) {
|
|
|
|
|
|
|
+ public WarningSupervision supervisionWarning(String warningId, String supervisionUser, String supervisionContent, String notificationType, String notificationContent, String attachment) {
|
|
|
warningAccess.requireVisible(warningId);
|
|
warningAccess.requireVisible(warningId);
|
|
|
EarlyWarning warning = earlyWarningMapper.selectForUpdate(warningId);
|
|
EarlyWarning warning = earlyWarningMapper.selectForUpdate(warningId);
|
|
|
- WarningWorkflow.requireState(warning, "督办",
|
|
|
|
|
- WarningWorkflow.PENDING, WarningWorkflow.RECEIVED, WarningWorkflow.PROCESSING, WarningWorkflow.HANDLED);
|
|
|
|
|
- if (isBlank(supervisionUser) || isBlank(supervisionContent)) throw new ServiceException("请填写督办人员和督办意见");
|
|
|
|
|
|
|
+ WarningWorkflow.requireState(warning, "督办", WarningWorkflow.PENDING, WarningWorkflow.RECEIVED, WarningWorkflow.PROCESSING, WarningWorkflow.HANDLED);
|
|
|
|
|
+ if (isBlank(supervisionUser) || isBlank(supervisionContent))
|
|
|
|
|
+ throw new ServiceException("请填写督办人员和督办意见");
|
|
|
if (!"短信".equals(notificationType) && !"系统通知".equals(notificationType)) {
|
|
if (!"短信".equals(notificationType) && !"系统通知".equals(notificationType)) {
|
|
|
throw new ServiceException("督办通知方式仅支持短信或系统通知");
|
|
throw new ServiceException("督办通知方式仅支持短信或系统通知");
|
|
|
}
|
|
}
|
|
|
SysUser recipient = requireActiveUser(supervisionUser, "督办人员");
|
|
SysUser recipient = requireActiveUser(supervisionUser, "督办人员");
|
|
|
String message = isBlank(notificationContent) ? supervisionContent.trim() : notificationContent.trim();
|
|
String message = isBlank(notificationContent) ? supervisionContent.trim() : notificationContent.trim();
|
|
|
if (message.length() > 180) throw new ServiceException("通知内容不能超过180字");
|
|
if (message.length() > 180) throw new ServiceException("通知内容不能超过180字");
|
|
|
- if (attachment != null) validateAttachment(attachment);
|
|
|
|
|
|
|
+ if (attachment != null) validateAttachmentPath(attachment);
|
|
|
if ("短信".equals(notificationType)) {
|
|
if ("短信".equals(notificationType)) {
|
|
|
if (isBlank(recipient.getPhonenumber())) throw new ServiceException("督办人员未配置手机号");
|
|
if (isBlank(recipient.getPhonenumber())) throw new ServiceException("督办人员未配置手机号");
|
|
|
if (smsTemplateProvider.getIfAvailable() == null || isBlank(smsProperties.getSupervisionTemplateCode())) {
|
|
if (smsTemplateProvider.getIfAvailable() == null || isBlank(smsProperties.getSupervisionTemplateCode())) {
|
|
@@ -843,9 +805,11 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
createTodo(warningId, recipient.getUserName(), message, "NOTICE", "NOTICE");
|
|
createTodo(warningId, recipient.getUserName(), message, "NOTICE", "NOTICE");
|
|
|
} else {
|
|
} else {
|
|
|
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
|
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
|
|
- @Override public void afterCommit() {
|
|
|
|
|
- try { supervisionNotifier.send(supervision, recipient.getPhonenumber(), warning.getWarningNo()); }
|
|
|
|
|
- catch (Exception ignored) {
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void afterCommit() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ supervisionNotifier.send(supervision, recipient.getPhonenumber(), warning.getWarningNo());
|
|
|
|
|
+ } catch (Exception ignored) {
|
|
|
supervision.setNotificationStatus("FAILED");
|
|
supervision.setNotificationStatus("FAILED");
|
|
|
supervision.setNotificationError("短信发送结果未能确认,请联系管理员核查,勿重复提交");
|
|
supervision.setNotificationError("短信发送结果未能确认,请联系管理员核查,勿重复提交");
|
|
|
log.warn("督办短信发送结果保存失败,supervisionId={}", supervision.getSupervisionId());
|
|
log.warn("督办短信发送结果保存失败,supervisionId={}", supervision.getSupervisionId());
|
|
@@ -859,8 +823,8 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
@Override
|
|
@Override
|
|
|
public boolean readNotification(String todoId) {
|
|
public boolean readNotification(String todoId) {
|
|
|
WarningTodo todo = warningTodoMapper.selectById(todoId);
|
|
WarningTodo todo = warningTodoMapper.selectById(todoId);
|
|
|
- if (todo == null || !"NOTICE".equals(todo.getTodoType())
|
|
|
|
|
- || !Objects.equals(String.valueOf(SecurityUtils.getUserId()), todo.getUserId())) return false;
|
|
|
|
|
|
|
+ if (todo == null || !"NOTICE".equals(todo.getTodoType()) || !Objects.equals(String.valueOf(SecurityUtils.getUserId()), todo.getUserId()))
|
|
|
|
|
+ return false;
|
|
|
todo.setReadStatus("READ");
|
|
todo.setReadStatus("READ");
|
|
|
return warningTodoMapper.updateById(todo) > 0;
|
|
return warningTodoMapper.updateById(todo) > 0;
|
|
|
}
|
|
}
|
|
@@ -869,8 +833,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public boolean addLeaderInstruction(String warningId, String leaderName, String instructionContent, String smsReceivers) {
|
|
public boolean addLeaderInstruction(String warningId, String leaderName, String instructionContent, String smsReceivers) {
|
|
|
warningAccess.requireVisible(warningId);
|
|
warningAccess.requireVisible(warningId);
|
|
|
- WarningWorkflow.requireState(earlyWarningMapper.selectForUpdate(warningId), "添加领导批示",
|
|
|
|
|
- WarningWorkflow.PENDING, WarningWorkflow.RECEIVED, WarningWorkflow.PROCESSING, WarningWorkflow.HANDLED);
|
|
|
|
|
|
|
+ WarningWorkflow.requireState(earlyWarningMapper.selectForUpdate(warningId), "添加领导批示", WarningWorkflow.PENDING, WarningWorkflow.RECEIVED, WarningWorkflow.PROCESSING, WarningWorkflow.HANDLED);
|
|
|
if (isBlank(leaderName) || isBlank(instructionContent)) throw new ServiceException("请填写批示领导和批示内容");
|
|
if (isBlank(leaderName) || isBlank(instructionContent)) throw new ServiceException("请填写批示领导和批示内容");
|
|
|
WarningDisposal disposal = new WarningDisposal();
|
|
WarningDisposal disposal = new WarningDisposal();
|
|
|
disposal.setWarningId(warningId);
|
|
disposal.setWarningId(warningId);
|
|
@@ -886,8 +849,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public boolean linkAlarms(String warningId, List<String> alarmIds) {
|
|
public boolean linkAlarms(String warningId, List<String> alarmIds) {
|
|
|
warningAccess.requireVisible(warningId);
|
|
warningAccess.requireVisible(warningId);
|
|
|
- WarningWorkflow.requireState(earlyWarningMapper.selectForUpdate(warningId), "关联报警",
|
|
|
|
|
- WarningWorkflow.DRAFT, WarningWorkflow.PENDING, WarningWorkflow.RECEIVED, WarningWorkflow.PROCESSING, WarningWorkflow.HANDLED);
|
|
|
|
|
|
|
+ WarningWorkflow.requireState(earlyWarningMapper.selectForUpdate(warningId), "关联报警", WarningWorkflow.DRAFT, WarningWorkflow.PENDING, WarningWorkflow.RECEIVED, WarningWorkflow.PROCESSING, WarningWorkflow.HANDLED);
|
|
|
LambdaQueryWrapper<AlarmWarningRel> wrapper = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<AlarmWarningRel> wrapper = new LambdaQueryWrapper<>();
|
|
|
wrapper.eq(AlarmWarningRel::getWarningId, warningId);
|
|
wrapper.eq(AlarmWarningRel::getWarningId, warningId);
|
|
|
alarmWarningRelMapper.delete(wrapper);
|
|
alarmWarningRelMapper.delete(wrapper);
|
|
@@ -1030,11 +992,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private List<Map<String, Object>> getAttachmentList(String warningId) {
|
|
private List<Map<String, Object>> getAttachmentList(String warningId) {
|
|
|
- List<WarningAttachment> list = warningAttachmentMapper.selectList(
|
|
|
|
|
- new LambdaQueryWrapper<WarningAttachment>()
|
|
|
|
|
- .eq(WarningAttachment::getWarningId, warningId)
|
|
|
|
|
- .orderByDesc(WarningAttachment::getCreateTime)
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ List<WarningAttachment> list = warningAttachmentMapper.selectList(new LambdaQueryWrapper<WarningAttachment>().eq(WarningAttachment::getWarningId, warningId).orderByDesc(WarningAttachment::getCreateTime));
|
|
|
|
|
|
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
|
for (WarningAttachment attachment : list) {
|
|
for (WarningAttachment attachment : list) {
|
|
@@ -1048,8 +1006,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
map.put("createBy", attachment.getCreateBy());
|
|
map.put("createBy", attachment.getCreateBy());
|
|
|
map.put("disposalId", attachment.getDisposalId());
|
|
map.put("disposalId", attachment.getDisposalId());
|
|
|
String attachmentName = attachment.getAttachmentName();
|
|
String attachmentName = attachment.getAttachmentName();
|
|
|
- map.put("attachmentStage", isBlank(attachment.getAttachmentStage())
|
|
|
|
|
- ? (attachmentName != null && attachmentName.startsWith("[处理反馈]") ? "PROCESS" : "REPORT") : attachment.getAttachmentStage());
|
|
|
|
|
|
|
+ map.put("attachmentStage", isBlank(attachment.getAttachmentStage()) ? (attachmentName != null && attachmentName.startsWith("[处理反馈]") ? "PROCESS" : "REPORT") : attachment.getAttachmentStage());
|
|
|
result.add(map);
|
|
result.add(map);
|
|
|
}
|
|
}
|
|
|
return result;
|
|
return result;
|
|
@@ -1088,8 +1045,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
|
|
|
|
|
private void completeTodo(String warningId) {
|
|
private void completeTodo(String warningId) {
|
|
|
LambdaQueryWrapper<WarningTodo> wrapper = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<WarningTodo> wrapper = new LambdaQueryWrapper<>();
|
|
|
- wrapper.eq(WarningTodo::getWarningId, warningId)
|
|
|
|
|
- .eq(WarningTodo::getTodoType, "TODO");
|
|
|
|
|
|
|
+ wrapper.eq(WarningTodo::getWarningId, warningId).eq(WarningTodo::getTodoType, "TODO");
|
|
|
List<WarningTodo> todos = warningTodoMapper.selectList(wrapper);
|
|
List<WarningTodo> todos = warningTodoMapper.selectList(wrapper);
|
|
|
|
|
|
|
|
for (WarningTodo todo : todos) {
|
|
for (WarningTodo todo : todos) {
|
|
@@ -1110,11 +1066,11 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public IPage<WarningArchive> getArchiveList(Page<WarningArchive> page, String warningNo, String warningType, String warningLevel, LocalDateTime startTime, LocalDateTime endTime) {
|
|
public IPage<WarningArchive> getArchiveList(Page<WarningArchive> page, String warningNo, String warningType, String warningLevel, LocalDateTime startTime, LocalDateTime endTime) {
|
|
|
- return earlyWarningMapper.selectVisibleArchives(page, warningNo, warningType, warningLevel,
|
|
|
|
|
- startTime, endTime, warningAccess.current());
|
|
|
|
|
|
|
+ return earlyWarningMapper.selectVisibleArchives(page, warningNo, warningType, warningLevel, startTime, endTime, warningAccess.current());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static final Map<String, String> DISPOSAL_TYPE_MAP = new HashMap<>();
|
|
private static final Map<String, String> DISPOSAL_TYPE_MAP = new HashMap<>();
|
|
|
|
|
+
|
|
|
static {
|
|
static {
|
|
|
DISPOSAL_TYPE_MAP.put("RELEASE", "发布预警");
|
|
DISPOSAL_TYPE_MAP.put("RELEASE", "发布预警");
|
|
|
DISPOSAL_TYPE_MAP.put("RECEIVE", "接收预警");
|
|
DISPOSAL_TYPE_MAP.put("RECEIVE", "接收预警");
|
|
@@ -1179,8 +1135,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
taskNode.put("y", 150);
|
|
taskNode.put("y", 150);
|
|
|
taskNode.put("status", "completed");
|
|
taskNode.put("status", "completed");
|
|
|
taskNode.put("disposalUser", disposal.getDisposalUser());
|
|
taskNode.put("disposalUser", disposal.getDisposalUser());
|
|
|
- taskNode.put("disposalTime", disposal.getCreateTime() != null ?
|
|
|
|
|
- disposal.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
|
|
|
|
|
|
|
+ taskNode.put("disposalTime", disposal.getCreateTime() != null ? disposal.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
|
|
|
taskNode.put("disposalId", disposal.getDisposalId());
|
|
taskNode.put("disposalId", disposal.getDisposalId());
|
|
|
nodes.add(taskNode);
|
|
nodes.add(taskNode);
|
|
|
|
|
|
|
@@ -1253,10 +1208,8 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
result.put("supervisionUser", disposal.getSupervisionUser());
|
|
result.put("supervisionUser", disposal.getSupervisionUser());
|
|
|
result.put("supervisionContent", disposal.getSupervisionContent());
|
|
result.put("supervisionContent", disposal.getSupervisionContent());
|
|
|
result.put("notificationType", disposal.getNotificationType());
|
|
result.put("notificationType", disposal.getNotificationType());
|
|
|
- result.put("createTime", disposal.getCreateTime() != null ?
|
|
|
|
|
- disposal.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
|
|
|
|
|
- result.put("attachmentList", warningAttachmentMapper.selectList(
|
|
|
|
|
- new LambdaQueryWrapper<WarningAttachment>().eq(WarningAttachment::getDisposalId, disposalId)));
|
|
|
|
|
|
|
+ result.put("createTime", disposal.getCreateTime() != null ? disposal.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
|
|
|
|
|
+ result.put("attachmentList", warningAttachmentMapper.selectList(new LambdaQueryWrapper<WarningAttachment>().eq(WarningAttachment::getDisposalId, disposalId)));
|
|
|
|
|
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
@@ -1289,10 +1242,8 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
result.put("handlerCount", handlers.size());
|
|
result.put("handlerCount", handlers.size());
|
|
|
|
|
|
|
|
if (!disposals.isEmpty()) {
|
|
if (!disposals.isEmpty()) {
|
|
|
- result.put("firstDisposalTime", disposals.get(0).getCreateTime() != null ?
|
|
|
|
|
- disposals.get(0).getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
|
|
|
|
|
- result.put("lastDisposalTime", disposals.get(disposals.size() - 1).getCreateTime() != null ?
|
|
|
|
|
- disposals.get(disposals.size() - 1).getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
|
|
|
|
|
|
|
+ result.put("firstDisposalTime", disposals.get(0).getCreateTime() != null ? disposals.get(0).getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
|
|
|
|
|
+ result.put("lastDisposalTime", disposals.get(disposals.size() - 1).getCreateTime() != null ? disposals.get(disposals.size() - 1).getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
return result;
|
|
@@ -1313,37 +1264,25 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
return contentType.substring(0, ATTACHMENT_TYPE_MAX_LEN);
|
|
return contentType.substring(0, ATTACHMENT_TYPE_MAX_LEN);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private static final Set<String> ALLOWED_ATTACHMENT_EXTENSIONS = new HashSet<>(Arrays.asList(
|
|
|
|
|
- "jpg", "jpeg", "png", "gif", "webp", "pdf", "xls", "xlsx", "doc", "docx"
|
|
|
|
|
- ));
|
|
|
|
|
|
|
+ private static final Set<String> ALLOWED_ATTACHMENT_EXTENSIONS = new HashSet<>(Arrays.asList("jpg", "jpeg", "png", "gif", "webp", "pdf", "xls", "xlsx", "doc", "docx"));
|
|
|
|
|
|
|
|
- private void validateAttachment(MultipartFile file) {
|
|
|
|
|
- if (file == null || file.isEmpty()) {
|
|
|
|
|
- throw new IllegalArgumentException("上传文件不能为空");
|
|
|
|
|
- }
|
|
|
|
|
- String originalName = file.getOriginalFilename();
|
|
|
|
|
- String extension = "";
|
|
|
|
|
- if (originalName != null && originalName.lastIndexOf('.') >= 0) {
|
|
|
|
|
- extension = originalName.substring(originalName.lastIndexOf('.') + 1).toLowerCase(Locale.ROOT);
|
|
|
|
|
- }
|
|
|
|
|
- if (!ALLOWED_ATTACHMENT_EXTENSIONS.contains(extension)) {
|
|
|
|
|
- throw new IllegalArgumentException("仅支持图片、PDF、Excel、Word文件");
|
|
|
|
|
- }
|
|
|
|
|
- String contentType = file.getContentType();
|
|
|
|
|
- if (contentType != null && !contentType.trim().isEmpty()
|
|
|
|
|
- && !"application/octet-stream".equalsIgnoreCase(contentType)
|
|
|
|
|
- && !isCompatibleAttachmentType(extension, contentType)) {
|
|
|
|
|
- throw new IllegalArgumentException("附件类型与文件扩展名不匹配");
|
|
|
|
|
|
|
+ private String validateAttachmentPath(String path) {
|
|
|
|
|
+ if (isBlank(path) || path.contains("://") || !path.startsWith("/")) {
|
|
|
|
|
+ throw new ServiceException("附件路径无效");
|
|
|
}
|
|
}
|
|
|
- if (file.getSize() > 20 * 1024 * 1024L) {
|
|
|
|
|
- throw new IllegalArgumentException("单个附件不能超过20MB");
|
|
|
|
|
|
|
+ String normalized = path.trim().replaceFirst("^/+", "");
|
|
|
|
|
+ String lower = normalized.toLowerCase(Locale.ROOT);
|
|
|
|
|
+ boolean allowed = false;
|
|
|
|
|
+ for (String ext : ALLOWED_ATTACHMENT_EXTENSIONS) {
|
|
|
|
|
+ if (lower.endsWith("." + ext)) { allowed = true; break; }
|
|
|
}
|
|
}
|
|
|
|
|
+ if (!allowed) throw new ServiceException("仅支持图片、PDF、Excel、Word文件");
|
|
|
|
|
+ return normalized;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private boolean isCompatibleAttachmentType(String extension, String contentType) {
|
|
private boolean isCompatibleAttachmentType(String extension, String contentType) {
|
|
|
String type = contentType.toLowerCase(Locale.ROOT);
|
|
String type = contentType.toLowerCase(Locale.ROOT);
|
|
|
- if ("jpg".equals(extension) || "jpeg".equals(extension) || "png".equals(extension)
|
|
|
|
|
- || "gif".equals(extension) || "webp".equals(extension)) {
|
|
|
|
|
|
|
+ if ("jpg".equals(extension) || "jpeg".equals(extension) || "png".equals(extension) || "gif".equals(extension) || "webp".equals(extension)) {
|
|
|
return type.startsWith("image/");
|
|
return type.startsWith("image/");
|
|
|
}
|
|
}
|
|
|
if ("pdf".equals(extension)) {
|
|
if ("pdf".equals(extension)) {
|
|
@@ -1353,13 +1292,11 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
return "application/vnd.ms-excel".equals(type) || "application/octet-stream".equals(type);
|
|
return "application/vnd.ms-excel".equals(type) || "application/octet-stream".equals(type);
|
|
|
}
|
|
}
|
|
|
if ("xlsx".equals(extension)) {
|
|
if ("xlsx".equals(extension)) {
|
|
|
- return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".equals(type)
|
|
|
|
|
- || "application/zip".equals(type) || "application/octet-stream".equals(type);
|
|
|
|
|
|
|
+ return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".equals(type) || "application/zip".equals(type) || "application/octet-stream".equals(type);
|
|
|
}
|
|
}
|
|
|
if ("doc".equals(extension)) {
|
|
if ("doc".equals(extension)) {
|
|
|
return "application/msword".equals(type) || "application/octet-stream".equals(type);
|
|
return "application/msword".equals(type) || "application/octet-stream".equals(type);
|
|
|
}
|
|
}
|
|
|
- return "application/vnd.openxmlformats-officedocument.wordprocessingml.document".equals(type)
|
|
|
|
|
- || "application/zip".equals(type) || "application/octet-stream".equals(type);
|
|
|
|
|
|
|
+ return "application/vnd.openxmlformats-officedocument.wordprocessingml.document".equals(type) || "application/zip".equals(type) || "application/octet-stream".equals(type);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|