|
@@ -9,6 +9,7 @@ import com.zksy.base.warning.mapper.*;
|
|
|
import com.zksy.base.warning.service.EarlyWarningService;
|
|
import com.zksy.base.warning.service.EarlyWarningService;
|
|
|
import com.zksy.common.core.domain.entity.SysDictData;
|
|
import com.zksy.common.core.domain.entity.SysDictData;
|
|
|
import com.zksy.common.utils.DictUtils;
|
|
import com.zksy.common.utils.DictUtils;
|
|
|
|
|
+import com.zksy.common.utils.SecurityUtils;
|
|
|
import com.zksy.service.MinioFileStorageService;
|
|
import com.zksy.service.MinioFileStorageService;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
@@ -34,6 +35,9 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private WarningTodoMapper warningTodoMapper;
|
|
private WarningTodoMapper warningTodoMapper;
|
|
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private WarningSupervisionMapper warningSupervisionMapper;
|
|
|
|
|
+
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private WarningArchiveMapper warningArchiveMapper;
|
|
private WarningArchiveMapper warningArchiveMapper;
|
|
|
@Autowired
|
|
@Autowired
|
|
@@ -45,8 +49,8 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public IPage<Map<String, Object>> searchWarnings(Page<?> page, String warningName, String warningNo, String warningType, String warningLevel, String status, String location, String publisher, String ownershipUnit, LocalDateTime startTime, LocalDateTime endTime, String excludePublisher) {
|
|
|
|
|
- return earlyWarningMapper.searchWarnings(page, warningName, warningNo, warningType, warningLevel, status, location, publisher, ownershipUnit, startTime, endTime, excludePublisher);
|
|
|
|
|
|
|
+ public IPage<Map<String, Object>> searchWarnings(Page<?> page, String warningName, String warningNo, String warningType, String warningLevel, String status, String location, String publisher, String ownershipUnit, LocalDateTime startTime, LocalDateTime endTime, String excludePublisher, String deviceCode, String deviceName) {
|
|
|
|
|
+ return earlyWarningMapper.searchWarnings(page, warningName, warningNo, warningType, warningLevel, status, location, publisher, ownershipUnit, startTime, endTime, excludePublisher, deviceCode, deviceName);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -77,6 +81,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
result.put("gisLocation", getGisLocation(basicInfo));
|
|
result.put("gisLocation", getGisLocation(basicInfo));
|
|
|
result.put("disposalHistory", getDisposalHistory(warningId));
|
|
result.put("disposalHistory", getDisposalHistory(warningId));
|
|
|
result.put("attachmentList", getAttachmentList(warningId));
|
|
result.put("attachmentList", getAttachmentList(warningId));
|
|
|
|
|
+ result.put("supervisionList", getSupervisionList(warningId));
|
|
|
result.put("alarmList", getLinkedAlarms(warningId));
|
|
result.put("alarmList", getLinkedAlarms(warningId));
|
|
|
result.put("electronicArchive", generateElectronicArchive(basicInfo));
|
|
result.put("electronicArchive", generateElectronicArchive(basicInfo));
|
|
|
|
|
|
|
@@ -123,7 +128,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
archive.setLatitude(warningInfo.get("latitude") != null ? ((Number) warningInfo.get("latitude")).doubleValue() : null);
|
|
archive.setLatitude(warningInfo.get("latitude") != null ? ((Number) warningInfo.get("latitude")).doubleValue() : null);
|
|
|
archive.setOwnershipUnit((String) warningInfo.get("ownership_unit"));
|
|
archive.setOwnershipUnit((String) warningInfo.get("ownership_unit"));
|
|
|
archive.setPublisher((String) warningInfo.get("publisher"));
|
|
archive.setPublisher((String) warningInfo.get("publisher"));
|
|
|
- archive.setPublishTime(warningInfo.get("publish_time") instanceof LocalDateTime ? (LocalDateTime) warningInfo.get("publishTime") : null);
|
|
|
|
|
|
|
+ archive.setPublishTime(warningInfo.get("publish_time") instanceof LocalDateTime ? (LocalDateTime) warningInfo.get("publish_time") : null);
|
|
|
archive.setHandler((String) warningInfo.get("handler"));
|
|
archive.setHandler((String) warningInfo.get("handler"));
|
|
|
archive.setWarningContent((String) warningInfo.get("warning_content"));
|
|
archive.setWarningContent((String) warningInfo.get("warning_content"));
|
|
|
archive.setArchiveContent((String) warningInfo.get("warning_content"));
|
|
archive.setArchiveContent((String) warningInfo.get("warning_content"));
|
|
@@ -156,7 +161,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
linkAlarms(warning.getWarningId(), alarmIds);
|
|
linkAlarms(warning.getWarningId(), alarmIds);
|
|
|
}
|
|
}
|
|
|
if (files != null && !files.isEmpty()) {
|
|
if (files != null && !files.isEmpty()) {
|
|
|
- saveAttachments(warning.getWarningId(), files);
|
|
|
|
|
|
|
+ saveAttachments(warning.getWarningId(), null, "REPORT", files);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
return result;
|
|
return result;
|
|
@@ -166,15 +171,23 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
* 保存附件
|
|
* 保存附件
|
|
|
*/
|
|
*/
|
|
|
private void saveAttachments(String warningId, List<MultipartFile> files) {
|
|
private void saveAttachments(String warningId, List<MultipartFile> files) {
|
|
|
|
|
+ saveAttachments(warningId, null, "REPORT", files);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void saveAttachments(String warningId, String disposalId, String stage, List<MultipartFile> files) {
|
|
|
try {
|
|
try {
|
|
|
for (MultipartFile file : files) {
|
|
for (MultipartFile file : files) {
|
|
|
|
|
+ validateAttachment(file);
|
|
|
String path = minioFileStorageService.uploadFile(file, "warning");
|
|
String path = minioFileStorageService.uploadFile(file, "warning");
|
|
|
// 上传文件
|
|
// 上传文件
|
|
|
- String fileName = path.substring(path.lastIndexOf("/") + 1);
|
|
|
|
|
|
|
+ String fileName = file.getOriginalFilename();
|
|
|
|
|
+ if (fileName == null || fileName.trim().isEmpty()) {
|
|
|
|
|
+ fileName = path.substring(path.lastIndexOf("/") + 1);
|
|
|
|
|
+ }
|
|
|
// 保存附件信息
|
|
// 保存附件信息
|
|
|
WarningAttachment attachment = new WarningAttachment();
|
|
WarningAttachment attachment = new WarningAttachment();
|
|
|
attachment.setWarningId(warningId);
|
|
attachment.setWarningId(warningId);
|
|
|
- attachment.setAttachmentName(fileName);
|
|
|
|
|
|
|
+ attachment.setAttachmentName(("PROCESS".equals(stage) ? "[处理反馈] " : "[预警报告] ") + fileName);
|
|
|
attachment.setAttachmentUrl(path);
|
|
attachment.setAttachmentUrl(path);
|
|
|
// 部分 MIME(如 vnd.openxmlformats-officedocument.*)长度超过 64,写入前按 DB 列宽截断兜底
|
|
// 部分 MIME(如 vnd.openxmlformats-officedocument.*)长度超过 64,写入前按 DB 列宽截断兜底
|
|
|
attachment.setAttachmentType(truncateAttachmentType(file.getContentType()));
|
|
attachment.setAttachmentType(truncateAttachmentType(file.getContentType()));
|
|
@@ -197,7 +210,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
linkAlarms(warning.getWarningId(), alarmIds);
|
|
linkAlarms(warning.getWarningId(), alarmIds);
|
|
|
}
|
|
}
|
|
|
if (files != null && !files.isEmpty()) {
|
|
if (files != null && !files.isEmpty()) {
|
|
|
- saveAttachments(warning.getWarningId(), files);
|
|
|
|
|
|
|
+ saveAttachments(warning.getWarningId(), null, "REPORT", files);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
return result;
|
|
return result;
|
|
@@ -240,6 +253,10 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
archiveWrapper.eq(WarningArchive::getWarningId, warningId);
|
|
archiveWrapper.eq(WarningArchive::getWarningId, warningId);
|
|
|
warningArchiveMapper.delete(archiveWrapper);
|
|
warningArchiveMapper.delete(archiveWrapper);
|
|
|
|
|
|
|
|
|
|
+ LambdaQueryWrapper<WarningSupervision> supervisionWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ supervisionWrapper.eq(WarningSupervision::getWarningId, warningId);
|
|
|
|
|
+ warningSupervisionMapper.delete(supervisionWrapper);
|
|
|
|
|
+
|
|
|
// 删除主表记录
|
|
// 删除主表记录
|
|
|
return removeById(warningId);
|
|
return removeById(warningId);
|
|
|
}
|
|
}
|
|
@@ -266,13 +283,112 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
boolean result = updateById(warning);
|
|
boolean result = updateById(warning);
|
|
|
|
|
|
|
|
if (result) {
|
|
if (result) {
|
|
|
- addDisposalRecord(warningId, "RELEASE", null, null, warning.getHandler(), "系统发布预警信息");
|
|
|
|
|
- createTodo(warningId, warning.getHandler(), "待办预警", "TODO");
|
|
|
|
|
|
|
+ String assignee = isBlank(warning.getHandler()) ? currentUser() : warning.getHandler();
|
|
|
|
|
+ warning.setHandler(assignee);
|
|
|
|
|
+ updateById(warning);
|
|
|
|
|
+ addDisposalRecord(warningId, "RELEASE", null, null, assignee, "系统发布预警信息");
|
|
|
|
|
+ createTodo(warningId, assignee, "待办预警", "TODO");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public boolean confirmWarning(String warningId, String assignedUser, String confirmRemark) {
|
|
|
|
|
+ EarlyWarning warning = getById(warningId);
|
|
|
|
|
+ if (warning == null || "CLOSED".equals(warning.getStatus())) return false;
|
|
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
+ String operator = currentUser();
|
|
|
|
|
+ String assignee = isBlank(assignedUser) ? warning.getHandler() : assignedUser;
|
|
|
|
|
+ if (isBlank(assignee)) assignee = operator;
|
|
|
|
|
+ warning.setStatus("PROCESSING");
|
|
|
|
|
+ warning.setHandler(assignee);
|
|
|
|
|
+ warning.setPublishTime(warning.getPublishTime() == null ? now : warning.getPublishTime());
|
|
|
|
|
+ warning.setUpdateTime(now);
|
|
|
|
|
+ if (!updateById(warning)) return false;
|
|
|
|
|
+ addDisposalRecord(warningId, "CONFIRM", null, null, operator, confirmRemark);
|
|
|
|
|
+ createTodo(warningId, assignee, "预警处理", "TODO", "PROCESS");
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public boolean misreportWarning(String warningId, String reason) {
|
|
|
|
|
+ EarlyWarning warning = getById(warningId);
|
|
|
|
|
+ if (warning == null) return false;
|
|
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
+ String operator = currentUser();
|
|
|
|
|
+ warning.setStatus("CLOSED");
|
|
|
|
|
+ warning.setRemark(reason);
|
|
|
|
|
+ warning.setUpdateTime(now);
|
|
|
|
|
+ if (!updateById(warning)) return false;
|
|
|
|
|
+ addDisposalRecord(warningId, "MISREPORT", null, null, operator, reason);
|
|
|
|
|
+ completeTodo(warningId);
|
|
|
|
|
+ generateArchive(warningId);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public boolean submitWarningProcess(String warningId, String processContent, List<MultipartFile> files) {
|
|
|
|
|
+ EarlyWarning warning = getById(warningId);
|
|
|
|
|
+ if (warning == null || "CLOSED".equals(warning.getStatus())) return false;
|
|
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
+ String operator = currentUser();
|
|
|
|
|
+ warning.setStatus("HANDLED");
|
|
|
|
|
+ warning.setRemark(processContent);
|
|
|
|
|
+ warning.setUpdateTime(now);
|
|
|
|
|
+ if (!updateById(warning)) return false;
|
|
|
|
|
+ WarningDisposal disposal = new WarningDisposal();
|
|
|
|
|
+ disposal.setWarningId(warningId);
|
|
|
|
|
+ disposal.setDisposalType("HANDLE");
|
|
|
|
|
+ disposal.setDisposalUser(operator);
|
|
|
|
|
+ disposal.setDisposalContent(processContent);
|
|
|
|
|
+ disposal.setCreateTime(now);
|
|
|
|
|
+ warningDisposalMapper.insert(disposal);
|
|
|
|
|
+ if (files != null && !files.isEmpty()) {
|
|
|
|
|
+ saveAttachments(warningId, disposal.getDisposalId(), "PROCESS", files);
|
|
|
|
|
+ }
|
|
|
|
|
+ completeTodo(warningId);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public boolean clearWarning(String warningId, String clearRemark) {
|
|
|
|
|
+ EarlyWarning warning = getById(warningId);
|
|
|
|
|
+ if (warning == null || "CLOSED".equals(warning.getStatus())) return false;
|
|
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
+ String operator = currentUser();
|
|
|
|
|
+ warning.setStatus("CLOSED");
|
|
|
|
|
+ warning.setRemark(clearRemark);
|
|
|
|
|
+ warning.setUpdateTime(now);
|
|
|
|
|
+ if (!updateById(warning)) return false;
|
|
|
|
|
+ addDisposalRecord(warningId, "CLEAR", null, null, operator, clearRemark);
|
|
|
|
|
+ completeTodo(warningId);
|
|
|
|
|
+ generateArchive(warningId);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void generateArchive(String warningId) {
|
|
|
|
|
+ Map<String, Object> detail = earlyWarningMapper.selectWarningDetail(warningId);
|
|
|
|
|
+ if (detail != null) generateElectronicArchive(detail);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String currentUser() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ String username = SecurityUtils.getUsername();
|
|
|
|
|
+ return isBlank(username) ? "system" : username;
|
|
|
|
|
+ } catch (Exception ex) {
|
|
|
|
|
+ return "system";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private boolean isBlank(String value) {
|
|
|
|
|
+ return value == null || value.trim().isEmpty();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public boolean upgradeWarning(String warningId, String newLevel, String disposalContent) {
|
|
public boolean upgradeWarning(String warningId, String newLevel, String disposalContent) {
|
|
@@ -336,6 +452,16 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public boolean supervisionWarning(String warningId, String supervisionUser, String supervisionContent, String notificationType, String notificationContent, String attachmentUrl) {
|
|
public boolean supervisionWarning(String warningId, String supervisionUser, String supervisionContent, String notificationType, String notificationContent, String attachmentUrl) {
|
|
|
|
|
+ WarningSupervision supervision = new WarningSupervision();
|
|
|
|
|
+ supervision.setWarningId(warningId);
|
|
|
|
|
+ supervision.setSupervisionUser(supervisionUser);
|
|
|
|
|
+ supervision.setSupervisionContent(supervisionContent);
|
|
|
|
|
+ supervision.setNotificationType(notificationType);
|
|
|
|
|
+ supervision.setNotificationContent(notificationContent);
|
|
|
|
|
+ supervision.setAttachmentUrl(attachmentUrl);
|
|
|
|
|
+ supervision.setCreateBy(currentUser());
|
|
|
|
|
+ supervision.setCreateTime(LocalDateTime.now());
|
|
|
|
|
+ warningSupervisionMapper.insert(supervision);
|
|
|
WarningDisposal disposal = new WarningDisposal();
|
|
WarningDisposal disposal = new WarningDisposal();
|
|
|
disposal.setWarningId(warningId);
|
|
disposal.setWarningId(warningId);
|
|
|
disposal.setDisposalType("SUPERVISION");
|
|
disposal.setDisposalType("SUPERVISION");
|
|
@@ -517,7 +643,7 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
disposal.setDisposalType(disposalType);
|
|
disposal.setDisposalType(disposalType);
|
|
|
disposal.setOldLevel(oldLevel);
|
|
disposal.setOldLevel(oldLevel);
|
|
|
disposal.setNewLevel(newLevel);
|
|
disposal.setNewLevel(newLevel);
|
|
|
- disposal.setDisposalUser(disposalUser);
|
|
|
|
|
|
|
+ disposal.setDisposalUser(isBlank(disposalUser) ? currentUser() : disposalUser);
|
|
|
disposal.setDisposalContent(content);
|
|
disposal.setDisposalContent(content);
|
|
|
disposal.setCreateTime(LocalDateTime.now());
|
|
disposal.setCreateTime(LocalDateTime.now());
|
|
|
warningDisposalMapper.insert(disposal);
|
|
warningDisposalMapper.insert(disposal);
|
|
@@ -539,12 +665,23 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
map.put("attachmentType", attachment.getAttachmentType());
|
|
map.put("attachmentType", attachment.getAttachmentType());
|
|
|
map.put("attachmentSize", attachment.getAttachmentSize());
|
|
map.put("attachmentSize", attachment.getAttachmentSize());
|
|
|
map.put("createTime", attachment.getCreateTime());
|
|
map.put("createTime", attachment.getCreateTime());
|
|
|
|
|
+ String attachmentName = attachment.getAttachmentName();
|
|
|
|
|
+ map.put("attachmentStage", attachmentName != null && attachmentName.startsWith("[处理反馈]") ? "PROCESS" : "REPORT");
|
|
|
result.add(map);
|
|
result.add(map);
|
|
|
}
|
|
}
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void createTodo(String warningId, String userId, String taskName, String todoType) {
|
|
private void createTodo(String warningId, String userId, String taskName, String todoType) {
|
|
|
|
|
+ createTodo(warningId, userId, taskName, todoType, todoType);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public WarningAttachment getAttachment(String attachmentId) {
|
|
|
|
|
+ return warningAttachmentMapper.selectById(attachmentId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void createTodo(String warningId, String userId, String taskName, String todoType, String actionType) {
|
|
|
WarningTodo todo = new WarningTodo();
|
|
WarningTodo todo = new WarningTodo();
|
|
|
todo.setWarningId(warningId);
|
|
todo.setWarningId(warningId);
|
|
|
todo.setUserId(userId);
|
|
todo.setUserId(userId);
|
|
@@ -556,6 +693,11 @@ public class EarlyWarningServiceImpl extends ServiceImpl<EarlyWarningMapper, Ear
|
|
|
warningTodoMapper.insert(todo);
|
|
warningTodoMapper.insert(todo);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<WarningSupervision> getSupervisionList(String warningId) {
|
|
|
|
|
+ return warningSupervisionMapper.selectByWarningId(warningId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
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)
|
|
wrapper.eq(WarningTodo::getWarningId, warningId)
|
|
@@ -787,4 +929,54 @@ 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 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("附件类型与文件扩展名不匹配");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (file.getSize() > 20 * 1024 * 1024L) {
|
|
|
|
|
+ throw new IllegalArgumentException("单个附件不能超过20MB");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private boolean isCompatibleAttachmentType(String extension, String contentType) {
|
|
|
|
|
+ String type = contentType.toLowerCase(Locale.ROOT);
|
|
|
|
|
+ if ("jpg".equals(extension) || "jpeg".equals(extension) || "png".equals(extension)
|
|
|
|
|
+ || "gif".equals(extension) || "webp".equals(extension)) {
|
|
|
|
|
+ return type.startsWith("image/");
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("pdf".equals(extension)) {
|
|
|
|
|
+ return "application/pdf".equals(type);
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("xls".equals(extension)) {
|
|
|
|
|
+ return "application/vnd.ms-excel".equals(type) || "application/octet-stream".equals(type);
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("xlsx".equals(extension)) {
|
|
|
|
|
+ return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".equals(type)
|
|
|
|
|
+ || "application/zip".equals(type) || "application/octet-stream".equals(type);
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("doc".equals(extension)) {
|
|
|
|
|
+ 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);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|