Merge branch 'dev-tw'

This commit is contained in:
tangwei 2026-05-08 14:14:51 +08:00
commit 42df8c9498
44 changed files with 1723 additions and 286 deletions

View File

@ -2,6 +2,7 @@ package com.yfd.platform.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.yfd.platform.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
@ -12,6 +13,7 @@ import java.util.Date;
* 用于处理 @TableField(fill = FieldFill.INSERT/UPDATE) 注解
*/
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
@ -35,7 +37,7 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
// 自动填充更新时间
this.strictInsertFill(metaObject, "updatedBy", String.class, userId);
} catch (Exception e) {
e.printStackTrace();
log.info("message{}",e.getMessage());
}
}
@ -52,7 +54,7 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
// 自动填充更新人
this.strictInsertFill(metaObject, "updatedBy", String.class, userId);
} catch (Exception e) {
e.printStackTrace();
log.info("message{}",e.getMessage());
}
}

View File

@ -5,6 +5,7 @@ import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.data.domain.ApprovalMain;
import com.yfd.platform.data.service.IApprovalMainService;
import com.yfd.platform.data.service.IFishDraftDataService;
import com.yfd.platform.utils.DataSourceRequestUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -26,15 +27,20 @@ public class ApprovalMainController {
@Resource
private IApprovalMainService approvalMainService;
@Resource
private IFishDraftDataService fishDraftDataService;
@GetMapping("/page")
@Operation(summary = "分页查询审批列表")
public ResponseResult queryPageList(
@RequestParam(defaultValue = "1") Integer current,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam(required = false) String bizType,
@RequestParam(required = false) String status) {
@RequestParam(required = false) String status,
@RequestParam(required = false) String ennm,
@RequestParam(required = false) String hbrvnm) {
Page<ApprovalMain> page = new Page<>(current, size);
Page<ApprovalMain> result = approvalMainService.queryPageList(page, bizType, status);
Page<ApprovalMain> result = approvalMainService.queryPageList(page, bizType, status,ennm,hbrvnm);
return ResponseResult.successData(result);
}

View File

@ -5,11 +5,15 @@ import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yfd.platform.common.DataSourceRequest;
@ -29,6 +33,9 @@ import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -111,16 +118,57 @@ public class FishDraftDataController {
return result ? ResponseResult.success("保存成功") : ResponseResult.error("保存失败");
}
// @PostMapping("/batchSaveDraft")
// @Operation(summary = "批量保存草稿")
// public ResponseResult saveDraft(@RequestBody List<FishDraftData> fishDraftDataList) {
//
// fishDraftDataList.forEach(fishDraftData -> {
// fishDraftData.setStatus("DRAFT");
// fishDraftData.setDeletedFlag(0);
// fishDraftData.setLockFlag(0);
// });
// boolean result = fishDraftDataService.saveBatch(fishDraftDataList);
// return result ? ResponseResult.success("保存成功") : ResponseResult.error("保存失败");
// }
@PostMapping("/batchSaveDraft")
@Operation(summary = "批量保存草稿")
public ResponseResult saveDraft(@RequestBody List<FishDraftData> fishDraftDataList) {
@Transactional(rollbackFor = Exception.class)
public ResponseResult saveDraft(@RequestBody FishImportRowRequest request) {
String taskId = request.getTaskId();
ImportTask importTask = importTaskService.getById(taskId);
String resultJson = importTask.getResultJson();
FishImportResult importResult = null;
Map<String, String> imageFiles = null;
Map<String, String> videoFiles = null;
if (resultJson != null && !resultJson.isEmpty()) {
try {
importResult = objectMapper.readValue(resultJson, FishImportResult.class);
imageFiles = importResult.getImageFiles();
videoFiles = importResult.getVideoFiles();
} catch (Exception e) {
e.printStackTrace();
}
}
fishDraftDataList.forEach(fishDraftData -> {
fishDraftData.setStatus("DRAFT");
fishDraftData.setDeletedFlag(0);
fishDraftData.setLockFlag(0);
});
if (importResult == null || importResult.getRows() == null) {
return ResponseResult.error("导入数据不存在");
}
Date date = new Date();
List<FishDraftData> fishDraftDataList = new ArrayList<>();
for (FishImportResult.FishImportRow row : importResult.getRows()) {
FishDraftData data = row.getData();
data.setRowIndex(row.getRowIndex());
data.setStatus("DRAFT");
data.setEnddt(data.getStrdt());
data.setDeletedFlag(0);
data.setLockFlag(0);
data.setTm(date);
fishDraftDataList.add(data);
}
boolean result = fishDraftDataService.saveBatch(fishDraftDataList);
fishImportService.processAttachmentsAsync(fishDraftDataList, imageFiles, videoFiles,importTask.getTempDir());
importTaskService.markSuccess(taskId);
return result ? ResponseResult.success("保存成功") : ResponseResult.error("保存失败");
}
@ -200,6 +248,15 @@ public class FishDraftDataController {
return result ? ResponseResult.success("提交成功") : ResponseResult.error("提交失败");
}
@PostMapping("/submitDraftsAll")
@Operation(summary = "批量提交当前用户全部草稿")
public ResponseResult submitDraftsAll() {
List<FishDraftData> draft = fishDraftDataService.list(new LambdaQueryWrapper<FishDraftData>().eq(FishDraftData::getDeletedFlag, 0).eq(FishDraftData::getCreatedBy, SecurityUtils.getUserId()).in(FishDraftData::getStatus, "REJECTED", "DRAFT").select(FishDraftData::getId));
List<String> ids = draft.stream().map(FishDraftData::getId).toList();
boolean result = fishDraftDataService.submitDrafts(ids);
return result ? ResponseResult.success("提交成功") : ResponseResult.error("提交失败");
}
@PostMapping("/batchApprove")
@Operation(summary = "批量审批通过")
public ResponseResult batchApprove(@RequestBody BatchApproveRequest request) {
@ -207,6 +264,27 @@ public class FishDraftDataController {
return result ? ResponseResult.success("审批通过") : ResponseResult.error("审批失败");
}
// @PostMapping("/batchApproveAll")
// @Operation(summary = "批量全部审批通过")
// public ResponseResult batchApproveAll(@RequestBody BatchApproveRequest request) {
// List<FishDraftData> draft = fishDraftDataService.list(new LambdaQueryWrapper<FishDraftData>().eq(FishDraftData::getCreatedBy, SecurityUtils.getUserId()).eq(FishDraftData::getStatus, "PENDING").select(FishDraftData::getId));
// List<String> ids = draft.stream().map(FishDraftData::getId).toList();
// boolean result = fishDraftDataService.batchApprove(ids, request.getApproveComment());
// return result ? ResponseResult.success("审批通过") : ResponseResult.error("审批失败");
// }
@PostMapping("/batchApproveByApprovalId")
@Operation(summary = "根据审批批次全部审批通过")
public ResponseResult batchApproveByApprovalId(@RequestBody BatchApproveRequest request) {
if (request.getApprovalIds().isEmpty()) {
return ResponseResult.error("请选择审批批次");
}
List<FishDraftData> draft = fishDraftDataService.list(new LambdaQueryWrapper<FishDraftData>().eq(FishDraftData::getDeletedFlag, 0).in(FishDraftData::getApprovalId, request.getApprovalIds()).eq(FishDraftData::getStatus, "PENDING").select(FishDraftData::getId));
List<String> ids = draft.stream().map(FishDraftData::getId).toList();
boolean result = fishDraftDataService.batchApprove(ids, request.getApproveComment());
return result ? ResponseResult.success("审批通过") : ResponseResult.error("审批失败");
}
@PostMapping("/reject")
@Operation(summary = "审批驳回")
public ResponseResult batchReject(@RequestBody BatchRejectRequest request) {
@ -214,6 +292,22 @@ public class FishDraftDataController {
return result ? ResponseResult.success("驳回成功") : ResponseResult.error("驳回失败");
}
@PostMapping("/batchReject")
@Operation(summary = "批量驳回")
public ResponseResult batchRejectFull(@RequestBody BatchRejectRequest request) {
if (request.getApprovalIds() != null && !request.getApprovalIds().isEmpty()) {
List<FishDraftData> draft = fishDraftDataService.list(new LambdaQueryWrapper<FishDraftData>().eq(FishDraftData::getDeletedFlag, 0).in(FishDraftData::getApprovalId, request.getApprovalIds()).eq(FishDraftData::getStatus, "PENDING").select(FishDraftData::getId));
List<String> ids = draft.stream().map(FishDraftData::getId).toList();
boolean result = fishDraftDataService.rejectBatch(ids, request.getRejectReason());
return result ? ResponseResult.success("驳回成功") : ResponseResult.error("驳回失败");
}
if (request.getIds() != null && !request.getIds().isEmpty()) {
boolean result = fishDraftDataService.rejectBatch(request.getIds(), request.getRejectReason());
return result ? ResponseResult.success("驳回成功") : ResponseResult.error("驳回失败");
}
return ResponseResult.error("请选择要驳回的数据");
}
@PostMapping("/lockDraft")
@Operation(summary = "锁定草稿")
@ -264,22 +358,27 @@ public class FishDraftDataController {
if (file == null || file.isEmpty()) {
return ResponseResult.error("请上传文件");
}
log.info("开始上传文件");
String fileName = file.getOriginalFilename();
if (fileName == null || (!fileName.endsWith(".zip"))) {
return ResponseResult.error("请上传ZIP文件(.zip)");
}
log.info("开始处理文件");
String uploadUserId = SecurityUtils.getUserId();
if (importTaskService.hasImportingTask(uploadUserId)) {
return ResponseResult.error("您有正在进行的导入任务,请等待完成后重试");
}
log.info("开始保存导入任务");
String importNo = "IMP" + System.currentTimeMillis();
String taskId = UUID.randomUUID().toString();
try {
String baseTempDir = ZipFileUtil.getDefaultTempDir();
String taskDirName = "zip_" + UUID.randomUUID().toString().substring(0, 8);
Path tempDirPath = Paths.get(baseTempDir, taskDirName);
Files.createDirectories(tempDirPath);
File savedZipFile = new File(tempDirPath.toFile(), "upload.zip");
file.transferTo(savedZipFile);
log.info("ZIP文件已保存到: {}", savedZipFile.getAbsolutePath());
ImportTask task = new ImportTask();
task.setId(taskId);
task.setImportNo(importNo);
@ -289,33 +388,45 @@ public class FishDraftDataController {
task.setStatus("UPLOADED");
task.setUploadUserId(uploadUserId);
task.setUploadTime(new Date());
log.info("保存导入任务成功");
task.setTempDir(tempDirPath.toString());
importTaskService.save(task);
log.info("导入任务已创建: {}", taskId);
SecurityContext securityContext = SecurityContextHolder.getContext();
CompletableFuture.runAsync(() -> {
try {
SecurityContextHolder.setContext(securityContext);
log.info("异步开始解析ZIP文件, taskId: {}", taskId);
FishImportResult result = fishImportService.parseAndMapZipFromFile(
savedZipFile, tempDirPath.toString(), uploadUserId);
result.setTaskId(taskId);
String status = "VALIDATED";
if ("1".equals(result.getCode())) {
status = "FAILED";
}
importTaskService.updateStatus(taskId, status, result.getTempDir(), null);
importTaskService.updateProgress(taskId, result.getTotalCount(),
result.getSuccessCount(), result.getFailedCount());
String resultJson = objectMapper.writeValueAsString(result);
importTaskService.saveResultJson(taskId, resultJson);
log.info("异步解析完成, taskId: {}, 状态: {}", taskId, status);
} catch (Exception e) {
log.error("异步解析ZIP失败, taskId: {}", taskId, e);
importTaskService.markFailed(taskId, "导入失败: " + e.getMessage());
} finally {
SecurityContextHolder.clearContext();
if (savedZipFile.exists()) {
savedZipFile.delete();
}
}
});
log.info("开始保存文件");
FishImportRequest request = new FishImportRequest();
request.setImportNo(importNo);
request.setUploadUserId(uploadUserId);
request.setBizType("FISH");
FishImportResult result = fishImportService.parseAndMapZip(file, uploadUserId);
result.setTaskId(taskId);
String status = "VALIDATED";
if ("1".equals(result.getCode())) {
status = "FAILED";
}
importTaskService.updateStatus(taskId, status, null);
importTaskService.updateProgress(taskId, result.getTotalCount(), result.getSuccessCount(), result.getFailedCount());
try {
String resultJson = objectMapper.writeValueAsString(result);
importTaskService.saveResultJson(taskId, resultJson);
} catch (Exception e) {
// 忽略JSON序列化错误不影响主流程
e.printStackTrace();
}
return ResponseResult.successData(result);
Map<String, String> response = new HashMap<>();
response.put("taskId", taskId);
response.put("importNo", importNo);
response.put("status", "UPLOADED");
return ResponseResult.successData(response);
} catch (Exception e) {
log.error("创建导入任务失败", e);
importTaskService.markFailed(taskId, "导入失败: " + e.getMessage());
return ResponseResult.error("导入失败: " + e.getMessage());
}
@ -435,12 +546,13 @@ public class FishDraftDataController {
writeErrorResponse(response, "预览失败: " + e.getMessage());
}
}
@GetMapping("/deleteFile")
@Operation(summary = "删除导入文件")
public ResponseResult deleteFile(@RequestParam String taskId,
@RequestParam String id,
@RequestParam String type,
@RequestParam String filename) {
@RequestParam String id,
@RequestParam String type,
@RequestParam String filename) {
if (taskId == null || taskId.isEmpty()) {
return ResponseResult.error("任务ID不能为空");
}
@ -612,28 +724,13 @@ public class FishDraftDataController {
return ResponseResult.successData(result);
}
int totalCount = currentTask.getTotalCount() != null ? currentTask.getTotalCount() : 0;
int successCount = currentTask.getSuccessCount() != null ? currentTask.getSuccessCount() : 0;
int failCount = currentTask.getFailCount() != null ? currentTask.getFailCount() : 0;
int progressPercent = totalCount > 0 ? (int) ((successCount + failCount) * 100.0 / totalCount) : 0;
String statusText = getStatusText(currentTask.getStatus());
boolean canImport = isTaskComplete(currentTask.getStatus());
Map<String, Object> taskInfo = new HashMap<>();
taskInfo.put("id", currentTask.getId());
taskInfo.put("importNo", currentTask.getImportNo());
taskInfo.put("fileName", currentTask.getFileName());
taskInfo.put("fileSize", currentTask.getFileSize());
taskInfo.put("status", currentTask.getStatus());
taskInfo.put("statusText", statusText);
taskInfo.put("totalCount", totalCount);
taskInfo.put("successCount", successCount);
taskInfo.put("failCount", failCount);
taskInfo.put("progressPercent", progressPercent);
taskInfo.put("errorMsg", currentTask.getErrorMsg() != null ? currentTask.getErrorMsg() : "");
taskInfo.put("uploadTime", currentTask.getUploadTime());
result.put("hasImportingTask", true);
result.put("canImport", canImport);
result.put("currentTask", taskInfo);
@ -845,6 +942,57 @@ public class FishDraftDataController {
}
}
@PostMapping("/deleteRowById")
@Operation(summary = "删除数据")
public ResponseResult deleteRowById(@RequestBody FishImportRowRequest request) {
String taskId = request.getTaskId();
FishDraftData data = request.getData();
if (taskId == null || taskId.isEmpty()) {
return ResponseResult.error("任务ID不能为空");
}
if (data == null || data.getId() == null || data.getId().isEmpty()) {
return ResponseResult.error("数据对象或其ID不能为空");
}
try {
ImportTask task = importTaskService.getById(taskId);
if (task == null) {
return ResponseResult.error("任务不存在");
}
String resultJson = task.getResultJson();
if (resultJson == null || resultJson.isEmpty()) {
return ResponseResult.error("任务结果为空");
}
FishImportResult importResult = objectMapper.readValue(resultJson, FishImportResult.class);
FishImportResult.FishImportRow targetRow = null;
int targetIndex = -1;
for (int i = 0; i < importResult.getRows().size(); i++) {
FishImportResult.FishImportRow row = importResult.getRows().get(i);
if (row.getData() != null && data.getId().equals(row.getData().getId())) {
targetRow = row;
targetIndex = i;
break;
}
}
if (targetIndex == -1) {
return ResponseResult.error("未找到对应的数据行");
}
importResult.getRows().remove(targetIndex);
String updatedJson = objectMapper.writeValueAsString(importResult);
importTaskService.saveResultJson(taskId, updatedJson);
return ResponseResult.success();
} catch (Exception e) {
log.error("删除数据失败: " + e.getMessage(), e);
return ResponseResult.error("删除数据失败: " + e.getMessage());
}
}
private void validateAndNormalizeData(FishDraftData data, FishImportResult.FishImportRow importRow,
List<String> warnings) {
if (data.getStcd() == null || data.getStcd().isEmpty()) {

View File

@ -101,7 +101,7 @@ public class ImportTaskController {
public ResponseResult updateStatus(@RequestParam String id,
@RequestParam String status,
@RequestParam(required = false) String errorMsg) {
boolean result = importTaskService.updateStatus(id, status, errorMsg);
boolean result = importTaskService.updateStatus(id, status,null, errorMsg);
return result ? ResponseResult.success("更新成功") : ResponseResult.error("更新失败");
}

View File

@ -82,6 +82,30 @@ public class ApprovalMain implements Serializable {
*/
private String remark;
/**
* 电站
*/
private String ennm;
/**
* 流域
*/
private String hbrvnm;
/**
* 电站
*/
private String stcd;
/**
* 流域
*/
private String hbrvcd;
/**
* 创建时间
*/

View File

@ -15,6 +15,9 @@ public class BatchApproveRequest {
@Schema(description = "草稿数据ID列表")
private List<String> ids;
@Schema(description = "批次ID列表")
List<String> approvalIds;
@Schema(description = "审批意见")
private String approveComment;
}

View File

@ -3,6 +3,8 @@ package com.yfd.platform.data.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* 审批驳回请求参数
*/
@ -13,6 +15,12 @@ public class BatchRejectRequest {
@Schema(description = "草稿数据ID")
private String id;
@Schema(description = "草稿数据ID列表")
private List<String> ids;
@Schema(description = "批次ID列表")
private List<String> approvalIds;
@Schema(description = "驳回原因")
private String rejectReason;
}

View File

@ -156,6 +156,14 @@ public class FishDraftData implements Serializable {
*/
private Integer deletedFlag;
/**
* 行号
*/
private Integer rowIndex;
/**
* 删除人
*/

View File

@ -216,7 +216,7 @@ public class FishDraftDataVO implements Serializable {
/**
* 排序字段
*/
private Integer orderIndex;
private Integer rowIndex;
/**
* 创建人名称

View File

@ -27,7 +27,10 @@ public interface FishDraftDataMapper extends BaseMapper<FishDraftData> {
@Param("status") String status,
@Param("ftp") String ftp,
@Param("startTime") String startTime,
@Param("endTime") String endTime,@Param("userId") String userId,@Param("hbrvcd") String hbrvcd);
@Param("endTime") String endTime,
@Param("userId") String userId,
@Param("hbrvcd") String hbrvcd,
@Param("approvalId") String approvalId);
/**
* 关联查询过鱼数据不分页

View File

@ -38,15 +38,16 @@ public interface ImportTaskMapper extends BaseMapper<ImportTask> {
@Select("SELECT * FROM IMPORT_TASK WHERE UPLOAD_USER_ID = #{uploadUserId} ORDER BY CREATED_AT DESC")
List<ImportTask> selectByUploadUserId(@Param("uploadUserId") String uploadUserId);
@Select("<script>" +
"SELECT * FROM IMPORT_TASK WHERE UPLOAD_USER_ID = #{uploadUserId} AND STATUS IN " +
"<foreach item='status' collection='statuses' open='(' separator=',' close=')'>" +
"#{status}" +
"</foreach>" +
" ORDER BY CREATED_AT DESC" +
"</script>")
List<ImportTask> selectByUserIdAndStatuses(@Param("uploadUserId") String uploadUserId,
@Param("statuses") List<String> statuses);
@Select("SELECT * FROM (" +
"SELECT ID, IMPORT_NO, BIZ_TYPE, FILE_NAME, FILE_SIZE, FILE_PATH, TEMP_DIR, " +
"TOTAL_COUNT, SUCCESS_COUNT, FAIL_COUNT, STATUS, ERROR_MSG, " +
"UPLOAD_USER_ID, UPLOAD_TIME, EXPIRE_TIME, CREATED_AT, UPDATED_AT " +
"FROM IMPORT_TASK " +
"WHERE UPLOAD_USER_ID = #{uploadUserId} " +
"AND STATUS IN ('UPLOADED', 'PARSING', 'VALIDATED') " +
"ORDER BY CREATED_AT DESC" +
") WHERE ROWNUM = 1")
List<ImportTask> selectByUserIdAndStatuses(@Param("uploadUserId") String uploadUserId);
/**
* 查询过期的任务

View File

@ -42,5 +42,5 @@ public interface SysUserDataScopeMapper extends BaseMapper<SysUserDataScope> {
/**
* 查询有效权限状态=1且在有效期内的
*/
List<SysUserDataScope> selectValidPermissions(@Param("userId") Long userId);
List<SysUserDataScope> selectValidPermissions(@Param("userId") String userId);
}

View File

@ -32,13 +32,20 @@ public class AttachmentUploadService {
@Value("${attachment.token}")
private String token;
// 定义一个固定的线程池用于文件上传建议根据服务器性能调整核心线程数
@Value("${attachment.upload-url}")
private String uploadUrl;
@Value("${attachment.video-url}")
private String videoUrl;
@Value("${attachment.delete-url}")
private String deleteUrl;
// private static final String DELETE_URL = "https://211.99.26.225:12125/FileDelete";
private static final ExecutorService UPLOAD_EXECUTOR = new ThreadPoolExecutor(
5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100),
new ThreadPoolExecutor.CallerRunsPolicy()
);
private static final String UPLOAD_URL = "https://211.99.26.225:12125/upload";
private static final String VIDEO_URL = "https://211.99.26.225:12125/upload";
private final HttpClient httpClient;
@ -68,32 +75,14 @@ public class AttachmentUploadService {
System.arraycopy(footer.getBytes(), 0, body, header.getBytes().length + fileContent.length, footer.getBytes().length);
try {
// 1. 创建信任所有证书的 TrustManager
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
}
};
// 2. 初始化 SSLContext
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
// 3. 构建支持 HTTPS 且忽略证书验证的 HttpClient
HttpClient secureClient = HttpClient.newBuilder()
.sslContext(sc)
.build();
log.info("开始上传文件:uploadUrl {}", uploadUrl);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(UPLOAD_URL))
.uri(URI.create(uploadUrl))
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.POST(HttpRequest.BodyPublishers.ofByteArray(body))
.build();
// 4. 使用新的 secureClient 发送请求
HttpResponse<String> response = secureClient.send(request, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
String responseBody = response.body();
@ -109,6 +98,68 @@ public class AttachmentUploadService {
}
// public String uploadFile(File file) throws IOException, InterruptedException {
// if (file == null || !file.exists()) {
// log.warn("文件不存在或为空: {}", file);
// return null;
// }
//
// String boundary = "----FormBoundary" + System.currentTimeMillis();
// byte[] fileContent = Files.readAllBytes(file.toPath());
// String fileName = file.getName();
//
// String header = "--" + boundary + "\r\n" +
// "Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"\r\n" +
// "Content-Type: application/octet-stream\r\n\r\n";
// String footer = "\r\n--" + boundary + "--\r\n";
//
// byte[] body = new byte[header.getBytes().length + fileContent.length + footer.getBytes().length];
// System.arraycopy(header.getBytes(), 0, body, 0, header.getBytes().length);
// System.arraycopy(fileContent, 0, body, header.getBytes().length, fileContent.length);
// System.arraycopy(footer.getBytes(), 0, body, header.getBytes().length + fileContent.length, footer.getBytes().length);
//
// try {
// // 1. 创建信任所有证书的 TrustManager
// TrustManager[] trustAllCerts = new TrustManager[]{
// new X509TrustManager() {
// public void checkClientTrusted(X509Certificate[] chain, String authType) {}
// public void checkServerTrusted(X509Certificate[] chain, String authType) {}
// public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
// }
// };
//
// // 2. 初始化 SSLContext
// SSLContext sc = SSLContext.getInstance("TLS");
// sc.init(null, trustAllCerts, new SecureRandom());
//
// // 3. 构建支持 HTTPS 且忽略证书验证的 HttpClient
// HttpClient secureClient = HttpClient.newBuilder()
// .sslContext(sc)
// .build();
//
// HttpRequest request = HttpRequest.newBuilder()
// .uri(URI.create(uploadUrl))
// .header("Content-Type", "multipart/form-data; boundary=" + boundary)
// .POST(HttpRequest.BodyPublishers.ofByteArray(body))
// .build();
//
// // 4. 使用新的 secureClient 发送请求
// HttpResponse<String> response = secureClient.send(request, HttpResponse.BodyHandlers.ofString());
//
// if (response.statusCode() == 200) {
// String responseBody = response.body();
// return parseAttachmentId(responseBody);
// } else {
// log.error("上传文件失败: {}, 状态码: {}", fileName, response.statusCode());
// return null;
// }
// } catch (Exception e) {
// log.error("文件上传过程中发生异常: {}", e.getMessage(), e);
// return null;
// }
// }
/**
* 多线程批量上传文件
* @param files 文件列表
@ -266,7 +317,55 @@ public class AttachmentUploadService {
}
}
private static final String DELETE_URL = "https://211.99.26.225:12125/FileDelete";
// public boolean deleteFile(String attachmentId) {
// if (attachmentId == null || attachmentId.isEmpty()) {
// log.warn("附件ID为空");
// return false;
// }
//
// try {
// TrustManager[] trustAllCerts = new TrustManager[]{
// new X509TrustManager() {
// public void checkClientTrusted(X509Certificate[] chain, String authType) {}
// public void checkServerTrusted(X509Certificate[] chain, String authType) {}
// public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
// }
// };
//
// SSLContext sc = SSLContext.getInstance("TLS");
// sc.init(null, trustAllCerts, new SecureRandom());
//
// HttpClient secureClient = HttpClient.newBuilder()
// .sslContext(sc)
// .build();
//
// String formData = "fileId=" + attachmentId;
//
// HttpRequest request = HttpRequest.newBuilder()
// .uri(URI.create(deleteUrl))
// .header("Content-Type", "application/x-www-form-urlencoded")
// .header("token", token)
// .POST(HttpRequest.BodyPublishers.ofString(formData))
// .build();
//
// HttpResponse<String> response = secureClient.send(request, HttpResponse.BodyHandlers.ofString());
//
// if (response.statusCode() == 200) {
// String responseBody = response.body();
// return parseDeleteResult(responseBody);
// } else {
// log.error("删除附件失败: {}, 状态码: {}", attachmentId, response.statusCode());
// return false;
// }
// } catch (Exception e) {
// log.error("删除附件过程中发生异常: {}", attachmentId, e);
// return false;
// }
// }
public boolean deleteFile(String attachmentId) {
if (attachmentId == null || attachmentId.isEmpty()) {
@ -275,31 +374,16 @@ public class AttachmentUploadService {
}
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
}
};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpClient secureClient = HttpClient.newBuilder()
.sslContext(sc)
.build();
String formData = "fileId=" + attachmentId;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(DELETE_URL))
.uri(URI.create(deleteUrl))
.header("Content-Type", "application/x-www-form-urlencoded")
.header("token", token)
.POST(HttpRequest.BodyPublishers.ofString(formData))
.build();
HttpResponse<String> response = secureClient.send(request, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
String responseBody = response.body();
@ -314,6 +398,7 @@ public class AttachmentUploadService {
}
}
private boolean parseDeleteResult(String jsonResponse) {
if (jsonResponse == null || jsonResponse.isEmpty()) {
return false;

View File

@ -3,6 +3,7 @@ package com.yfd.platform.data.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yfd.platform.data.domain.ApprovalMain;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@ -16,7 +17,7 @@ public interface IApprovalMainService extends IService<ApprovalMain> {
/**
* 分页查询审批列表
*/
Page<ApprovalMain> queryPageList(Page<ApprovalMain> page, String bizType, String status);
Page<ApprovalMain> queryPageList(Page<ApprovalMain> page, String bizType, String status,String ennm, String hbrvnm);
void fillUserNames(List<ApprovalMain> list);

View File

@ -75,6 +75,11 @@ public interface IFishDraftDataService extends IService<FishDraftData> {
*/
boolean batchReject(String id, String rejectReason);
/**
* 批量驳回
*/
boolean rejectBatch(List<String> ids, String rejectReason);
/**
* 锁定草稿
*/

View File

@ -5,6 +5,7 @@ import com.yfd.platform.data.domain.FishImportResult;
import com.yfd.platform.data.utils.ZipFileUtil;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
/**
@ -14,12 +15,14 @@ import java.io.InputStream;
*/
public interface IFishImportService {
FishImportResult parseAndMapExcel(FishImportRequest request, InputStream inputStream);
FishImportResult parseAndMapExcel(FishImportRequest request, InputStream inputStream,String userId);
FishImportResult parseAndMapExcelFromPath(FishImportRequest request);
FishImportResult parseAndMapExcelFromPath(FishImportRequest request,String userId);
FishImportResult parseAndMapZip(MultipartFile file, String uploadUserId);
FishImportResult parseAndMapZipFromFile(File zipFile, String tempDir, String uploadUserId);
String resolveStationCode(String stationName);
String resolveFpssCode(String name);
@ -48,4 +51,9 @@ public interface IFishImportService {
boolean validateFpssBelongsToStation(String fpssCode, String stationCode);
void processAttachments(FishImportResult result, ZipFileUtil.ZipContent zipContent);
void processAttachmentsAsync(java.util.List<com.yfd.platform.data.domain.FishDraftData> dataList,
java.util.Map<String, String> imageFiles,
java.util.Map<String, String> videoFiles,
String tempDir);
}

View File

@ -41,7 +41,7 @@ public interface IImportTaskService extends IService<ImportTask> {
/**
* 更新任务状态
*/
boolean updateStatus(String id, String status, String errorMsg);
boolean updateStatus(String id, String status,String tempDir, String errorMsg);
/**
* 更新解析进度

View File

@ -1,10 +1,13 @@
package com.yfd.platform.data.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.data.domain.ApprovalMain;
import com.yfd.platform.data.domain.SysUserDataScope;
import com.yfd.platform.data.mapper.ApprovalMainMapper;
import com.yfd.platform.data.mapper.SysUserDataScopeMapper;
import com.yfd.platform.data.service.IApprovalLogService;
import com.yfd.platform.data.service.IApprovalMainService;
import com.yfd.platform.system.domain.SysUser;
@ -15,6 +18,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
@ -33,11 +37,16 @@ public class ApprovalMainServiceImpl extends ServiceImpl<ApprovalMainMapper, App
@Resource
private SysUserMapper sysUserMapper;
@Resource
private SysUserDataScopeMapper sysUserDataScopeMapper;
@Override
public Page<ApprovalMain> queryPageList(Page<ApprovalMain> page, String bizType, String status) {
public Page<ApprovalMain> queryPageList(Page<ApprovalMain> page, String bizType, String status,String ennm, String hbrvnm) {
Page<ApprovalMain> approvalMainPage = this.page(page, this.lambdaQuery()
.eq(StringUtils.hasText(bizType), ApprovalMain::getBizType, bizType)
.eq(StringUtils.hasText(status), ApprovalMain::getStatus, status)
.like(StringUtils.hasText(ennm), ApprovalMain::getEnnm, ennm)
.like(StringUtils.hasText(hbrvnm), ApprovalMain::getHbrvnm, hbrvnm)
.orderByDesc(ApprovalMain::getCreatedAt)
.getWrapper());
fillUserNames(approvalMainPage.getRecords());
@ -52,6 +61,7 @@ public class ApprovalMainServiceImpl extends ServiceImpl<ApprovalMainMapper, App
Set<String> userIds = new HashSet<>();
for (ApprovalMain vo : list) {
if (StrUtil.isNotBlank(vo.getApproverId())) {
userIds.add(vo.getApproverId());
}
@ -63,7 +73,6 @@ public class ApprovalMainServiceImpl extends ServiceImpl<ApprovalMainMapper, App
if (userIds.isEmpty()) {
return;
}
Map<String, String> userNameMap = new HashMap<>();
List<SysUser> users = sysUserMapper.selectBatchIds(userIds);
for (SysUser user : users) {

View File

@ -9,12 +9,21 @@ import com.yfd.platform.common.DataSourceLoadOptionsBase;
import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.data.domain.ApprovalMain;
import com.yfd.platform.data.domain.FishDraftData;
import com.yfd.platform.data.domain.SysUserDataScope;
import com.yfd.platform.data.domain.vo.FishDraftDataVO;
import com.yfd.platform.data.mapper.FishDraftDataMapper;
import com.yfd.platform.data.mapper.SysUserDataScopeMapper;
import com.yfd.platform.data.service.IApprovalChangeLogService;
import com.yfd.platform.data.service.IApprovalLogService;
import com.yfd.platform.data.service.IApprovalMainService;
import com.yfd.platform.data.service.IFishDraftDataService;
import com.yfd.platform.env.domain.SdEngInfoBH;
import com.yfd.platform.env.domain.SdFpssR;
import com.yfd.platform.env.domain.SdHbrvDic;
import com.yfd.platform.env.mapper.SdEngInfoBHMapper;
import com.yfd.platform.env.mapper.SdFpssRMapper;
import com.yfd.platform.env.mapper.SdHbrvDicMapper;
import com.yfd.platform.env.service.ISdFpssRService;
import com.yfd.platform.system.domain.SysUser;
import com.yfd.platform.system.mapper.SysUserMapper;
import com.yfd.platform.utils.KendoUtil;
@ -22,6 +31,8 @@ import com.yfd.platform.utils.QgcQueryWrapperUtil;
import com.yfd.platform.utils.SecurityUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.BatchResult;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -35,6 +46,7 @@ import java.util.*;
* </p>
*/
@Service
@Slf4j
public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, FishDraftData> implements IFishDraftDataService {
@Resource
@ -55,27 +67,49 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
@Resource
private ObjectMapper objectMapper;
@Resource
private SysUserDataScopeMapper userDataScopeMapper;
@Resource
private SdEngInfoBHMapper engInfoBHMapper;
@Resource
private SdHbrvDicMapper hbrvDicMapper;
@Resource
private SdFpssRMapper sdFpssRMapper;
@Resource
private ISdFpssRService sdFpssRService;
@Override
public Page<FishDraftDataVO> queryPageList(DataSourceRequest dataSourceRequest) {
Page<FishDraftDataVO> page = KendoUtil.getPage(dataSourceRequest);
page.setSize(dataSourceRequest.getTake());
page.setCurrent(dataSourceRequest.getSkip());
DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest();
String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd");
String approvalId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "approvalId");
String rstcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rstcd");
String hbrvcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "hbrvcd");
String baseId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "baseId");
String ftp = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "ftp");
String direction = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "direction");
String status = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "status");
String TM = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "TM");
String STRDT = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "strdt");
String startTime=null;
String endTime=null;
String userId = (SecurityUtils.hasPermission("sjtb:edit-review") || "admin".equals(SecurityUtils.getCurrentUsername())) ?null:SecurityUtils.getUserId();
// 如果 startTime endTime 为空尝试从 TM 字段解析
if (StrUtil.isNotBlank(TM)&& TM.split( ",").length==2) {
startTime=TM.split(",")[0];
endTime=TM.split(",")[1];
// String userId = (SecurityUtils.hasPermission("sjtb:edit-review") || "admin".equals(SecurityUtils.getCurrentUsername())) ?null:SecurityUtils.getUserId();
String userId = SecurityUtils.getUserId();
if(StrUtil.isNotBlank(approvalId)){
userId=null;
}
Page<FishDraftDataVO> resultPage = fishDraftDataMapper.selectJoinPage(page, stcd, rstcd, baseId, direction, status, ftp, startTime, endTime,userId,hbrvcd);
// 如果 startTime endTime 为空尝试从 TM 字段解析
if (StrUtil.isNotBlank(STRDT)&& STRDT.split( ",").length==2) {
startTime=STRDT.split(",")[0];
endTime=STRDT.split(",")[1];
}
Page<FishDraftDataVO> resultPage = fishDraftDataMapper.selectJoinPage(page, stcd, rstcd, baseId, direction, status, ftp, startTime, endTime,userId,hbrvcd,approvalId);
fillUserNames(resultPage.getRecords());
return resultPage;
}
@ -240,6 +274,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
approvalMain.setApplyUserId(operatorId);
approvalMain.setApplyTime(new Date());
approvalMain.setStatus("PENDING");
setUserDataScope(approvalMain);
approvalMainService.save(approvalMain);
fishDraftData.setApprovalId(approvalMain.getId());
@ -267,6 +302,8 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
approvalMain.setApplyUserId(operatorId);
approvalMain.setApplyTime(new Date());
approvalMain.setStatus("PENDING");
// 查询当前人的数据权限
setUserDataScope(approvalMain);
approvalMainService.save(approvalMain);
LambdaUpdateWrapper<FishDraftData> updateWrapper = new LambdaUpdateWrapper<>();
@ -282,6 +319,85 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
return true;
}
private void setUserDataScope(ApprovalMain approvalMain) {
String userId = SecurityUtils.getUserId();
if (userId == null) {
return;
}
List<SysUserDataScope> permissions = userDataScopeMapper.selectValidPermissions(userId);
if (permissions == null || permissions.isEmpty()) {
return;
}
Set<String> hbrvcdSet = new HashSet<>();
Set<String> hbrvnmSet = new HashSet<>();
Set<String> stcdSet = new HashSet<>();
Set<String> ennmSet = new HashSet<>();
for (SysUserDataScope permission : permissions) {
String orgType = permission.getOrgType();
String orgId = permission.getOrgId();
if (orgId == null || orgId.isEmpty()) {
continue;
}
if ("HBRVCD".equals(orgType)) {
hbrvcdSet.add(orgId);
SdHbrvDic hbrv = hbrvDicMapper.selectById(orgId);
if (hbrv != null && hbrv.getHbrvnm() != null) {
hbrvnmSet.add(hbrv.getHbrvnm());
}
List<SdEngInfoBH> stationList = engInfoBHMapper.selectByHbrvcd(orgId);
if (stationList != null) {
for (SdEngInfoBH station : stationList) {
if (station.getStcd() != null) {
stcdSet.add(station.getStcd());
}
if (station.getEnnm() != null) {
ennmSet.add(station.getEnnm());
}
}
}
} else if ("STATION".equals(orgType)) {
SdEngInfoBH station = engInfoBHMapper.selectById(orgId);
if (station != null) {
if (station.getHbrvcd() != null) {
hbrvcdSet.add(station.getHbrvcd());
}
if (station.getStcd() != null) {
stcdSet.add(station.getStcd());
}
if (station.getEnnm() != null) {
ennmSet.add(station.getEnnm());
}
SdHbrvDic hbrv = hbrvDicMapper.selectById(station.getHbrvcd());
if (hbrv != null && hbrv.getHbrvnm() != null) {
hbrvnmSet.add(hbrv.getHbrvnm());
}
}
}
}
if (!hbrvcdSet.isEmpty()) {
approvalMain.setHbrvcd(String.join(",", hbrvcdSet));
}
if (!hbrvnmSet.isEmpty()) {
approvalMain.setHbrvnm(String.join(",", hbrvnmSet));
}
if (!stcdSet.isEmpty()) {
approvalMain.setStcd(String.join(",", stcdSet));
}
if (!ennmSet.isEmpty()) {
approvalMain.setEnnm(String.join(",", ennmSet));
}
}
@Override
@Transactional(rollbackFor = Exception.class)
@ -295,6 +411,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
List<FishDraftData> dataList = this.listByIds(ids);
Set<String> processedApprovalIds = new HashSet<>();
List<String> validIds = new ArrayList<>();
List<SdFpssR> fpssRList = new ArrayList<>();
for (FishDraftData fishDraftData : dataList) {
if ("PENDING".equals(fishDraftData.getStatus())) {
@ -302,6 +419,8 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
if (fishDraftData.getApprovalId() != null) {
processedApprovalIds.add(fishDraftData.getApprovalId());
}
SdFpssR fpssR = convertToSdFpssR(fishDraftData, operatorId);
fpssRList.add(fpssR);
}
}
@ -312,6 +431,8 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
updateWrapper.set(FishDraftData::getApproveTime, now);
updateWrapper.set(FishDraftData::getUpdatedBy, operatorId);
this.update(updateWrapper);
boolean b = sdFpssRService.saveOrUpdateBatch(fpssRList);
log.info("=======================插入数据条数======================="+fpssRList.size());
for (String approvalId : processedApprovalIds) {
ApprovalMain approvalMain = approvalMainService.getById(approvalId);
approvalLogService.logApprove(approvalId, SecurityUtils.getUserId(), approveComment);
@ -328,6 +449,47 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
return true;
}
private SdFpssR convertToSdFpssR(FishDraftData draft, String operatorId) {
SdFpssR fpssR = new SdFpssR();
fpssR.setId(draft.getId());
fpssR.setStcd(draft.getStcd());
fpssR.setTm(draft.getTm());
fpssR.setFtp(draft.getFtp());
fpssR.setFsz(draft.getFsz());
fpssR.setIsfs(draft.getIsfs());
fpssR.setFcnt(draft.getFcnt());
fpssR.setFwet(draft.getFwet());
fpssR.setStrdt(draft.getStrdt());
fpssR.setEnddt(draft.getEnddt());
fpssR.setDirection(convertDirection(draft.getDirection()));
fpssR.setYr(draft.getYr());
fpssR.setMouth(draft.getMouth() != null ? String.valueOf(draft.getMouth()) : null);
fpssR.setVdpth(draft.getVdpth());
fpssR.setPicpth(draft.getPicpth());
fpssR.setRecordUser(operatorId);
fpssR.setRecordTime(new Date());
fpssR.setIsDeleted(0);
return fpssR;
}
private Integer convertDirection(String direction) {
if (direction == null) {
return null;
}
switch (direction.trim()) {
case "上行", "0":
return 0;
case "下行", "1":
return 1;
case "上行折返", "2":
return 2;
case "下行折返", "3":
return 3;
default:
return null;
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean batchReject(String id, String rejectReason) {
@ -361,6 +523,55 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean rejectBatch(List<String> ids, String rejectReason) {
if (ids == null || ids.isEmpty()) {
return false;
}
if (StrUtil.isBlank(rejectReason)) {
throw new IllegalArgumentException("驳回原因不能为空");
}
Date now = new Date();
String operatorId = SecurityUtils.getUserId();
List<FishDraftData> dataList = this.listByIds(ids);
Set<String> processedApprovalIds = new HashSet<>();
List<String> validIds = new ArrayList<>();
for (FishDraftData fishDraftData : dataList) {
if ("PENDING".equals(fishDraftData.getStatus())) {
validIds.add(fishDraftData.getId());
if (fishDraftData.getApprovalId() != null) {
processedApprovalIds.add(fishDraftData.getApprovalId());
}
}
}
if (!validIds.isEmpty()) {
LambdaUpdateWrapper<FishDraftData> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.in(FishDraftData::getId, validIds);
updateWrapper.set(FishDraftData::getStatus, "REJECTED");
updateWrapper.set(FishDraftData::getApproveTime, now);
updateWrapper.set(FishDraftData::getUpdatedBy, operatorId);
this.update(updateWrapper);
for (String approvalId : processedApprovalIds) {
approvalLogService.logReject(approvalId, operatorId, rejectReason);
ApprovalMain approvalMain = approvalMainService.getById(approvalId);
if (approvalMain != null) {
approvalMain.setStatus("REJECTED");
approvalMain.setApproverId(operatorId);
approvalMain.setApproveTime(now);
approvalMain.setRemark(rejectReason);
approvalMainService.updateById(approvalMain);
}
}
}
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean lockDraft(String id) {

View File

@ -1,24 +1,33 @@
package com.yfd.platform.data.service.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yfd.platform.data.domain.FishDraftData;
import com.yfd.platform.data.domain.FishImportRequest;
import com.yfd.platform.data.domain.FishImportResult;
import com.yfd.platform.data.domain.SysUserDataScope;
import com.yfd.platform.data.mapper.SysUserDataScopeMapper;
import com.yfd.platform.data.service.AttachmentUploadService;
import com.yfd.platform.data.service.IFishDraftDataService;
import com.yfd.platform.data.service.IFishImportService;
import com.yfd.platform.data.utils.ZipFileUtil;
import com.yfd.platform.env.domain.*;
import com.yfd.platform.env.mapper.*;
import com.yfd.platform.system.service.ISysDictionaryItemsService;
import com.yfd.platform.system.service.ISysDictionaryService;
import com.yfd.platform.utils.SecurityUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@ -26,6 +35,7 @@ import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
@Service
@Slf4j
@ -58,6 +68,12 @@ public class FishImportServiceImpl implements IFishImportService {
@Resource
private AttachmentUploadService attachmentUploadService;
@Resource
private IFishDraftDataService fishDraftDataService;
@Resource
private SysUserDataScopeMapper userDataScopeMapper;
private static final Map<String, String> EXCEL_COLUMN_MAPPING = new LinkedHashMap<>();
private static final Map<Integer, String> EXCEL_COLUMN_INDEX_MAPPING = new LinkedHashMap<>();
@ -123,12 +139,12 @@ public class FishImportServiceImpl implements IFishImportService {
}
@Override
public FishImportResult parseAndMapExcel(FishImportRequest request, InputStream inputStream) {
public FishImportResult parseAndMapExcel(FishImportRequest request, InputStream inputStream, String userId) {
FishImportResult result = new FishImportResult();
try (Workbook workbook = new XSSFWorkbook(inputStream)) {
Sheet sheet = workbook.getSheetAt(0);
return parseSheet(sheet, result);
return parseSheet(sheet, result, userId);
} catch (IOException e) {
result.setSummary("Excel文件解析失败: " + e.getMessage());
return result;
@ -136,20 +152,20 @@ public class FishImportServiceImpl implements IFishImportService {
}
@Override
public FishImportResult parseAndMapExcelFromPath(FishImportRequest request) {
public FishImportResult parseAndMapExcelFromPath(FishImportRequest request, String userId) {
FishImportResult result = new FishImportResult();
try (InputStream inputStream = request.getFilePath().startsWith("http")
? new java.net.URL(request.getFilePath()).openStream()
: new java.io.FileInputStream(request.getFilePath())) {
return parseAndMapExcel(request, inputStream);
return parseAndMapExcel(request, inputStream, userId);
} catch (IOException e) {
result.setSummary("读取文件失败: " + e.getMessage());
return result;
}
}
private FishImportResult parseSheet(Sheet sheet, FishImportResult result) {
private FishImportResult parseSheet(Sheet sheet, FishImportResult result, String uploadUserId) {
loadStationAndBaseCache();
Row headerRow = sheet.getRow(0);
@ -167,7 +183,7 @@ public class FishImportServiceImpl implements IFishImportService {
continue;
}
FishImportResult.FishImportRow importRow = parseRow(result, row, columnIndexMap, i);
FishImportResult.FishImportRow importRow = parseRow(result, row, columnIndexMap, i, uploadUserId);
result.setTotalCount(result.getTotalCount() + 1);
if (importRow.getData() != null && importRow.getWarnings().isEmpty()) {
result.addSuccessRow(importRow);
@ -183,10 +199,65 @@ public class FishImportServiceImpl implements IFishImportService {
return result;
}
private FishImportResult.FishImportRow parseRow(FishImportResult result, Row row, Map<Integer, String> columnIndexMap, int rowIndex) {
private FishImportResult.FishImportRow parseRow(FishImportResult result, Row row, Map<Integer, String> columnIndexMap, int rowIndex, String userId) {
FishImportResult.FishImportRow importRow = new FishImportResult.FishImportRow(rowIndex);
FishDraftData data = new FishDraftData();
data.setId(UUID.randomUUID().toString());
Set<String> allowedHbrvcdSet = new HashSet<>();
Set<String> directStcdSet = new HashSet<>();
Set<String> directBHSet = new HashSet<>();
if (userId != null) {
List<SysUserDataScope> permissions = userDataScopeMapper.selectValidPermissions(userId);
if (permissions != null && !permissions.isEmpty()) {
for (SysUserDataScope permission : permissions) {
String orgType = permission.getOrgType();
String orgId = permission.getOrgId();
if (orgId == null || orgId.isEmpty()) {
continue;
}
if ("HBRVCD".equals(orgType)) {
allowedHbrvcdSet.add(orgId);
} else if ("STATION".equals(orgType)) {
directStcdSet.add(orgId);
}
}
}
}
// Set<String> allStcdSet = new HashSet<>();
if (!allowedHbrvcdSet.isEmpty() || !directStcdSet.isEmpty()) {
if (!allowedHbrvcdSet.isEmpty()) {
List<SdEngInfoBH> stationsFromHbrv = engInfoBHMapper.selectByHbrvcdList(new ArrayList<>(allowedHbrvcdSet));
for (SdEngInfoBH station : stationsFromHbrv) {
if (station.getStcd() != null) {
directStcdSet.add(station.getStcd());
}
}
}
if (!directStcdSet.isEmpty()) {
List<SdEngInfoBH> stationsFromStcd = engInfoBHMapper.selectBatchIds(new ArrayList<>(directStcdSet));
for (SdEngInfoBH station : stationsFromStcd) {
if (station.getStcd() != null) {
directStcdSet.add(station.getStcd());
}
if (station.getHbrvcd() != null) {
allowedHbrvcdSet.add(station.getHbrvcd());
}
}
}
}
if (!directStcdSet.isEmpty()) {
List<SdFpssBH> sdFpssBHS = fpssBHMapper.selectList(new LambdaQueryWrapper<SdFpssBH>().in(SdFpssBH::getRstcd, directStcdSet).select(SdFpssBH::getStcd));
for (SdFpssBH sdFpssBH : sdFpssBHS) {
if (sdFpssBH.getStcd() != null) {
directBHSet.add(sdFpssBH.getStcd());
}
}
}
for (Map.Entry<Integer, String> entry : columnIndexMap.entrySet()) {
Integer columnIndex = entry.getKey();
String fieldName = entry.getValue();
@ -205,8 +276,15 @@ public class FishImportServiceImpl implements IFishImportService {
importRow.getWarnings().add("rstcd");
data.setEnnm(cellValue.trim());
} else {
data.setEnnm(cellValue.trim());
data.setRstcd(stcd);
if (directStcdSet.contains(stcd)) {
data.setEnnm(cellValue.trim());
data.setRstcd(stcd);
} else {
importRow.getWarnings().add("rstcd");
data.setEnnm(cellValue.trim());
data.setRstcd(cellValue);
}
}
}
break;
@ -239,19 +317,26 @@ public class FishImportServiceImpl implements IFishImportService {
}
break;
case "hbrvcd":
if(!StringUtils.hasText(cellValue)){
if (!StringUtils.hasText(cellValue)) {
importRow.getWarnings().add("hbrvcd");
data.setHbrvcd(cellValue);
data.setHbrvnm(cellValue);
}else{
} else {
String hbrvcdCode = resolveHbrvcdCode(cellValue.trim());
if (hbrvcdCode == null) {
importRow.getWarnings().add("hbrvcd");
data.setHbrvcd(cellValue.trim());
data.setHbrvnm(cellValue.trim());
}else{
data.setHbrvcd(hbrvcdCode);
data.setHbrvnm(cellValue.trim());
} else {
if (allowedHbrvcdSet.contains(hbrvcdCode)) {
data.setHbrvcd(hbrvcdCode);
data.setHbrvnm(cellValue.trim());
} else {
importRow.getWarnings().add("hbrvcd");
data.setHbrvcd(cellValue.trim());
data.setHbrvnm(cellValue.trim());
}
}
}
// if (StringUtils.hasText(cellValue)) {
@ -419,8 +504,15 @@ public class FishImportServiceImpl implements IFishImportService {
data.setStcd(cellValue.trim());
data.setStnm(cellValue.trim());
} else {
data.setStnm(cellValue.trim());
data.setStcd(stcd);
if (directBHSet.contains(stcd)) {
data.setStnm(cellValue.trim());
data.setStcd(stcd);
} else {
importRow.getWarnings().add("stcd");
data.setStcd(cellValue.trim());
data.setStnm(cellValue.trim());
}
}
}
break;
@ -468,8 +560,65 @@ public class FishImportServiceImpl implements IFishImportService {
}
private void loadStationAndBaseCache() {
// String userId = SecurityUtils.getUserId();
// Set<String> allowedHbrvcdSet = new HashSet<>();
// Set<String> directStcdSet = new HashSet<>();
//
// if (userId != null) {
// List<SysUserDataScope> permissions = userDataScopeMapper.selectValidPermissions(userId);
// if (permissions != null && !permissions.isEmpty()) {
// for (SysUserDataScope permission : permissions) {
// String orgType = permission.getOrgType();
// String orgId = permission.getOrgId();
//
// if (orgId == null || orgId.isEmpty()) {
// continue;
// }
//
// if ("HBRVCD".equals(orgType)) {
// allowedHbrvcdSet.add(orgId);
// } else if ("STATION".equals(orgType)) {
// directStcdSet.add(orgId);
// }
// }
// }
// }
//
// Set<String> allStcdSet = new HashSet<>();
//
// if (!allowedHbrvcdSet.isEmpty() || !directStcdSet.isEmpty()) {
// if (!allowedHbrvcdSet.isEmpty()) {
// List<SdEngInfoBH> stationsFromHbrv = engInfoBHMapper.selectByHbrvcdList(new ArrayList<>(allowedHbrvcdSet));
// for (SdEngInfoBH station : stationsFromHbrv) {
// if (station.getStcd() != null) {
// allStcdSet.add(station.getStcd());
// }
// }
// }
//
// if (!directStcdSet.isEmpty()) {
// List<SdEngInfoBH> stationsFromStcd = engInfoBHMapper.selectBatchIds(new ArrayList<>(directStcdSet));
// for (SdEngInfoBH station : stationsFromStcd) {
// if (station.getStcd() != null) {
// allStcdSet.add(station.getStcd());
// }
// if (station.getHbrvcd() != null) {
// allowedHbrvcdSet.add(station.getHbrvcd());
// }
// }
// }
// }
if (STATION_NAME_CACHE.isEmpty()) {
List<SdEngInfoBH> stationList = engInfoBHMapper.selectList(null);
// if (!allStcdSet.isEmpty()) {
// stationList = engInfoBHMapper.selectBatchIds(new ArrayList<>(allStcdSet));
// } else if("admin".equals(SecurityUtils.getCurrentUsername())){
//
// }else {
// stationList = new ArrayList<>();
// }
for (SdEngInfoBH station : stationList) {
if (StringUtils.hasText(station.getEnnm())) {
STATION_NAME_CACHE.put(station.getEnnm().trim().toLowerCase(), station.getStcd());
@ -478,7 +627,7 @@ public class FishImportServiceImpl implements IFishImportService {
if (StringUtils.hasText(station.getEnnm())) {
STATION_CODE_TO_NAME_CACHE.put(station.getStcd().trim().toLowerCase(), station.getEnnm().trim().toLowerCase());
}
if (StringUtils.hasText(station.getBaseId())) {
if (StringUtils.hasText(station.getHbrvcd())) {
STATION_TO_BASE_CACHE.put(station.getStcd().trim().toLowerCase(), station.getHbrvcd());
}
}
@ -515,6 +664,13 @@ public class FishImportServiceImpl implements IFishImportService {
if (HBRVCD_NAME_CACHE.isEmpty()) {
List<SdHbrvDic> riverList = sdHbrvDicMapper.selectList(null);
// if (!allowedHbrvcdSet.isEmpty()) {
// LambdaQueryWrapper<SdHbrvDic> wrapper = new LambdaQueryWrapper<>();
// wrapper.in(SdHbrvDic::getHbrvcd, allowedHbrvcdSet);
// riverList = sdHbrvDicMapper.selectList(wrapper);
// } else {
// riverList = sdHbrvDicMapper.selectList(null);
// }
for (SdHbrvDic river : riverList) {
if (StringUtils.hasText(river.getHbrvnm())) {
HBRVCD_NAME_CACHE.put(river.getHbrvnm().trim().toLowerCase(), river.getHbrvcd());
@ -543,6 +699,11 @@ public class FishImportServiceImpl implements IFishImportService {
if (FPSS_BH_CACHE.isEmpty()) {
List<SdFpssBH> sdFpssBHS = fpssBHMapper.selectList(null);
// if (!allStcdSet.isEmpty()) {
// sdFpssBHS = fpssBHMapper.selectList(new LambdaQueryWrapper<SdFpssBH>().in(SdFpssBH::getStcd, allStcdSet));
// } else {
// sdFpssBHS = fpssBHMapper.selectList(null);
// }
for (SdFpssBH sdFpssBH : sdFpssBHS) {
if (StringUtils.hasText(sdFpssBH.getStnm())) {
FPSS_BH_CACHE.put(sdFpssBH.getStnm().trim().toLowerCase(), sdFpssBH.getStcd());
@ -1046,7 +1207,7 @@ public class FishImportServiceImpl implements IFishImportService {
result.setVideoFiles(zipContent.videos);
try (Workbook workbook = new XSSFWorkbook(new FileInputStream(zipContent.excelFilePath))) {
Sheet sheet = workbook.getSheetAt(0);
result = parseSheet(sheet, result);
result = parseSheet(sheet, result, uploadUserId);
}
result.setExcelFileName(zipContent.excelFileName);
result.setExcelFilePath(zipContent.excelFilePath);
@ -1069,6 +1230,44 @@ public class FishImportServiceImpl implements IFishImportService {
}
}
@Override
public FishImportResult parseAndMapZipFromFile(File zipFile, String tempDir, String uploadUserId) {
FishImportResult result = new FishImportResult();
try {
log.info("开始异步解析ZIP文件...");
ZipFileUtil.ZipContent zipContent = ZipFileUtil.extractFromSavedZipFile(zipFile, tempDir);
if (zipContent.excelFilePath == null) {
result.setSummary("ZIP文件中未找到Excel文件");
result.setCode("1");
result.setMessage("ZIP文件中未找到Excel文件");
return result;
}
result.setTempDir(zipContent.tempDir);
result.setImageFiles(zipContent.images);
result.setVideoFiles(zipContent.videos);
try (Workbook workbook = new XSSFWorkbook(new FileInputStream(zipContent.excelFilePath))) {
Sheet sheet = workbook.getSheetAt(0);
result = parseSheet(sheet, result, uploadUserId);
}
result.setExcelFileName(zipContent.excelFileName);
result.setExcelFilePath(zipContent.excelFilePath);
log.info("ZIP文件异步解析完成");
result.setSummary(result.getSummary() + String.format("\nZIP内容: 发现%d张图片, %d个视频",
zipContent.images.size(), zipContent.videos.size()));
return result;
} catch (Exception e) {
log.error("ZIP文件异步解析失败", e);
result.setSummary("ZIP文件解析失败: " + e.getMessage());
result.setCode("1");
result.setMessage("ZIP文件解析失败");
return result;
}
}
@Override
public void processAttachments(FishImportResult result, ZipFileUtil.ZipContent zipContent) {
for (FishImportResult.FishImportRow importRow : result.getRows()) {
@ -1092,6 +1291,118 @@ public class FishImportServiceImpl implements IFishImportService {
}
}
@Override
public void processAttachmentsAsync(List<FishDraftData> dataList,
Map<String, String> imageFiles,
Map<String, String> videoFiles,
String tempDir) {
if (dataList == null || dataList.isEmpty()) {
return;
}
List<CompletableFuture<Void>> futures = new ArrayList<>();
SecurityContext securityContext = SecurityContextHolder.getContext();
for (FishDraftData data : dataList) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
SecurityContextHolder.setContext(securityContext);
String vdpth = data.getVdpth();
String picpth = data.getPicpth();
if(StrUtil.isBlank(vdpth)||StrUtil.isBlank(picpth)){
log.error("数据不完整, 忽略处理");
return;
}
if (StringUtils.hasText(vdpth) && videoFiles != null && !videoFiles.isEmpty()) {
String uploadedVdpth = uploadVideoFilesAsync(vdpth, videoFiles);
if (uploadedVdpth != null) {
data.setVdpth(uploadedVdpth);
}
}
if (StringUtils.hasText(picpth) && imageFiles != null && !imageFiles.isEmpty()) {
String uploadedPicpth = uploadImageFilesAsync(picpth, imageFiles);
if (uploadedPicpth != null) {
data.setPicpth(uploadedPicpth);
}
}
fishDraftDataService.updateById(data);
log.info("异步上传附件完成, dataId: {},{},{}", data.getId(), data.getPicpth(), data.getVdpth());
} catch (Exception e) {
log.error("异步上传附件失败, dataId: {}", data.getId(), e);
} finally {
SecurityContextHolder.clearContext();
}
});
futures.add(future);
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenRun(() -> {
try {
// del 方法会递归删除目录及其所有内容
FileUtil.del(tempDir);
} catch (Exception e) {
log.error("删除临时目录失败{}", e.getMessage());
}
})
.exceptionally(ex -> {
log.error("等待异步任务完成时发生异常", ex);
return null;
});
}
private String uploadVideoFilesAsync(String videoNames, Map<String, String> videoMap) {
String[] fileNames = videoNames.split(";");
List<String> attachmentIds = new ArrayList<>();
for (String fileName : fileNames) {
fileName = fileName.trim();
if (fileName.isEmpty()) {
continue;
}
String actualPath = findFilePath(fileName, videoMap);
if (actualPath != null) {
try {
String attachmentId = attachmentUploadService.uploadFileAndGetId(actualPath);
if (attachmentId != null) {
attachmentIds.add(attachmentId);
}
} catch (Exception e) {
log.error("上传视频失败: {}", fileName, e);
}
}
}
return attachmentIds.isEmpty() ? videoNames : String.join(",", attachmentIds);
}
private String uploadImageFilesAsync(String imageNames, Map<String, String> imageMap) {
String[] fileNames = imageNames.split(";");
List<String> attachmentIds = new ArrayList<>();
for (String fileName : fileNames) {
fileName = fileName.trim();
if (fileName.isEmpty()) {
continue;
}
String actualPath = findFilePath(fileName, imageMap);
if (actualPath != null) {
try {
String attachmentId = attachmentUploadService.uploadFileAndGetId(actualPath);
if (attachmentId != null) {
attachmentIds.add(attachmentId);
}
} catch (Exception e) {
log.error("上传图片失败: {}", fileName, e);
}
}
}
return attachmentIds.isEmpty() ? imageNames : String.join(",", attachmentIds);
}
private String processVideoAttachments(FishImportResult.FishImportRow importRow, String videoNames, Map<String, String> videoMap) {
if (videoNames == null || videoNames.isEmpty() || videoMap == null || videoMap.isEmpty()) {
return videoNames;
@ -1110,7 +1421,9 @@ public class FishImportServiceImpl implements IFishImportService {
fileMap.put("name", fileName);
if (actualPath != null) {
try {
log.info("开始上传视频文件: {}", actualPath);
String attachmentId = attachmentUploadService.uploadFileAndGetId(actualPath);
log.info("开始上传视频文件后:{}attachmentId{} ", actualPath, attachmentId);
if (attachmentId != null) {
attachmentIds.add(attachmentId);
fileMap.put("value", attachmentId);
@ -1150,7 +1463,9 @@ public class FishImportServiceImpl implements IFishImportService {
String actualPath = findFilePath(fileName, imageMap);
if (actualPath != null) {
try {
log.info("开始上传图片文件: {}", actualPath);
String attachmentId = attachmentUploadService.uploadFileAndGetId(actualPath);
log.info("开始上传图片文件后:{}attachmentId{} ", actualPath, attachmentId);
if (attachmentId != null) {
attachmentIds.add(attachmentId);
fileMap.put("value", attachmentId);

View File

@ -12,12 +12,14 @@ import com.yfd.platform.data.mapper.ImportTaskMapper;
import com.yfd.platform.data.service.AttachmentUploadService;
import com.yfd.platform.data.service.IImportTaskService;
import jakarta.annotation.Resource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* <p>
@ -81,12 +83,13 @@ public class ImportTaskServiceImpl extends ServiceImpl<ImportTaskMapper, ImportT
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateStatus(String id, String status, String errorMsg) {
public boolean updateStatus(String id, String status,String tempDir, String errorMsg) {
ImportTask importTask = this.getById(id);
if (importTask == null) {
return false;
}
importTask.setStatus(status);
importTask.setTempDir(tempDir);
if (StringUtils.hasText(errorMsg)) {
importTask.setErrorMsg(errorMsg);
}
@ -137,19 +140,6 @@ public class ImportTaskServiceImpl extends ServiceImpl<ImportTaskMapper, ImportT
importTask.setStatus("CONFIRMED");
importTask.setUpdatedAt(new Date());
boolean b = this.updateById(importTask);
// 删除本地临时目录数据
String resultJson = importTask.getResultJson();
if (resultJson != null && !resultJson.isEmpty()) {
try {
FishImportResult importResult = objectMapper.readValue(resultJson, FishImportResult.class);
String tempDir = importResult.getTempDir();
// del 方法会递归删除目录及其所有内容
FileUtil.del(tempDir);
} catch (Exception e) {
e.printStackTrace();
// ignore parse error
}
}
return b;
}
@ -166,8 +156,8 @@ public class ImportTaskServiceImpl extends ServiceImpl<ImportTaskMapper, ImportT
@Override
public boolean hasImportingTask(String uploadUserId) {
List<String> activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATING");
List<ImportTask> tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId, activeStatuses);
// List<String> activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATING");
List<ImportTask> tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId);
return tasks != null && !tasks.isEmpty();
}
@ -182,30 +172,20 @@ public class ImportTaskServiceImpl extends ServiceImpl<ImportTaskMapper, ImportT
if ("CONFIRMED".equals(currentStatus) || "FAILED".equals(currentStatus) || "CANCELLED".equals(currentStatus)) {
return false;
}
if (importTask.getResultJson() != null && !importTask.getResultJson().isEmpty()) {
try {
FishImportResult importResult = objectMapper.readValue(importTask.getResultJson(), FishImportResult.class);
for (FishImportResult.FishImportRow successRow : importResult.getRows()) {
if (successRow.getData()==null) {
continue;
}
String vdpth = successRow.getData().getVdpth();
if (StringUtils.hasText(vdpth)) {
List<String> fileIds = StrUtil.split(vdpth, ",");
fileIds.forEach(fileId -> attachmentUploadService.deleteFile(fileId));
}
String picpth = successRow.getData().getPicpth();
if (StringUtils.hasText(picpth)) {
List<String> fileIds = StrUtil.split(vdpth, ",");
fileIds.forEach(fileId -> attachmentUploadService.deleteFile(fileId));
}
String temp = importTask.getTempDir();
if (StrUtil.isNotBlank( temp)) {
FileUtil.del(temp);
}else{
if (importTask.getResultJson() != null && !importTask.getResultJson().isEmpty()) {
try {
FishImportResult importResult = objectMapper.readValue(importTask.getResultJson(), FishImportResult.class);
String tempDir = importResult.getTempDir();
// del 方法会递归删除目录及其所有内容
FileUtil.del(tempDir);
} catch (Exception e) {
e.printStackTrace();
// ignore parse error
}
String tempDir = importResult.getTempDir();
// del 方法会递归删除目录及其所有内容
FileUtil.del(tempDir);
} catch (Exception e) {
e.printStackTrace();
// ignore parse error
}
}
importTask.setStatus("CANCELLED");
@ -216,8 +196,8 @@ public class ImportTaskServiceImpl extends ServiceImpl<ImportTaskMapper, ImportT
@Override
public ImportTask getCurrentTaskByUserId(String uploadUserId) {
List<String> activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATED");
List<ImportTask> tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId, activeStatuses);
// List<String> activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATED");
List<ImportTask> tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId);
if (tasks == null || tasks.isEmpty()) {
return null;
}

View File

@ -73,6 +73,55 @@ public class ZipFileUtil {
return extractZipToTemp(file, getDefaultTempDir());
}
// public static ZipContent extractZipToTemp(MultipartFile file, String baseTempDir) throws IOException {
// ZipContent content = new ZipContent();
//
// String taskId = UUID.randomUUID().toString().substring(0, 8);
// Path tempDirPath = Paths.get(baseTempDir, "zip_" + taskId);
//
// log.info("extractZipToTemp: {}", tempDirPath);
// Files.createDirectories(tempDirPath);
// content.tempDir = tempDirPath.toString();
// File zipFile = new File(tempDirPath.toFile(), "upload.zip");
// file.transferTo(zipFile);
//
// try {
// log.info("--------------isValidZipFile------------");
// if (!isValidZipFile(zipFile)) {
// log.info("--------------文件不是有效的ZIP格式或已损坏------------");
// throw new IOException("文件不是有效的ZIP格式或已损坏");
// }
//
// IOException lastException = null;
// Charset[] charsets = new Charset[]{
// StandardCharsets.UTF_8,
// Charset.forName("GBK"),
// StandardCharsets.ISO_8859_1,
// Charset.forName("GB18030")
// };
//
// for (Charset charset : charsets) {
// try {
// content = extractFromZipFile(zipFile, tempDirPath.toFile(), charset);
// content.tempDir = tempDirPath.toString();
// return content;
// } catch (IOException e) {
// lastException = e;
// content = new ZipContent();
// content.tempDir = tempDirPath.toString();
// }
// }
//
// log.error("extractZipToTemp: {}", lastException.getMessage());
// throw lastException != null ? lastException : new IOException("无法解析ZIP文件");
//
// } finally {
// if (zipFile.exists()) {
// zipFile.delete();
// }
// }
// }
public static ZipContent extractZipToTemp(MultipartFile file, String baseTempDir) throws IOException {
ZipContent content = new ZipContent();
@ -86,35 +135,7 @@ public class ZipFileUtil {
file.transferTo(zipFile);
try {
log.info("--------------isValidZipFile------------");
if (!isValidZipFile(zipFile)) {
log.info("--------------文件不是有效的ZIP格式或已损坏------------");
throw new IOException("文件不是有效的ZIP格式或已损坏");
}
IOException lastException = null;
Charset[] charsets = new Charset[]{
StandardCharsets.UTF_8,
Charset.forName("GBK"),
StandardCharsets.ISO_8859_1,
Charset.forName("GB18030")
};
for (Charset charset : charsets) {
try {
content = extractFromZipFile(zipFile, tempDirPath.toFile(), charset);
content.tempDir = tempDirPath.toString();
return content;
} catch (IOException e) {
lastException = e;
content = new ZipContent();
content.tempDir = tempDirPath.toString();
}
}
log.error("extractZipToTemp: {}", lastException.getMessage());
throw lastException != null ? lastException : new IOException("无法解析ZIP文件");
return extractFromSavedZipFile(zipFile, tempDirPath.toString());
} finally {
if (zipFile.exists()) {
zipFile.delete();
@ -122,6 +143,35 @@ public class ZipFileUtil {
}
}
public static ZipContent extractFromSavedZipFile(File zipFile, String tempDir) throws IOException {
if (!isValidZipFile(zipFile)) {
log.info("--------------文件不是有效的ZIP格式或已损坏------------");
throw new IOException("文件不是有效的ZIP格式或已损坏");
}
IOException lastException = null;
Charset[] charsets = new Charset[]{
StandardCharsets.UTF_8,
Charset.forName("GBK"),
StandardCharsets.ISO_8859_1,
Charset.forName("GB18030")
};
for (Charset charset : charsets) {
try {
ZipContent content = extractExcelWithRelatedFiles(zipFile, new File(tempDir), charset);
content.tempDir = tempDir;
return content;
} catch (IOException e) {
lastException = e;
log.warn("使用编码 {} 解析失败: {}", charset, e.getMessage());
}
}
log.error("extractFromSavedZipFile: {}", lastException != null ? lastException.getMessage() : "未知错误");
throw lastException != null ? lastException : new IOException("无法解析ZIP文件");
}
private static boolean isValidZipFile(File file) {
if (file == null || file.length() < 4) {
return false;
@ -179,6 +229,134 @@ public class ZipFileUtil {
return content;
}
private static ZipContent extractExcelWithRelatedFiles(File zipFile, File tempDir, Charset charset) throws IOException {
ZipContent content = new ZipContent();
try (ZipFile zip = new ZipFile(zipFile, charset)) {
Enumeration<? extends ZipEntry> entries = zip.entries();
String excelEntryName = null;
String excelParentPath = null;
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String entryName = entry.getName();
if (entry.isDirectory()) {
continue;
}
String lowerName = entryName.toLowerCase();
if ((lowerName.endsWith(".xlsx") || lowerName.endsWith(".xls")) && excelEntryName == null) {
excelEntryName = entryName;
excelParentPath = getParentDirectory(entryName);
log.info("找到Excel文件: {}, 所在目录: {}", excelEntryName, excelParentPath);
break;
}
}
if (excelEntryName == null) {
throw new IOException("ZIP文件中未找到Excel文件(.xlsx或.xls)");
}
entries = zip.entries();
int excelCount = 0;
int imageCount = 0;
int videoCount = 0;
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String entryName = entry.getName();
if (entry.isDirectory()) {
continue;
}
String entryParentPath = getParentDirectory(entryName);
String fileName = getFileName(entryName);
String lowerName = entryName.toLowerCase();
boolean shouldExtract = false;
String targetSubFolder = "";
if (lowerName.endsWith(".xlsx") || lowerName.endsWith(".xls")) {
if (excelParentPath.equals(entryParentPath)) {
shouldExtract = true;
targetSubFolder = "";
}
} else if (isInSubDirectory(entryParentPath, excelParentPath, "images")) {
if (isImageFile(lowerName)) {
shouldExtract = true;
targetSubFolder = "images";
}
} else if (isInSubDirectory(entryParentPath, excelParentPath, "videos")) {
if (isVideoFile(lowerName)) {
shouldExtract = true;
targetSubFolder = "videos";
}
}
if (shouldExtract) {
try (InputStream is = zip.getInputStream(entry)) {
String filePath = saveFileToDir(is, tempDir, targetSubFolder, fileName);
if (targetSubFolder.isEmpty()) {
if (content.excelFilePath == null) {
content.excelFileName = fileName;
content.excelFilePath = filePath;
excelCount++;
log.info("提取Excel文件: {}", fileName);
}
} else if ("images".equals(targetSubFolder)) {
content.images.put(fileName, filePath);
imageCount++;
log.debug("提取图片文件: {}", fileName);
} else if ("videos".equals(targetSubFolder)) {
content.videos.put(fileName, filePath);
videoCount++;
log.debug("提取视频文件: {}", fileName);
}
}
}
}
if (content.excelFilePath == null) {
throw new IOException("未能提取到Excel文件");
}
log.info("提取完成 - Excel: {}个, 图片: {}个, 视频: {}个",
excelCount, imageCount, videoCount);
}
return content;
}
private static String getParentDirectory(String entryName) {
if (entryName == null || entryName.isEmpty()) {
return "";
}
int lastSep = Math.max(entryName.lastIndexOf('/'), entryName.lastIndexOf('\\'));
if (lastSep >= 0) {
return entryName.substring(0, lastSep);
}
return "";
}
private static boolean isInSubDirectory(String entryParentPath, String excelParentPath, String subFolder) {
String expectedPath;
if (excelParentPath.isEmpty()) {
expectedPath = subFolder;
} else {
expectedPath = excelParentPath + "/" + subFolder;
}
String normalizedEntryPath = entryParentPath.replace("\\", "/");
String normalizedExpectedPath = expectedPath.replace("\\", "/");
return normalizedEntryPath.equalsIgnoreCase(normalizedExpectedPath);
}
private static String getFileName(String entryName) {
if (entryName == null) return "";
int lastSep = Math.max(entryName.lastIndexOf('/'), entryName.lastIndexOf('\\'));

View File

@ -0,0 +1,80 @@
package com.yfd.platform.env.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.env.domain.SdFpssR;
import com.yfd.platform.env.service.ISdFpssRService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
/**
* <p>
* 过鱼设施人工数据表 前端控制器
* </p>
*/
@RestController
@RequestMapping("/data/fpssR")
@Tag(name = "过鱼数据管理")
public class FpssRController {
@Resource
private ISdFpssRService fpssRService;
@GetMapping("/page")
@Operation(summary = "分页查询过鱼数据列表")
public ResponseResult queryPageList(
@RequestParam(defaultValue = "1") Integer current,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam(required = false) String stcd,
@RequestParam(required = false) Integer yr,
@RequestParam(required = false) String ftp) {
Page<SdFpssR> page = new Page<>(current, size);
Page<SdFpssR> result = fpssRService.queryPageList(page, stcd, yr, ftp);
return ResponseResult.successData(result);
}
@GetMapping("/getById")
@Operation(summary = "根据ID查询过鱼数据")
public ResponseResult getById(@RequestParam String id) {
SdFpssR fpssR = fpssRService.getById(id);
return ResponseResult.successData(fpssR);
}
@PostMapping("/add")
@Operation(summary = "新增过鱼数据")
public ResponseResult add(@RequestBody SdFpssR fpssR) {
boolean result = fpssRService.save(fpssR);
return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败");
}
@PostMapping("/update")
@Operation(summary = "修改过鱼数据")
public ResponseResult update(@RequestBody SdFpssR fpssR) {
boolean result = fpssRService.updateById(fpssR);
return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败");
}
@PostMapping("/delete")
@Operation(summary = "删除过鱼数据")
public ResponseResult delete(@RequestParam String id) {
boolean result = fpssRService.removeById(id);
return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
}
@PostMapping("/batchDelete")
@Operation(summary = "批量删除过鱼数据")
public ResponseResult batchDelete(@RequestBody java.util.List<String> ids) {
if (ids == null || ids.isEmpty()) {
return ResponseResult.error("请选择要删除的数据");
}
boolean result = true;
for (String id : ids) {
if (!fpssRService.removeById(id)) {
result = false;
}
}
return result ? ResponseResult.success("删除成功") : ResponseResult.error("部分删除失败");
}
}

View File

@ -61,9 +61,8 @@ public class SdFpssBHController {
@Operation(summary = "设施下拉列表(根据电站编码筛选 + 支持名称模糊搜索 + 支持基地编码筛选)")
public ResponseResult dropdown(@RequestParam(required = false) String rstcd,
@RequestParam(required = false) String stnm,
@RequestParam(required = false) String baseId,
@RequestParam(required = false) String hbrvcd) {
return ResponseResult.successData(sdFpssBHService.selectForDropdown(rstcd, stnm, baseId,hbrvcd));
@RequestParam(required = false) String baseId) {
return ResponseResult.successData(sdFpssBHService.selectForDropdown(rstcd, stnm, baseId));
}
@Log(module = "过鱼设施管理", value = "新增过鱼设施")

View File

@ -0,0 +1,144 @@
package com.yfd.platform.env.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* <p>
* 过鱼设施人工数据表
* </p>
*/
@Data
@TableName("SD_FPSS_R")
public class SdFpssR implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_UUID)
private String id;
/**
* 过鱼设施编码
*/
private String stcd;
/**
* 填报时间
*/
private Date tm;
/**
* 鱼种类
*/
private String ftp;
/**
* 鱼类规格单位cm
*/
private String fsz;
/**
* 过鱼数量单位
*/
private Integer fcnt;
/**
* 平均体重单位g
*/
private String fwet;
/**
* 开始日期
*/
private Date strdt;
/**
* 结束日期
*/
private Date enddt;
/**
* 游向0=上行,1=下行,2=上行折返,3=下行折返
*/
private Integer direction;
/**
* 当日运行次数
*/
private Integer rcnt;
/**
* 过鱼设施引用流量
*/
private BigDecimal fq;
/**
* 过鱼图片文件路径
*/
private String picpth;
/**
* 过鱼视频文件路径
*/
private String vdpth;
/**
* 年份数据时间精确到年
*/
private Integer yr;
/**
* 主要月份
*/
private String mouth;
/**
* 创建人
*/
private String recordUser;
/**
* 创建时间
*/
private Date recordTime;
/**
* 更新人
*/
private String modifyUser;
/**
* 更新时间
*/
private Date modifyTime;
/**
* 是否已删除0=未删除 1=已删除
*/
private Integer isDeleted;
/**
* 删除人
*/
private String deleteUser;
/**
* 删除时间
*/
private Date deleteTime;
/**
* 是否鱼苗0否 1是
*/
private Integer isfs;
}

View File

@ -16,13 +16,11 @@ public interface SdFpssBHMapper extends BaseMapper<SdFpssBH> {
"LEFT JOIN SD_ENGINFO_B_H E ON F.RSTCD = E.STCD " +
"WHERE 1=1 " +
"<if test='baseId != null and baseId != \"\"'> AND E.BASE_ID = #{baseId} </if>" +
"<if test='hbrvcd != null and hbrvcd != \"\"'> AND E.HBRVCD = #{hbrvcd} </if>" +
"<if test='rstcd != null and rstcd != \"\"'> AND F.RSTCD = #{rstcd} </if>" +
"<if test='stnm != null and stnm != \"\"'> AND F.STNM LIKE '%' || #{stnm} || '%' </if>" +
"ORDER BY F.ORDER_INDEX DESC" +
"</script>")
List<SdFpssBH> selectForDropdownWithBaseId(@Param("rstcd") String rstcd,
@Param("stnm") String stnm,
@Param("baseId") String baseId,
@Param("hbrvcd") String hbrvcd);
@Param("baseId") String baseId);
}

View File

@ -0,0 +1,14 @@
package com.yfd.platform.env.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.env.domain.SdFpssR;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 过鱼设施人工数据表 Mapper 接口
* </p>
*/
@Mapper
public interface SdFpssRMapper extends BaseMapper<SdFpssR> {
}

View File

@ -16,7 +16,7 @@ public interface ISdFpssBHService extends IService<SdFpssBH> {
/**
* 设施下拉列表根据电站编码筛选 + 支持名称模糊搜索 + 支持基地编码筛选
*/
List<SdFpssBH> selectForDropdown(String rstcd, String stnm, String baseId,String hbrvcd);
List<SdFpssBH> selectForDropdown(String rstcd, String stnm, String baseId);
Set<String> getUserAuthorizedStationCodes();

View File

@ -0,0 +1,18 @@
package com.yfd.platform.env.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yfd.platform.env.domain.SdFpssR;
/**
* <p>
* 过鱼设施人工数据表 服务类
* </p>
*/
public interface ISdFpssRService extends IService<SdFpssR> {
/**
* 分页查询过鱼数据
*/
Page<SdFpssR> queryPageList(Page<SdFpssR> page, String stcd, Integer yr, String ftp);
}

View File

@ -46,6 +46,8 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
Set<String> authorizedStations = getUserAuthorizedStationCodes();
if (authorizedStations != null && !authorizedStations.isEmpty()) {
wrapper.in(SdEngInfoBH::getStcd, authorizedStations);
}else if (!"admin".equals(SecurityUtils.getCurrentUsername())){
return page;
}
return this.page(page, wrapper);
}
@ -68,10 +70,10 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
@Override
public List<SdEngInfoBH> selectForDropdown(SdEngInfoBHRequest sdEngInfoBHRequest) {
String baseId = sdEngInfoBHRequest.getBaseId();
String hbrvcd = sdEngInfoBHRequest.getHbrvcd();
String ennm = sdEngInfoBHRequest.getEnnm();
List<String> rvcds = sdEngInfoBHRequest.getRvcds();
List<String> hbrvcds = sdEngInfoBHRequest.getHbrvcds();
String hbrvcd = sdEngInfoBHRequest.getHbrvcd();
LambdaQueryWrapper<SdEngInfoBH> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StringUtils.hasText(baseId), SdEngInfoBH::getBaseId, baseId)
.eq(StringUtils.hasText(hbrvcd), SdEngInfoBH::getHbrvcd, hbrvcd)
@ -84,10 +86,9 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
Set<String> authorizedStations = getUserAuthorizedStationCodes();
if (authorizedStations != null && !authorizedStations.isEmpty()) {
wrapper.in(SdEngInfoBH::getStcd, authorizedStations);
} else if (!"admin".equals(SecurityUtils.getCurrentUsername())){
return new ArrayList<>();
}
// else {
// return new ArrayList<>();
// }
return this.list(wrapper);
}
@ -105,17 +106,38 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
return new HashSet<>();
}
Set<String> stationCodes = new HashSet<>();
List<String> basinCodes = new ArrayList<>();
Set<String> basinCodes = new HashSet<>();
for (SysUserDataScope scope : sysUserDataScopes) {
String orgType = scope.getOrgType();
String orgId = scope.getOrgId();
if ("STATION".equals(orgType)) {
stationCodes.add(orgId);
SdEngInfoBH station = engInfoBHMapper.selectById(orgId);
if (station != null) {
if (station.getHbrvcd() != null) {
basinCodes.add(station.getHbrvcd());
}
if (station.getStcd() != null) {
stationCodes.add(station.getStcd());
}
}
} else if ("HBRVCD".equals(orgType)) {
basinCodes.add(orgId);
List<SdEngInfoBH> stationList = engInfoBHMapper.selectByHbrvcd(orgId);
if (stationList != null) {
for (SdEngInfoBH station : stationList) {
if (station.getStcd() != null) {
stationCodes.add(station.getStcd());
}
if (station.getEnnm() != null) {
basinCodes.add(station.getHbrvcd());
}
}
}
}
}
@ -155,10 +177,12 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
public List<SdEngInfoBH> selectRegDropdown(SdEngInfoBHRequest sdEngInfoBHRequest) {
String baseId = sdEngInfoBHRequest.getBaseId();
String ennm = sdEngInfoBHRequest.getEnnm();
String hbrvcd = sdEngInfoBHRequest.getHbrvcd();
List<String> rvcds = sdEngInfoBHRequest.getRvcds();
List<String> hbrvcds = sdEngInfoBHRequest.getHbrvcds();
LambdaQueryWrapper<SdEngInfoBH> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StringUtils.hasText(baseId), SdEngInfoBH::getBaseId, baseId)
.eq(StringUtils.hasText(hbrvcd), SdEngInfoBH::getHbrvcd, hbrvcd)
.in(rvcds != null && !rvcds.isEmpty(), SdEngInfoBH::getRvcd, rvcds)
.in(hbrvcds != null && !hbrvcds.isEmpty(), SdEngInfoBH::getHbrvcd, hbrvcds)
.like(StringUtils.hasText(ennm), SdEngInfoBH::getEnnm, ennm)

View File

@ -50,6 +50,8 @@ public class SdFpssBHServiceImpl extends ServiceImpl<SdFpssBHMapper, SdFpssBH> i
Set<String> authorizedStations = getUserAuthorizedStationCodes();
if (authorizedStations != null && !authorizedStations.isEmpty()) {
wrapper.in(SdFpssBH::getRstcd, authorizedStations);
}else if (!"admin".equals(SecurityUtils.getCurrentUsername())){
return page;
}
wrapper.orderByDesc(SdFpssBH::getOrderIndex);
@ -64,13 +66,13 @@ public class SdFpssBHServiceImpl extends ServiceImpl<SdFpssBHMapper, SdFpssBH> i
}
@Override
public List<SdFpssBH> selectForDropdown(String rstcd, String stnm,String baseId, String hbrvcd) {
public List<SdFpssBH> selectForDropdown(String rstcd, String stnm, String baseId) {
Set<String> authorizedStations = getUserAuthorizedStationCodes();
List<SdFpssBH> result;
if (StringUtils.hasText(hbrvcd)|| StringUtils.hasText(baseId)) {
result = baseMapper.selectForDropdownWithBaseId(rstcd, stnm, baseId,hbrvcd);
if (StringUtils.hasText(baseId)) {
result = baseMapper.selectForDropdownWithBaseId(rstcd, stnm, baseId);
} else {
LambdaQueryWrapper<SdFpssBH> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StringUtils.hasText(rstcd), SdFpssBH::getRstcd, rstcd)
@ -78,7 +80,7 @@ public class SdFpssBHServiceImpl extends ServiceImpl<SdFpssBHMapper, SdFpssBH> i
.orderByDesc(SdFpssBH::getOrderIndex);
result = list(wrapper);
}
if (authorizedStations.isEmpty()) {
if (authorizedStations.isEmpty()&&"admin".equals(SecurityUtils.getCurrentUsername())) {
return result;
}
@ -100,20 +102,40 @@ public class SdFpssBHServiceImpl extends ServiceImpl<SdFpssBHMapper, SdFpssBH> i
return new HashSet<>();
}
Set<String> stationCodes = new HashSet<>();
List<String> basinCodes = new ArrayList<>();
Set<String> basinCodes = new HashSet<>();
for (SysUserDataScope scope : sysUserDataScopes) {
String orgType = scope.getOrgType();
String orgId = scope.getOrgId();
if ("STATION".equals(orgType)) {
stationCodes.add(orgId);
SdEngInfoBH station = sdEngInfoBHMapper.selectById(orgId);
if (station != null) {
if (station.getHbrvcd() != null) {
basinCodes.add(station.getHbrvcd());
}
if (station.getStcd() != null) {
stationCodes.add(station.getStcd());
}
}
} else if ("HBRVCD".equals(orgType)) {
basinCodes.add(orgId);
List<SdEngInfoBH> stationList = sdEngInfoBHMapper.selectByHbrvcd(orgId);
if (stationList != null) {
for (SdEngInfoBH station : stationList) {
if (station.getStcd() != null) {
stationCodes.add(station.getStcd());
}
if (station.getEnnm() != null) {
basinCodes.add(station.getHbrvcd());
}
}
}
}
}
if (!stationCodes.isEmpty()) {
return stationCodes;
}

View File

@ -0,0 +1,64 @@
package com.yfd.platform.env.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.env.domain.SdFpssR;
import com.yfd.platform.env.mapper.SdFpssRMapper;
import com.yfd.platform.env.service.ISdFpssRService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Date;
/**
* <p>
* 过鱼设施人工数据表 服务实现类
* </p>
*/
@Service
public class SdFpssRServiceImpl extends ServiceImpl<SdFpssRMapper, SdFpssR> implements ISdFpssRService {
@Override
public Page<SdFpssR> queryPageList(Page<SdFpssR> page, String stcd, Integer yr, String ftp) {
LambdaQueryWrapper<SdFpssR> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.hasText(stcd)) {
wrapper.eq(SdFpssR::getStcd, stcd);
}
if (yr != null) {
wrapper.eq(SdFpssR::getYr, yr);
}
if (StringUtils.hasText(ftp)) {
wrapper.like(SdFpssR::getFtp, ftp);
}
wrapper.eq(SdFpssR::getIsDeleted, 0);
wrapper.orderByDesc(SdFpssR::getRecordTime);
return page(page, wrapper);
}
@Override
public boolean save(SdFpssR entity) {
entity.setRecordTime(new Date());
entity.setIsDeleted(0);
return super.save(entity);
}
@Override
public boolean updateById(SdFpssR entity) {
entity.setModifyTime(new Date());
return super.updateById(entity);
}
// @Override
// public boolean removeById(Object id) {
// SdFpssR entity = getById(id);
// if (entity != null) {
// entity.setIsDeleted(1);
// entity.setDeleteTime(new Date());
// return updateById(entity);
// }
// return false;
// }
}

View File

@ -33,6 +33,8 @@ public class SdHbrvDicServiceImpl extends ServiceImpl<SdHbrvDicMapper, SdHbrvDic
@Resource
private SdEngInfoBHMapper engInfoBHMapper;
private SdHbrvDicMapper hbrvDicMapper;
@Override
public Page<SdHbrvDic> queryPageList(Page<SdHbrvDic> page, String hbrvnm, String baseid) {
return this.page(page, this.lambdaQuery()
@ -109,6 +111,8 @@ public class SdHbrvDicServiceImpl extends ServiceImpl<SdHbrvDicMapper, SdHbrvDic
} else {
return new ArrayList<>();
}
}else if (!"admin".equals(SecurityUtils.getCurrentUsername())){
return new ArrayList<>();
}
wrapper.like(hbrvnm != null && !hbrvnm.isEmpty(), SdHbrvDic::getHbrvnm, hbrvnm)
.eq(baseid != null && !baseid.isEmpty(), SdHbrvDic::getBaseid, baseid)
@ -131,16 +135,36 @@ public class SdHbrvDicServiceImpl extends ServiceImpl<SdHbrvDicMapper, SdHbrvDic
}
Set<String> stationCodes = new HashSet<>();
List<String> basinCodes = new ArrayList<>();
Set<String> basinCodes = new HashSet<>();
for (SysUserDataScope scope : sysUserDataScopes) {
String orgType = scope.getOrgType();
String orgId = scope.getOrgId();
if ("STATION".equals(orgType)) {
stationCodes.add(orgId);
SdEngInfoBH station = engInfoBHMapper.selectById(orgId);
if (station != null) {
if (station.getHbrvcd() != null) {
basinCodes.add(station.getHbrvcd());
}
if (station.getStcd() != null) {
stationCodes.add(station.getStcd());
}
}
} else if ("HBRVCD".equals(orgType)) {
basinCodes.add(orgId);
List<SdEngInfoBH> stationList = engInfoBHMapper.selectByHbrvcd(orgId);
if (stationList != null) {
for (SdEngInfoBH station : stationList) {
if (station.getStcd() != null) {
stationCodes.add(station.getStcd());
}
if (station.getEnnm() != null) {
basinCodes.add(station.getHbrvcd());
}
}
}
}
}

View File

@ -87,6 +87,8 @@ public class SdHydrobaseServiceImpl extends ServiceImpl<SdHydrobaseMapper, SdHyd
} else {
return new ArrayList<>();
}
}else if (!"admin".equals(SecurityUtils.getCurrentUsername())){
return new ArrayList<>();
}
// else {
// return new ArrayList<>();
@ -109,16 +111,36 @@ public class SdHydrobaseServiceImpl extends ServiceImpl<SdHydrobaseMapper, SdHyd
}
Set<String> stationCodes = new HashSet<>();
List<String> basinCodes = new ArrayList<>();
Set<String> basinCodes = new HashSet<>();
for (SysUserDataScope scope : sysUserDataScopes) {
String orgType = scope.getOrgType();
String orgId = scope.getOrgId();
if ("STATION".equals(orgType)) {
stationCodes.add(orgId);
SdEngInfoBH station = sdEngInfoBHMapper.selectById(orgId);
if (station != null) {
if (station.getHbrvcd() != null) {
basinCodes.add(station.getHbrvcd());
}
if (station.getStcd() != null) {
stationCodes.add(station.getStcd());
}
}
} else if ("HBRVCD".equals(orgType)) {
basinCodes.add(orgId);
List<SdEngInfoBH> stationList = sdEngInfoBHMapper.selectByHbrvcd(orgId);
if (stationList != null) {
for (SdEngInfoBH station : stationList) {
if (station.getStcd() != null) {
stationCodes.add(station.getStcd());
}
if (station.getEnnm() != null) {
basinCodes.add(station.getHbrvcd());
}
}
}
}
}

View File

@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.wf.captcha.base.Captcha;
import com.yfd.platform.annotation.Log;
@ -97,9 +98,18 @@ public class LoginController {
}
LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
Integer status = loginUser.getUser().getStatus();
String regStatus = loginUser.getUser().getRegStatus();
if ("0".equals(status.toString())) {
return ResponseResult.error("账号已停用");
}
if ("PENDING".equals(regStatus)) {
return ResponseResult.error("账号待审核,请联系管理员");
}
if ("REJECTED".equals(regStatus)) {
return ResponseResult.error("账号审核未通过");
}
HttpServletRequest request = RequestHolder.getHttpServletRequest();
SysLog sysLog = new SysLog();
sysLog.setUsercode(user.getUsername());
@ -190,7 +200,7 @@ public class LoginController {
}
@Log(module = "用户登录", value = "更改用户密码")
@GetMapping("/updatePassword")
@PostMapping("/updatePassword")
@Operation(summary = "更改用户密码")
@ResponseBody
public ResponseResult updatePassword(@RequestBody SysUser user) throws Exception {
@ -199,9 +209,13 @@ public class LoginController {
user.getPassword());
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String cryptPassword = passwordEncoder.encode(password);
UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("password", cryptPassword);
updateWrapper.eq("id", user.getId());
// 验证新密码和旧密码是否一致
if (passwordEncoder.matches(password, user.getOldPassword())) {
return ResponseResult.error("新密码不能与旧密码相同");
}
LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(SysUser::getPassword, cryptPassword);
updateWrapper.eq(SysUser::getId, user.getId());
userService.update(updateWrapper);
return ResponseResult.success();
}

View File

@ -167,7 +167,7 @@ public class SmsVerifyCodeController {
user.setBelongingUnit(smsVerifyCodeRequest.getBelongingUnit());
user.setRegTime(new Date());
user.setNickname(smsVerifyCodeRequest.getRealName());
user.setStatus(1);
user.setStatus(0);
user.setOrgid("e90063ced25e3d469860e88d920c082f");
user.setUsertype(1);
user.setUsername(smsVerifyCodeRequest.getUsername());
@ -204,7 +204,7 @@ public class SmsVerifyCodeController {
selectedBasinCodes.addAll(Arrays.asList(hbrvcdCode.split(",")));
}
// Set<String> addedStationCodes = new HashSet<>();
Set<String> addedStationCodes = new HashSet<>();
for (String basinCode : selectedBasinCodes) {
if (StringUtils.isEmpty(basinCode)) {
@ -241,7 +241,7 @@ public class SmsVerifyCodeController {
scope.setStatus(1);
scope.setPermissionType("READ");
sysUserDataScopeService.addDataScope(scope);
// addedStationCodes.add(basinCode);
addedStationCodes.add(basinCode);
} else {
Set<String> stationsInBasinAndSelected = allStationCodesInBasin.stream()
.filter(selectedStationCodes::contains)
@ -255,27 +255,27 @@ public class SmsVerifyCodeController {
scope.setStatus(1);
scope.setPermissionType("READ");
sysUserDataScopeService.addDataScope(scope);
// addedStationCodes.add(stationCd);
addedStationCodes.add(stationCd);
}
}
}
// Set<String> standaloneStations = selectedStationCodes.stream()
// .filter(code -> !addedStationCodes.contains(code))
// .collect(Collectors.toSet());
//
// for (String stationCd : standaloneStations) {
// if (StringUtils.isEmpty(stationCd)) {
// continue;
// }
// SysUserDataScope scope = new SysUserDataScope();
// scope.setUserId(userId);
// scope.setOrgType("STATION");
// scope.setOrgId(stationCd);
// scope.setStatus(1);
// scope.setPermissionType("READ");
// sysUserDataScopeService.addDataScope(scope);
// }
Set<String> standaloneStations = selectedStationCodes.stream()
.filter(code -> !addedStationCodes.contains(code))
.collect(Collectors.toSet());
for (String stationCd : standaloneStations) {
if (StringUtils.isEmpty(stationCd)) {
continue;
}
SysUserDataScope scope = new SysUserDataScope();
scope.setUserId(userId);
scope.setOrgType("STATION");
scope.setOrgId(stationCd);
scope.setStatus(1);
scope.setPermissionType("READ");
sysUserDataScopeService.addDataScope(scope);
}
SysUser user = new SysUser();
user.setId(userId);
userService.updateUserRoles( user,"c13481a486c9ee559cf305284df4d207");
@ -316,12 +316,9 @@ public class SmsVerifyCodeController {
} catch (Exception e) {
return ResponseResult.error("密码解密失败");
}
String encodePassword = existUser.getPassword();
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encryptedPassword = passwordEncoder.encode(password);
if (passwordEncoder.matches(password, encodePassword)) {
return ResponseResult.error("新密码不能与旧密码相同");
}
boolean success = userService.updatePasswordByPhone(phone, encryptedPassword);
if (success) {
return ResponseResult.success();

View File

@ -214,7 +214,7 @@ public class UserController {
}
if (StrUtil.isBlank(auditStatus) || ( !"APPROVED".equals(auditStatus)&&!"REJECTED".equals(auditStatus))) {
return ResponseResult.error("审核状态错误1-通过 2-驳回");
return ResponseResult.error("审核状态错误");
}
SysUser user = userService.getById(userId);
if (user == null) {

View File

@ -155,6 +155,12 @@ public class SysUser implements Serializable {
*/
private String companyCode;
@TableField(exist = false)
/**
* 登录密码加密存储
*/
private String oldPassword;
@TableField(exist = false)
List<SysRole> roles;
}

View File

@ -35,9 +35,9 @@ public class UserDetailsServiceImpl implements UserDetailsService {
@Override
@DataSource(name = "master")
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//根据用户名称查询用户信息
//根据用户名称或手机号查询用户信息
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", username);
queryWrapper.and(wrapper -> wrapper.eq("username", username).or().eq("phone", username));
SysUser user = userService.getOne(queryWrapper);
if (ObjectUtil.isEmpty(user)) {
throw new RuntimeException("用户账号不存在!");

View File

@ -10,12 +10,12 @@ spring:
druid:
master:
driverClassName: oracle.jdbc.OracleDriver
url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}"
username: "${DB_MASTER_USERNAME:QGC_REFA}"
password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}"
slave:
driverClassName: oracle.jdbc.OracleDriver
url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}"
username: "${DB_SLAVE_USERNAME:QGC_REFA}"
password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}"
@ -27,8 +27,8 @@ spring:
matching-strategy: ant_path_matcher
servlet:
multipart:
max-file-size: 30MB
max-request-size: 100MB
max-file-size: 300MB
max-request-size: 500MB
logging:
file:
@ -117,3 +117,11 @@ task:
keep-alive-seconds: 60
# 队列容量
queue-capacity: 50
attachment:
token: ${ATTACHMENT_TOKEN:qgcBkod25ngBa4wu8BtfCPYsJ7lQGVDoexH}
upload-url: ${ATTACHMENT_UPLOAD_URL:http://172.16.31.185:18200/upload}
video-url: ${ATTACHMENT_VIDEO_URL:http://172.16.31.185:18200/upload}
delete-url: ${ATTACHMENT_DELETE_URL:http://172.16.31.185:18200/delete}
# upload-url: ${ATTACHMENT_UPLOAD_URL:https://211.99.26.225:12125/upload}
# video-url: ${ATTACHMENT_VIDEO_URL:https://211.99.26.225:12125/upload}

View File

@ -27,8 +27,8 @@ spring:
matching-strategy: ant_path_matcher
servlet:
multipart:
max-file-size: 30MB
max-request-size: 100MB
max-file-size: 300MB
max-request-size: 500MB
logging:
file:
@ -36,7 +36,7 @@ logging:
level:
root: info
com.yfd.platform: info
com.yfd.platform.*.mapper: trace
# com.yfd.platform.*.mapper: trace
# 在线文档: swagger-ui生产环境建议关闭
swagger-ui:
@ -117,3 +117,9 @@ task:
keep-alive-seconds: 60
# 队列容量
queue-capacity: 50
attachment:
token: ${ATTACHMENT_TOKEN:qgcBkod25ngBa4wu8BtfCPYsJ7lQGVDoexH}
upload-url: ${ATTACHMENT_UPLOAD_URL:http://172.16.31.185:18200/upload}
video-url: ${ATTACHMENT_VIDEO_URL:http://172.16.31.185:18200/upload}
delete-url: ${ATTACHMENT_DELETE_URL:http://172.16.31.185:18200/delete}

View File

@ -40,5 +40,3 @@ springdoc:
path: /swagger-ui.html
packages-to-scan: com.yfd.platform
attachment:
token: ${ATTACHMENT_TOKEN:qgcBkod25ngBa4wu8BtfCPYsJ7lQGVDoexH}

View File

@ -78,7 +78,7 @@
<result column="RVCD" property="rvcd"/>
<result column="LGTD" property="lgtd"/>
<result column="LTTD" property="lttd"/>
<result column="ORDER_INDEX" property="orderIndex"/>
<result column="ROW_INDEX" property="rowIndex"/>
</resultMap>
<sql id="joinColumns">
@ -123,7 +123,8 @@
E.RVCD,
E.LGTD,
E.LTTD,
E.ORDER_INDEX
E.ORDER_INDEX,
D.ROW_INDEX
</sql>
<select id="selectJoinPage" resultMap="JoinResultMap">
@ -160,13 +161,16 @@
<if test="status != null and status != ''">
AND D.STATUS = #{status}
</if>
<if test="approvalId != null and approvalId != ''">
AND D.APPROVAL_ID = #{approvalId}
</if>
<if test="startTime != null and startTime != ''">
AND D.TM &gt;= TO_DATE(#{startTime}, 'yyyy-mm-dd hh24:mi:ss')
AND D.STRDT &gt;= TO_DATE(#{startTime}, 'yyyy-mm-dd hh24:mi:ss')
</if>
<if test="endTime != null and endTime != ''">
AND D.TM &lt;= TO_DATE(#{endTime}, 'yyyy-mm-dd hh24:mi:ss')
AND D.STRDT &lt;= TO_DATE(#{endTime}, 'yyyy-mm-dd hh24:mi:ss')
</if>
ORDER BY D.CREATED_AT DESC
ORDER BY D.TM DESC, D.ROW_INDEX ASC
</select>
<select id="selectJoinList" resultMap="JoinResultMap">

View File

@ -67,8 +67,8 @@
SELECT * FROM SYS_USER_DATA_SCOPE
WHERE USER_ID = #{userId}
AND STATUS = 1
AND (START_TIME IS NULL OR START_TIME &lt;= SYSDATE)
AND (END_TIME IS NULL OR END_TIME &gt;= SYSDATE)
-- AND (START_TIME IS NULL OR START_TIME &lt;= SYSDATE)
-- AND (END_TIME IS NULL OR END_TIME &gt;= SYSDATE)
ORDER BY CREATED_AT DESC
</select>