Merge branch 'dev-tw'

This commit is contained in:
tangwei 2026-04-22 18:56:13 +08:00
commit 98a7ea956c
34 changed files with 2388 additions and 60 deletions

View File

@ -1,6 +1,7 @@
package com.yfd.platform.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.yfd.platform.utils.SecurityUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
@ -13,6 +14,7 @@ import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* 插入时自动填充
*/
@ -25,6 +27,11 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
// 自动填充更新时间
this.strictInsertFill(metaObject, "updatedAt", Date.class, now);
// 自动填充更新时间
this.strictInsertFill(metaObject, "createdBy", String.class, SecurityUtils.getUserId());
// 自动填充更新时间
this.strictInsertFill(metaObject, "updatedBy", String.class, SecurityUtils.getUserId());
}
/**
@ -34,5 +41,7 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
public void updateFill(MetaObject metaObject) {
// 自动填充更新时间
this.strictUpdateFill(metaObject, "updatedAt", Date.class, new Date());
// 自动填充更新人
this.strictInsertFill(metaObject, "updatedBy", String.class, SecurityUtils.getUserId());
}
}

View File

@ -54,4 +54,6 @@ public class SwaggerConfig {
.packagesToScan("com.yfd.platform.env.controller")
.build();
}
}

View File

@ -5,16 +5,24 @@ import com.yfd.platform.common.DataSourceLoadOptionsBase;
import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.config.ResponseResult;
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.ImportTask;
import com.yfd.platform.data.service.IFishDraftDataService;
import com.yfd.platform.data.service.IFishImportService;
import com.yfd.platform.data.service.IImportTaskService;
import com.yfd.platform.utils.KendoUtil;
import com.yfd.platform.utils.QgcQueryWrapperUtil;
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.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* <p>
@ -29,18 +37,11 @@ public class FishDraftDataController {
@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 stcd,
// @RequestParam(required = false) String status,
// @RequestParam(required = false) String ftp) {
// Page<FishDraftData> page = new Page<>(current, size);
// Page<FishDraftData> result = fishDraftDataService.queryPageList(page, stcd, status, ftp);
// return ResponseResult.successData(result);
// }
@Resource
private IFishImportService fishImportService;
@Resource
private IImportTaskService importTaskService;
@PostMapping("/page")
@Operation(summary = "分页查询过鱼数据")
@ -63,14 +64,14 @@ public class FishDraftDataController {
@GetMapping("/getById")
@Operation(summary = "根据ID查询")
public ResponseResult getById(@RequestParam Long id) {
public ResponseResult getById(@RequestParam String id) {
FishDraftData fishDraftData = fishDraftDataService.getById(id);
return ResponseResult.successData(fishDraftData);
}
@GetMapping("/getByApprovalId")
@Operation(summary = "根据审批批次ID查询")
public ResponseResult getByApprovalId(@RequestParam Long approvalId) {
public ResponseResult getByApprovalId(@RequestParam String approvalId) {
List<FishDraftData> list = fishDraftDataService.getByApprovalId(approvalId);
return ResponseResult.successData(list);
}
@ -105,7 +106,7 @@ public class FishDraftDataController {
@PostMapping("/removeDraft")
@Operation(summary = "删除草稿(软删除)")
public ResponseResult removeDraft(@RequestParam Long id,
public ResponseResult removeDraft(@RequestParam String id,
@RequestParam String operatorId) {
boolean result = fishDraftDataService.removeDraft(id, operatorId);
return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
@ -113,7 +114,7 @@ public class FishDraftDataController {
@PostMapping("/submitDraft")
@Operation(summary = "提交草稿")
public ResponseResult submitDraft(@RequestParam Long id,
public ResponseResult submitDraft(@RequestParam String id,
@RequestParam String operatorId) {
boolean result = fishDraftDataService.submitDraft(id, operatorId);
return result ? ResponseResult.success("提交成功") : ResponseResult.error("提交失败");
@ -121,7 +122,7 @@ public class FishDraftDataController {
@PostMapping("/submitDrafts")
@Operation(summary = "批量提交草稿")
public ResponseResult submitDrafts(@RequestBody List<Long> ids,
public ResponseResult submitDrafts(@RequestBody List<String> ids,
@RequestParam String operatorId) {
boolean result = fishDraftDataService.submitDrafts(ids, operatorId);
return result ? ResponseResult.success("提交成功") : ResponseResult.error("提交失败");
@ -129,14 +130,14 @@ public class FishDraftDataController {
@PostMapping("/lockDraft")
@Operation(summary = "锁定草稿")
public ResponseResult lockDraft(@RequestParam Long id) {
public ResponseResult lockDraft(@RequestParam String id) {
boolean result = fishDraftDataService.lockDraft(id);
return result ? ResponseResult.success("锁定成功") : ResponseResult.error("锁定失败");
}
@PostMapping("/unlockDraft")
@Operation(summary = "解锁草稿")
public ResponseResult unlockDraft(@RequestParam Long id) {
public ResponseResult unlockDraft(@RequestParam String id) {
boolean result = fishDraftDataService.unlockDraft(id);
return result ? ResponseResult.success("解锁成功") : ResponseResult.error("解锁失败");
}
@ -144,8 +145,6 @@ public class FishDraftDataController {
@PostMapping("/add")
@Operation(summary = "新增过鱼数据")
public ResponseResult add(@RequestBody FishDraftData fishDraftData) {
fishDraftData.setCreatedAt(new Date());
fishDraftData.setUpdatedAt(new Date());
boolean result = fishDraftDataService.save(fishDraftData);
return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败");
}
@ -153,15 +152,100 @@ public class FishDraftDataController {
@PostMapping("/update")
@Operation(summary = "修改过鱼数据")
public ResponseResult update(@RequestBody FishDraftData fishDraftData) {
fishDraftData.setUpdatedAt(new Date());
boolean result = fishDraftDataService.updateById(fishDraftData);
return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败");
}
@PostMapping("/delete")
@Operation(summary = "删除过鱼数据")
public ResponseResult delete(@RequestParam Long id) {
public ResponseResult delete(@RequestParam String id) {
boolean result = fishDraftDataService.removeById(id);
return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
}
@PostMapping("/batchDelete")
@Operation(summary = "批量删除过鱼数据")
public ResponseResult batchDelete(@RequestBody List<String> ids) {
boolean result = fishDraftDataService.removeByIds(ids);
return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
}
@PostMapping("/importZip")
@Operation(summary = "导入ZIP过鱼数据每个用户同时只能进行一次导入")
public ResponseResult importZip(@RequestParam("file") MultipartFile file,
@RequestParam String uploadUserId) {
if (file == null || file.isEmpty()) {
return ResponseResult.error("请上传文件");
}
String fileName = file.getOriginalFilename();
if (fileName == null || (!fileName.endsWith(".zip"))) {
return ResponseResult.error("请上传ZIP文件(.zip)");
}
if (importTaskService.hasImportingTask(uploadUserId)) {
return ResponseResult.error("您有正在进行的导入任务,请等待完成后重试");
}
String importNo = "IMP" + System.currentTimeMillis();
String taskId = UUID.randomUUID().toString();
try {
ImportTask task = new ImportTask();
task.setId(taskId);
task.setImportNo(importNo);
task.setBizType("FISH");
task.setFileName(fileName);
task.setFileSize(file.getSize());
task.setStatus("UPLOADED");
task.setUploadUserId(uploadUserId);
task.setUploadTime(new Date());
importTaskService.save(task);
FishImportRequest request = new FishImportRequest();
request.setImportNo(importNo);
request.setUploadUserId(uploadUserId);
request.setBizType("FISH");
FishImportResult result = fishImportService.parseAndMapZip(file, uploadUserId);
importTaskService.updateStatus(taskId, "VALIDATED", null);
importTaskService.updateProgress(taskId, result.getTotalCount(), result.getSuccessCount(), result.getFailedCount());
return ResponseResult.successData(result);
} catch (Exception e) {
importTaskService.markFailed(taskId, "导入失败: " + e.getMessage());
return ResponseResult.error("导入失败: " + e.getMessage());
}
}
@PostMapping("/cancelImport")
@Operation(summary = "取消导入任务")
public ResponseResult cancelImport(@RequestParam String taskId,
@RequestParam String operatorId) {
boolean result = importTaskService.cancelTask(taskId, operatorId);
return result ? ResponseResult.success("取消成功") : ResponseResult.error("取消失败");
}
@GetMapping("/checkImportStatus")
@Operation(summary = "检查用户导入状态")
public ResponseResult checkImportStatus(@RequestParam String uploadUserId) {
boolean hasTask = importTaskService.hasImportingTask(uploadUserId);
ImportTask currentTask = importTaskService.getCurrentTaskByUserId(uploadUserId);
return ResponseResult.successData(java.util.Map.of(
"hasImportingTask", hasTask,
"currentTask", currentTask
));
}
@PostMapping("/cleanupTemp")
@Operation(summary = "清理临时文件")
public ResponseResult cleanupTemp(@RequestParam String tempDir) {
try {
com.yfd.platform.data.utils.ZipFileUtil.cleanupTempDir(tempDir);
return ResponseResult.success("清理成功");
} catch (Exception e) {
return ResponseResult.error("清理失败: " + e.getMessage());
}
}
}

View File

@ -41,6 +41,7 @@ public class FishDraftData implements Serializable {
*/
private String ftp;
/**
* 鱼类全长
*/
@ -125,28 +126,10 @@ public class FishDraftData implements Serializable {
/**
* 水温
*/
@TableField(exist = false)
// @TableField(exist = false)
private BigDecimal wt;
/**
* 电站名称
*/
@TableField(exist = false)
private String engName;
/**
* 基地名称
*/
@TableField(exist = false)
private String baseName;
/**
* 设施名称
*/
@TableField(exist = false)
private String fPname;
/**
* 审批完成时间
@ -177,6 +160,7 @@ public class FishDraftData implements Serializable {
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
private String createdBy;
/**
@ -188,5 +172,44 @@ public class FishDraftData implements Serializable {
/**
* 更新人
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updatedBy;
/**
* 所属基地编码
*/
@TableField(exist = false)
private String baseId;
/**
* 电站名称
*/
@TableField(exist = false)
private String engName;
/**
* 基地名称
*/
@TableField(exist = false)
private String baseName;
/**
* 流域编码
*/
@TableField(exist = false)
private String rvcd;
/**
* 设施名称
*/
@TableField(exist = false)
private String fpname;
/**
* 鱼类名称
*/
@TableField(exist = false)
private String ftpName;
}

View File

@ -0,0 +1,20 @@
package com.yfd.platform.data.domain;
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
@Data
public class FishImportRequest implements Serializable {
private String filePath;
private String importNo;
private String bizType = "FISH";
private String uploadUserId;
private Map<String, String> columnMapping;
}

View File

@ -0,0 +1,47 @@
package com.yfd.platform.data.domain;
import lombok.Data;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Data
public class FishImportResult {
private List<FishImportRow> successRows;
private List<FishImportRow> failedRows;
private List<String> unrecognizedFields;
private Map<String, String> imageFiles;
private Map<String, String> videoFiles;
private String tempDir;
private String excelFileName;
private String excelFilePath;
private int totalCount;
private int successCount;
private int failedCount;
private String summary;
public FishImportResult() {
this.successRows = new ArrayList<>();
this.failedRows = new ArrayList<>();
this.unrecognizedFields = new ArrayList<>();
this.imageFiles = new LinkedHashMap<>();
this.videoFiles = new LinkedHashMap<>();
}
@Data
public static class FishImportRow {
private int rowIndex;
private FishDraftData data;
private List<String> unrecognizedFields;
private List<String> warnings;
public FishImportRow(int rowIndex) {
this.rowIndex = rowIndex;
this.unrecognizedFields = new ArrayList<>();
this.warnings = new ArrayList<>();
}
}
}

View File

@ -83,7 +83,7 @@ public class ImportTask implements Serializable {
/**
* 上传人ID
*/
private Long uploadUserId;
private String uploadUserId;
/**
* 上传时间

View File

@ -18,7 +18,7 @@ public interface FishDraftDataMapper extends BaseMapper<FishDraftData> {
* 根据审批批次ID查询草稿数据
*/
@Select("SELECT * FROM FISH_DRAFT_DATA WHERE APPROVAL_ID = #{approvalId} ORDER BY TM DESC")
List<FishDraftData> selectByApprovalId(@Param("approvalId") Long approvalId);
List<FishDraftData> selectByApprovalId(@Param("approvalId") String approvalId);
/**
* 根据状态查询草稿数据

View File

@ -36,7 +36,17 @@ 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") Long uploadUserId);
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);
/**
* 查询过期的任务

View File

@ -21,7 +21,7 @@ public interface IFishDraftDataService extends IService<FishDraftData> {
/**
* 根据审批批次ID查询
*/
List<FishDraftData> getByApprovalId(Long approvalId);
List<FishDraftData> getByApprovalId(String approvalId);
/**
* 根据状态查询
@ -46,25 +46,25 @@ public interface IFishDraftDataService extends IService<FishDraftData> {
/**
* 删除草稿软删除
*/
boolean removeDraft(Long id, String operatorId);
boolean removeDraft(String id, String operatorId);
/**
* 提交草稿
*/
boolean submitDraft(Long id, String operatorId);
boolean submitDraft(String id, String operatorId);
/**
* 批量提交草稿
*/
boolean submitDrafts(List<Long> ids, String operatorId);
boolean submitDrafts(List<String> ids, String operatorId);
/**
* 锁定草稿
*/
boolean lockDraft(Long id);
boolean lockDraft(String id);
/**
* 解锁草稿
*/
boolean unlockDraft(Long id);
boolean unlockDraft(String id);
}

View File

@ -0,0 +1,21 @@
package com.yfd.platform.data.service;
import com.yfd.platform.data.domain.FishImportRequest;
import com.yfd.platform.data.domain.FishImportResult;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
/**
* <p>
* 过鱼数据Excel导入服务接口
* </p>
*/
public interface IFishImportService {
FishImportResult parseAndMapExcel(FishImportRequest request, InputStream inputStream);
FishImportResult parseAndMapExcelFromPath(FishImportRequest request);
FishImportResult parseAndMapZip(MultipartFile file, String uploadUserId);
}

View File

@ -0,0 +1,40 @@
package com.yfd.platform.data.service;
import com.yfd.platform.data.domain.FishImportResult;
import java.io.InputStream;
/**
* <p>
* 过鱼数据ZIP导入服务接口
* </p>
*/
public interface IFishZipImportService {
/**
* 解析过鱼数据ZIP文件并映射字段
*
* @param importTaskId 导入任务ID
* @param inputStream ZIP文件输入流
* @param uploadUserId 上传用户ID
* @return 解析结果
*/
FishImportResult parseAndMapZip(String importTaskId, InputStream inputStream, String uploadUserId);
/**
* 检查用户是否有正在进行的导入任务
*
* @param uploadUserId 上传用户ID
* @return true表示有任务在进行false表示可以开始新任务
*/
boolean hasImportingTask(String uploadUserId);
/**
* 取消导入任务
*
* @param importTaskId 任务ID
* @param operatorId 操作人ID
* @return 是否成功
*/
boolean cancelImportTask(String importTaskId, String operatorId);
}

View File

@ -62,4 +62,19 @@ public interface IImportTaskService extends IService<ImportTask> {
* 删除过期任务
*/
boolean deleteExpiredTasks();
/**
* 检查用户是否有正在进行的导入任务
*/
boolean hasImportingTask(String uploadUserId);
/**
* 取消导入任务
*/
boolean cancelTask(String taskId, String operatorId);
/**
* 获取用户当前正在进行的导入任务
*/
ImportTask getCurrentTaskByUserId(String uploadUserId);
}

View File

@ -44,7 +44,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
}
@Override
public List<FishDraftData> getByApprovalId(Long approvalId) {
public List<FishDraftData> getByApprovalId(String approvalId) {
return fishDraftDataMapper.selectByApprovalId(approvalId);
}
@ -83,7 +83,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
@Override
@Transactional(rollbackFor = Exception.class)
public boolean removeDraft(Long id, String operatorId) {
public boolean removeDraft(String id, String operatorId) {
FishDraftData fishDraftData = this.getById(id);
if (fishDraftData == null || fishDraftData.getLockFlag() == 1) {
return false;
@ -97,7 +97,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
@Override
@Transactional(rollbackFor = Exception.class)
public boolean submitDraft(Long id, String operatorId) {
public boolean submitDraft(String id, String operatorId) {
FishDraftData fishDraftData = this.getById(id);
if (fishDraftData == null || fishDraftData.getLockFlag() == 1) {
return false;
@ -110,8 +110,8 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
@Override
@Transactional(rollbackFor = Exception.class)
public boolean submitDrafts(List<Long> ids, String operatorId) {
for (Long id : ids) {
public boolean submitDrafts(List<String> ids, String operatorId) {
for (String id : ids) {
FishDraftData fishDraftData = this.getById(id);
if (fishDraftData != null && fishDraftData.getLockFlag() == 0) {
fishDraftData.setStatus("SUBMITTED");
@ -125,7 +125,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
@Override
@Transactional(rollbackFor = Exception.class)
public boolean lockDraft(Long id) {
public boolean lockDraft(String id) {
FishDraftData fishDraftData = this.getById(id);
if (fishDraftData == null) {
return false;
@ -137,7 +137,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl<FishDraftDataMapper, F
@Override
@Transactional(rollbackFor = Exception.class)
public boolean unlockDraft(Long id) {
public boolean unlockDraft(String id) {
FishDraftData fishDraftData = this.getById(id);
if (fishDraftData == null) {
return false;

View File

@ -0,0 +1,737 @@
package com.yfd.platform.data.service.impl;
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.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.domain.SysDictionary;
import com.yfd.platform.system.domain.SysDictionaryItems;
import com.yfd.platform.system.service.ISysDictionaryItemsService;
import com.yfd.platform.system.service.ISysDictionaryService;
import jakarta.annotation.Resource;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class FishImportServiceImpl implements IFishImportService {
@Resource
private SdEngInfoBHMapper engInfoBHMapper;
@Resource
private SdHydrobaseMapper hydrobaseMapper;
@Resource
private SdRvcdDicMapper rvcdDicMapper;
@Resource
private SdFpssBHMapper fpssBHMapper;
@Resource
private SdFishDictoryBMapper fishDictoryBMapper;
@Resource
private ISysDictionaryService sysDictionaryService;
@Resource
private ISysDictionaryItemsService sysDictionaryItemsService;
private static final Map<String, String> EXCEL_COLUMN_MAPPING = new LinkedHashMap<>();
private static final Map<Integer, String> EXCEL_COLUMN_INDEX_MAPPING = new LinkedHashMap<>();
private static final Map<String, String> STATION_NAME_CACHE = new LinkedHashMap<>();
private static final Map<String, String> BASE_NAME_CACHE = new LinkedHashMap<>();
private static final Map<String, String> RIVER_NAME_CACHE = new LinkedHashMap<>();
private static final Map<String, String> FISH_DICT_CACHE = new LinkedHashMap<>();
private static final Map<String, String> FPSS_BH_CACHE = new LinkedHashMap<>();
private static final Map<String, String> DIRECTION_DICT_CACHE = new LinkedHashMap<>();
private static final Map<String, String> ISFS_DICT_CACHE = new LinkedHashMap<>();
private static final String DICT_CODE_FISH = "FISH_TYPE";
private static final String DICT_CODE_DIRECTION = "FISH_DIRECTION";
private static final String DICT_CODE_ISFS = "YES_NO";
static {
EXCEL_COLUMN_MAPPING.put("电站名称", "stcd");
EXCEL_COLUMN_MAPPING.put("基地名称", "baseId");
EXCEL_COLUMN_MAPPING.put("流域名称", "rvcd");
EXCEL_COLUMN_MAPPING.put("数据时间", "tm");
EXCEL_COLUMN_MAPPING.put("过鱼时间", "tm");
EXCEL_COLUMN_MAPPING.put("鱼类", "ftp");
EXCEL_COLUMN_MAPPING.put("鱼种类", "ftp");
EXCEL_COLUMN_MAPPING.put("鱼类全长", "fsz");
EXCEL_COLUMN_MAPPING.put("过鱼数量", "fcnt");
EXCEL_COLUMN_MAPPING.put("过鱼数量(尾)", "fcnt");
EXCEL_COLUMN_MAPPING.put("平均体重", "fwet");
EXCEL_COLUMN_MAPPING.put("开始日期", "strdt");
EXCEL_COLUMN_MAPPING.put("结束日期", "enddt");
EXCEL_COLUMN_MAPPING.put("游向", "direction");
EXCEL_COLUMN_MAPPING.put("水温", "wt");
EXCEL_COLUMN_MAPPING.put("年份", "yr");
EXCEL_COLUMN_MAPPING.put("月份", "mouth");
EXCEL_COLUMN_MAPPING.put("过鱼视频文件路径", "vdpth");
EXCEL_COLUMN_MAPPING.put("图片文件路径", "picpth");
EXCEL_COLUMN_MAPPING.put("是否鱼苗", "isfs");
EXCEL_COLUMN_MAPPING.put("数据来源", "sourceType");
EXCEL_COLUMN_MAPPING.put("过鱼设施名称", "fpname");
EXCEL_COLUMN_INDEX_MAPPING.put(0, "baseName");
EXCEL_COLUMN_INDEX_MAPPING.put(1, "stationName");
EXCEL_COLUMN_INDEX_MAPPING.put(2, "fpname");
EXCEL_COLUMN_INDEX_MAPPING.put(3, "tm");
EXCEL_COLUMN_INDEX_MAPPING.put(4, "ftp");
EXCEL_COLUMN_INDEX_MAPPING.put(5, "isfs");
EXCEL_COLUMN_INDEX_MAPPING.put(6, "direction");
EXCEL_COLUMN_INDEX_MAPPING.put(7, "fcnt");
EXCEL_COLUMN_INDEX_MAPPING.put(8, "fsz");
EXCEL_COLUMN_INDEX_MAPPING.put(9, "fwet");
EXCEL_COLUMN_INDEX_MAPPING.put(10, "wt");
}
@Override
public FishImportResult parseAndMapExcel(FishImportRequest request, InputStream inputStream) {
FishImportResult result = new FishImportResult();
try (Workbook workbook = new XSSFWorkbook(inputStream)) {
Sheet sheet = workbook.getSheetAt(0);
return parseSheet(sheet, result);
} catch (IOException e) {
result.setSummary("Excel文件解析失败: " + e.getMessage());
return result;
}
}
@Override
public FishImportResult parseAndMapExcelFromPath(FishImportRequest request) {
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);
} catch (IOException e) {
result.setSummary("读取文件失败: " + e.getMessage());
return result;
}
}
private FishImportResult parseSheet(Sheet sheet, FishImportResult result) {
loadStationAndBaseCache();
Row headerRow = sheet.getRow(0);
if (headerRow == null) {
result.setSummary("Excel文件没有表头");
return result;
}
List<String> unrecognizedHeaders = new ArrayList<>();
Map<Integer, String> columnIndexMap = new HashMap<>(EXCEL_COLUMN_INDEX_MAPPING);
int totalRows = sheet.getLastRowNum();
result.setTotalCount(totalRows);
for (int i = 1; i <= totalRows; i++) {
Row row = sheet.getRow(i);
if (row == null || isRowEmpty(row)) {
continue;
}
FishImportResult.FishImportRow importRow = parseRow(row, columnIndexMap, i);
if (importRow.getData() != null && importRow.getWarnings().isEmpty()) {
result.getSuccessRows().add(importRow);
result.setSuccessCount(result.getSuccessCount() + 1);
} else {
result.getFailedRows().add(importRow);
result.setFailedCount(result.getFailedCount() + 1);
}
}
result.setSummary(String.format("共解析%d条数据成功%d条失败%d条未识别字段%s",
result.getTotalCount(), result.getSuccessCount(), result.getFailedCount(),
unrecognizedHeaders.isEmpty() ? "" : String.join(", ", unrecognizedHeaders)));
return result;
}
private FishImportResult.FishImportRow parseRow(Row row, Map<Integer, String> columnIndexMap, int rowIndex) {
FishImportResult.FishImportRow importRow = new FishImportResult.FishImportRow(rowIndex);
FishDraftData data = new FishDraftData();
data.setId(UUID.randomUUID().toString());
List<String> missingRequiredFields = new ArrayList<>();
for (Map.Entry<Integer, String> entry : columnIndexMap.entrySet()) {
Integer columnIndex = entry.getKey();
String fieldName = entry.getValue();
Cell cell = row.getCell(columnIndex);
String cellValue = getCellStringValue(cell);
try {
switch (fieldName) {
case "stationName":
if (!StringUtils.hasText(cellValue)) {
missingRequiredFields.add("电站名称");
} else {
String stcd = resolveStationCode(cellValue.trim());
if (stcd == null) {
importRow.getWarnings().add(fieldName);
data.setEngName(cellValue.trim());
} else {
data.setEngName(cellValue.trim());
}
}
break;
case "baseName":
if (!StringUtils.hasText(cellValue)) {
missingRequiredFields.add("水电基地");
} else {
String baseId = resolveBaseCode(cellValue.trim());
if (baseId == null) {
importRow.getWarnings().add(fieldName);
data.setBaseId(cellValue.trim());
data.setBaseName(cellValue.trim());
} else {
data.setBaseId(baseId);
data.setBaseName(cellValue.trim());
}
}
break;
case "rvcd":
if (StringUtils.hasText(cellValue)) {
String rvcd = resolveRiverCode(cellValue.trim());
if (rvcd == null) {
importRow.getWarnings().add(fieldName);
} else {
data.setRvcd(rvcd);
}
}
break;
case "tm":
if (!StringUtils.hasText(cellValue)) {
missingRequiredFields.add("过鱼时间");
} else {
Date tm = parseDate(cellValue);
if (tm == null) {
importRow.getWarnings().add("过鱼时间格式错误: " + cellValue);
}
data.setTm(tm);
}
break;
case "ftp":
if (!StringUtils.hasText(cellValue)) {
missingRequiredFields.add("鱼种类");
} else {
String stcd = resolveFishDictCode(cellValue.trim());
if (stcd == null) {
importRow.getWarnings().add(fieldName);
data.setFtp(cellValue.trim());
data.setFtpName(cellValue.trim());
} else {
data.setFtp(stcd);
data.setFtpName(cellValue.trim());
}
}
break;
case "fsz":
data.setFsz(cellValue.trim());
break;
case "fcnt":
if (!StringUtils.hasText(cellValue)) {
missingRequiredFields.add("过鱼数量");
} else {
Integer fcnt = parseInteger(cellValue);
if (fcnt == null) {
importRow.getWarnings().add(fieldName);
data.setFcnt(parseInteger(cellValue));
}
data.setFcnt(fcnt);
}
break;
case "fwet":
data.setFwet(cellValue.trim());
break;
case "strdt":
data.setStrdt(parseDate(cellValue));
break;
case "enddt":
data.setEnddt(parseDate(cellValue));
break;
case "direction":
if (!StringUtils.hasText(cellValue)) {
missingRequiredFields.add("游向");
} else {
String direction = resolveDirection(cellValue.trim(), importRow);
data.setDirection(direction);
}
break;
case "yr":
data.setYr(parseInteger(cellValue));
break;
case "mouth":
data.setMouth(parseInteger(cellValue));
break;
case "vdpth":
data.setVdpth(cellValue.trim());
break;
case "picpth":
data.setPicpth(cellValue.trim());
break;
case "isfs":
if (StringUtils.hasText(cellValue)) {
String isfs = resolveIsfs(cellValue.trim(), importRow);
data.setIsfs("".equals(isfs) ? 1 : 0);
}
break;
case "sourceType":
data.setSourceType(parseSourceType(cellValue.trim()));
break;
case "fpname":
if (!StringUtils.hasText(cellValue)) {
missingRequiredFields.add("过鱼设施名称");
} else {
String stcd = resolveFpssCode(cellValue.trim());
if (stcd == null) {
importRow.getWarnings().add(fieldName);
data.setStcd(cellValue.trim());
data.setFpname(cellValue.trim());
} else {
data.setFpname(stcd);
data.setStcd(stcd);
}
}
break;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
// importRow.getWarnings().add("字段[" + fieldName + "]解析异常: " + e.getMessage());
}
}
importRow.setData(data);
return importRow;
}
private void loadStationAndBaseCache() {
if (STATION_NAME_CACHE.isEmpty()) {
List<SdEngInfoBH> stationList = engInfoBHMapper.selectList(null);
for (SdEngInfoBH station : stationList) {
if (StringUtils.hasText(station.getEnnm())) {
STATION_NAME_CACHE.put(station.getEnnm().trim().toLowerCase(), station.getStcd());
}
if (StringUtils.hasText(station.getStcd())) {
STATION_NAME_CACHE.put(station.getStcd().trim().toLowerCase(), station.getStcd());
}
}
}
if (BASE_NAME_CACHE.isEmpty()) {
List<SdHydrobase> baseList = hydrobaseMapper.selectList(null);
for (SdHydrobase base : baseList) {
if (StringUtils.hasText(base.getBasename())) {
BASE_NAME_CACHE.put(base.getBasename().trim().toLowerCase(), base.getBaseid());
}
if (StringUtils.hasText(base.getBaseid())) {
BASE_NAME_CACHE.put(base.getBaseid().trim().toLowerCase(), base.getBaseid());
}
}
}
if (RIVER_NAME_CACHE.isEmpty()) {
List<SdRvcdDic> riverList = rvcdDicMapper.selectList(null);
for (SdRvcdDic river : riverList) {
if (StringUtils.hasText(river.getRvnm())) {
RIVER_NAME_CACHE.put(river.getRvnm().trim().toLowerCase(), river.getRvcd());
}
if (StringUtils.hasText(river.getRvcd())) {
RIVER_NAME_CACHE.put(river.getRvcd().trim().toLowerCase(), river.getRvcd());
}
}
}
if (FISH_DICT_CACHE.isEmpty()) {
List<SdFishDictoryB> sdFishDictoryBS = fishDictoryBMapper.selectList(null);
for (SdFishDictoryB fishDictoryB : sdFishDictoryBS) {
if (StringUtils.hasText(fishDictoryB.getName())) {
FISH_DICT_CACHE.put(fishDictoryB.getName().trim().toLowerCase(), fishDictoryB.getCode());
}
if (StringUtils.hasText(fishDictoryB.getCode())) {
FISH_DICT_CACHE.put(fishDictoryB.getCode().trim().toLowerCase(), fishDictoryB.getCode());
}
}
}
if (FPSS_BH_CACHE.isEmpty()) {
List<SdFpssBH> sdFpssBHS = fpssBHMapper.selectList(null);
for (SdFpssBH sdFpssBH : sdFpssBHS) {
if (StringUtils.hasText(sdFpssBH.getStnm())) {
FPSS_BH_CACHE.put(sdFpssBH.getStnm().trim().toLowerCase(), sdFpssBH.getStcd());
}
if (StringUtils.hasText(sdFpssBH.getStcd())) {
FPSS_BH_CACHE.put(sdFpssBH.getStcd().trim().toLowerCase(), sdFpssBH.getStcd());
}
}
}
}
private String resolveStationCode(String stationName) {
if (stationName == null) {
return null;
}
String lowerName = stationName.toLowerCase().trim();
if (STATION_NAME_CACHE.containsKey(lowerName)) {
return STATION_NAME_CACHE.get(lowerName);
}
for (Map.Entry<String, String> entry : STATION_NAME_CACHE.entrySet()) {
if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) {
return entry.getValue();
}
}
return null;
}
private String resolveFpssCode(String name) {
if (name == null) {
return null;
}
String lowerName = name.toLowerCase().trim();
if (FPSS_BH_CACHE.containsKey(lowerName)) {
return FPSS_BH_CACHE.get(lowerName);
}
for (Map.Entry<String, String> entry : FPSS_BH_CACHE.entrySet()) {
if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) {
return entry.getValue();
}
}
return null;
}
private String resolveFishDictCode(String name) {
if (name == null) {
return null;
}
String lowerName = name.toLowerCase().trim();
if (FISH_DICT_CACHE.containsKey(lowerName)) {
return FISH_DICT_CACHE.get(lowerName);
}
for (Map.Entry<String, String> entry : FISH_DICT_CACHE.entrySet()) {
if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) {
return entry.getValue();
}
}
return null;
}
private String resolveBaseCode(String baseName) {
if (baseName == null) {
return null;
}
String lowerName = baseName.toLowerCase().trim();
if (BASE_NAME_CACHE.containsKey(lowerName)) {
return BASE_NAME_CACHE.get(lowerName);
}
for (Map.Entry<String, String> entry : BASE_NAME_CACHE.entrySet()) {
if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) {
return entry.getValue();
}
}
return null;
}
private String resolveRiverCode(String riverName) {
if (riverName == null) {
return null;
}
String lowerName = riverName.toLowerCase().trim();
if (RIVER_NAME_CACHE.containsKey(lowerName)) {
return RIVER_NAME_CACHE.get(lowerName);
}
for (Map.Entry<String, String> entry : RIVER_NAME_CACHE.entrySet()) {
if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) {
return entry.getValue();
}
}
return null;
}
private String validateFishType(String fishName, FishImportResult.FishImportRow importRow) {
if (fishName == null) {
return null;
}
String lowerName = fishName.toLowerCase().trim();
if (!FISH_DICT_CACHE.isEmpty()) {
if (FISH_DICT_CACHE.containsKey(lowerName)) {
return FISH_DICT_CACHE.get(lowerName);
}
for (Map.Entry<String, String> entry : FISH_DICT_CACHE.entrySet()) {
if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) {
return entry.getValue();
}
}
}
importRow.getWarnings().add("鱼种类【" + fishName + "】未在字典中找到匹配,请手动确认");
return fishName;
}
private String validateFishFacility(String facilityName, FishImportResult.FishImportRow importRow) {
if (facilityName == null) {
return null;
}
String lowerName = facilityName.toLowerCase().trim();
importRow.getWarnings().add("过鱼设施【" + facilityName + "】暂无可用字典验证,请手动确认");
return facilityName;
}
private String resolveDirection(String direction, FishImportResult.FishImportRow importRow) {
if (direction == null) {
return null;
}
String lowerName = direction.toLowerCase().trim();
if (!DIRECTION_DICT_CACHE.isEmpty()) {
if (DIRECTION_DICT_CACHE.containsKey(lowerName)) {
return DIRECTION_DICT_CACHE.get(lowerName);
}
for (Map.Entry<String, String> entry : DIRECTION_DICT_CACHE.entrySet()) {
if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) {
return entry.getValue();
}
}
}
if (lowerName.contains("上行") && lowerName.contains("折返")) {
return "上行折返";
} else if (lowerName.contains("下行") && lowerName.contains("折返")) {
return "下行折返";
} else if (lowerName.contains("上行")) {
return "上行";
} else if (lowerName.contains("下行")) {
return "下行";
}
importRow.getWarnings().add("无法识别的游向: " + direction + ",请手动选择");
return direction;
}
private String resolveIsfs(String value, FishImportResult.FishImportRow importRow) {
if (value == null) {
return null;
}
String lowerName = value.toLowerCase().trim();
if (!ISFS_DICT_CACHE.isEmpty()) {
if (ISFS_DICT_CACHE.containsKey(lowerName)) {
return ISFS_DICT_CACHE.get(lowerName);
}
for (Map.Entry<String, String> entry : ISFS_DICT_CACHE.entrySet()) {
if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) {
return entry.getValue();
}
}
}
if (lowerName.equals("1") || lowerName.equals("") || lowerName.equals("yes") || lowerName.equals("true")) {
return "";
} else if (lowerName.equals("0") || lowerName.equals("") || lowerName.equals("no") || lowerName.equals("false")) {
return "";
}
importRow.getWarnings().add("无法识别的【是否鱼苗】值: " + value + ",将默认设置为【否】");
return "";
}
// private void loadDirectionDict() {
// if (DIRECTION_DICT_CACHE.isEmpty()) {
// try {
// SysDictionary dict = sysDictionaryService.getByDictCode(DICT_CODE_DIRECTION);
// if (dict != null) {
// List<SysDictionaryItems> items = sysDictionaryItemsService.listByDictId(dict.getId());
// for (SysDictionaryItems item : items) {
// if (StringUtils.hasText(item.getItemName())) {
// DIRECTION_DICT_CACHE.put(item.getItemName().trim().toLowerCase(), item.getItemName());
// }
// }
// }
// } catch (Exception e) {
// }
// }
// }
//
// private void loadIsfsDict() {
// if (ISFS_DICT_CACHE.isEmpty()) {
// try {
// SysDictionary dict = sysDictionaryService.getByDictCode(DICT_CODE_ISFS);
// if (dict != null) {
// List<SysDictionaryItems> items = sysDictionaryItemsService.listByDictId(dict.getId());
// for (SysDictionaryItems item : items) {
// if (StringUtils.hasText(item.getItemName())) {
// ISFS_DICT_CACHE.put(item.getItemName().trim().toLowerCase(), item.getItemName());
// }
// }
// }
// } catch (Exception e) {
// }
// }
// }
// private void loadFishDict() {
// if (FISH_DICT_CACHE.isEmpty()) {
// try {
// SysDictionary dict = sysDictionaryService.getByDictCode(DICT_CODE_FISH);
// if (dict != null) {
// List<SysDictionaryItems> items = sysDictionaryItemsService.listByDictId(dict.getId());
// for (SysDictionaryItems item : items) {
// if (StringUtils.hasText(item.getItemName())) {
// FISH_DICT_CACHE.put(item.getItemName().trim().toLowerCase(), item.getItemCode());
// }
// if (StringUtils.hasText(item.getItemCode())) {
// FISH_DICT_CACHE.put(item.getItemCode().trim().toLowerCase(), item.getItemCode());
// }
// }
// }
// } catch (Exception e) {
// }
// }
// }
private String getCellStringValue(Cell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
return cell.getLocalDateTimeCellValue().toString();
}
return String.valueOf((long) cell.getNumericCellValue());
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case FORMULA:
try {
return cell.getStringCellValue();
} catch (Exception e) {
return String.valueOf(cell.getNumericCellValue());
}
default:
return "";
}
}
private boolean isRowEmpty(Row row) {
for (int i = 0; i < row.getLastCellNum(); i++) {
Cell cell = row.getCell(i);
if (cell != null && StringUtils.hasText(getCellStringValue(cell))) {
return false;
}
}
return true;
}
private Date parseDate(String dateStr) {
if (!StringUtils.hasText(dateStr)) {
return null;
}
String[] patterns = {
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd",
"yyyy/MM/dd",
"yyyy.MM.dd",
"yyyyMMdd"
};
for (String pattern : patterns) {
try {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
sdf.setLenient(false);
return sdf.parse(dateStr);
} catch (ParseException ignored) {
}
}
return null;
}
private Integer parseInteger(String value) {
if (!StringUtils.hasText(value)) {
return null;
}
try {
return Integer.parseInt(value.trim());
} catch (NumberFormatException e) {
try {
return (int) Double.parseDouble(value.trim());
} catch (NumberFormatException ex) {
return null;
}
}
}
private String parseSourceType(String value) {
if (!StringUtils.hasText(value)) {
return "IMPORT";
}
String v = value.toLowerCase();
if (v.contains("手工") || v.contains("manual") || v.contains("录入")) {
return "MANUAL";
} else if (v.contains("自动") || v.contains("auto") || v.contains("采集")) {
return "AUTO";
} else if (v.contains("导入") || v.contains("import")) {
return "IMPORT";
}
return "IMPORT";
}
@Override
public FishImportResult parseAndMapZip(MultipartFile file, String uploadUserId) {
FishImportResult result = new FishImportResult();
try {
ZipFileUtil.ZipContent zipContent = ZipFileUtil.extractZipToTemp(file);
if (zipContent.excelFilePath == null) {
result.setSummary("ZIP文件中未找到Excel文件");
ZipFileUtil.cleanupTempDir(zipContent.tempDir);
return result;
}
try (Workbook workbook = new XSSFWorkbook(new FileInputStream(zipContent.excelFilePath))) {
Sheet sheet = workbook.getSheetAt(0);
result = parseSheet(sheet, result);
}
result.setImageFiles(zipContent.images);
result.setVideoFiles(zipContent.videos);
result.setTempDir(zipContent.tempDir);
result.setExcelFileName(zipContent.excelFileName);
result.setExcelFilePath(zipContent.excelFilePath);
result.setSummary(result.getSummary() + String.format("\nZIP内容: 发现%d张图片, %d个视频, 临时目录: %s",
zipContent.images.size(), zipContent.videos.size(), zipContent.tempDir));
return result;
} catch (Exception e) {
result.setSummary("ZIP文件解析失败: " + e.getMessage());
return result;
}
}
}

View File

@ -137,4 +137,38 @@ public class ImportTaskServiceImpl extends ServiceImpl<ImportTaskMapper, ImportT
List<String> ids = expiredTasks.stream().map(ImportTask::getId).toList();
return this.removeByIds(ids);
}
@Override
public boolean hasImportingTask(String uploadUserId) {
List<String> activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATING");
List<ImportTask> tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId, activeStatuses);
return tasks != null && !tasks.isEmpty();
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean cancelTask(String taskId, String operatorId) {
ImportTask importTask = this.getById(taskId);
if (importTask == null) {
return false;
}
String currentStatus = importTask.getStatus();
if ("CONFIRMED".equals(currentStatus) || "FAILED".equals(currentStatus) || "CANCELLED".equals(currentStatus)) {
return false;
}
importTask.setStatus("CANCELLED");
importTask.setErrorMsg("用户取消: " + operatorId);
importTask.setUpdatedAt(new Date());
return this.updateById(importTask);
}
@Override
public ImportTask getCurrentTaskByUserId(String uploadUserId) {
List<String> activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATING");
List<ImportTask> tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId, activeStatuses);
if (tasks == null || tasks.isEmpty()) {
return null;
}
return tasks.get(0);
}
}

View File

@ -0,0 +1,219 @@
package com.yfd.platform.data.utils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
public class ZipFileUtil {
public static final String DEFAULT_TEMP_BASE = "D:\\zip_import_temp";
public static class ZipContent {
public String excelFileName;
public String excelFilePath;
public Map<String, String> images;
public Map<String, String> videos;
public Map<String, String> otherFiles;
public String tempDir;
public ZipContent() {
this.images = new HashMap<>();
this.videos = new HashMap<>();
this.otherFiles = new HashMap<>();
}
public InputStream getExcelStream() throws IOException {
if (excelFilePath == null) {
return null;
}
return new FileInputStream(excelFilePath);
}
}
public static String getDefaultTempDir() {
return DEFAULT_TEMP_BASE;
}
public static ZipContent extractZipToTemp(MultipartFile file) throws IOException {
return extractZipToTemp(file, DEFAULT_TEMP_BASE);
}
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);
Files.createDirectories(tempDirPath);
content.tempDir = tempDirPath.toString();
File zipFile = new File(tempDirPath.toFile(), "upload.zip");
file.transferTo(zipFile);
try {
if (!isValidZipFile(zipFile)) {
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();
}
}
throw lastException != null ? lastException : new IOException("无法解析ZIP文件");
} finally {
if (zipFile.exists()) {
zipFile.delete();
}
}
}
private static boolean isValidZipFile(File file) {
if (file == null || file.length() < 4) {
return false;
}
try (FileInputStream fis = new FileInputStream(file)) {
byte[] signature = new byte[4];
int read = fis.read(signature);
if (read != 4) {
return false;
}
return signature[0] == 0x50 && signature[1] == 0x4B &&
signature[2] == 0x03 && signature[3] == 0x04;
} catch (IOException e) {
return false;
}
}
private static ZipContent extractFromZipFile(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();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String entryName = entry.getName();
if (entry.isDirectory()) {
continue;
}
try (InputStream is = zip.getInputStream(entry)) {
String lowerName = entryName.toLowerCase();
if (lowerName.endsWith(".xlsx") || lowerName.endsWith(".xls")) {
String excelPath = saveFileToDir(is, tempDir, "excel", getFileName(entryName));
content.excelFileName = getFileName(entryName);
content.excelFilePath = excelPath;
} else if (isImageFile(lowerName)) {
String folder = "images";
String path = saveFileToDir(is, tempDir, folder, getFileName(entryName));
content.images.put(entryName, path);
} else if (isVideoFile(lowerName)) {
String folder = "videos";
String path = saveFileToDir(is, tempDir, folder, getFileName(entryName));
content.videos.put(entryName, path);
} else {
String folder = "others";
String path = saveFileToDir(is, tempDir, folder, getFileName(entryName));
content.otherFiles.put(entryName, path);
}
}
}
}
return content;
}
private static String getFileName(String entryName) {
if (entryName == null) return "";
int lastSep = Math.max(entryName.lastIndexOf('/'), entryName.lastIndexOf('\\'));
return lastSep >= 0 ? entryName.substring(lastSep + 1) : entryName;
}
private static String saveFileToDir(InputStream is, File tempDir, String subFolder, String fileName) throws IOException {
File folder = new File(tempDir, subFolder);
if (!folder.exists()) {
folder.mkdirs();
}
File file = new File(folder, fileName);
try (FileOutputStream fos = new FileOutputStream(file)) {
byte[] buffer = new byte[4096];
int len;
while ((len = is.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
return file.getAbsolutePath();
}
private static boolean isImageFile(String fileName) {
return fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") ||
fileName.endsWith(".png") || fileName.endsWith(".gif") ||
fileName.endsWith(".bmp") || fileName.endsWith(".webp");
}
private static boolean isVideoFile(String fileName) {
return fileName.endsWith(".mp4") || fileName.endsWith(".avi") ||
fileName.endsWith(".mov") || fileName.endsWith(".wmv") ||
fileName.endsWith(".flv") || fileName.endsWith(".mkv");
}
public static void cleanupTempDir(String tempDir) {
if (tempDir == null || tempDir.isEmpty()) {
return;
}
File dir = new File(tempDir);
if (dir.exists()) {
deleteDirectory(dir);
}
}
private static void deleteDirectory(File dir) {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
deleteDirectory(file);
} else {
file.delete();
}
}
}
dir.delete();
}
public static String getFileExtension(String fileName) {
if (fileName == null) return "";
int lastDot = fileName.lastIndexOf('.');
return lastDot >= 0 ? fileName.substring(lastDot + 1).toLowerCase() : "";
}
}

View File

@ -0,0 +1,77 @@
package com.yfd.platform.env.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.annotation.Log;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.env.domain.SdFishDictoryB;
import com.yfd.platform.env.service.ISdFishDictoryBService;
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.*;
import java.util.List;
/**
* <p>
* 鱼类字典表 前端控制器
* </p>
*/
@RestController
@RequestMapping("/env/fishDictory")
@Tag(name = "鱼类字典管理")
public class SdFishDictoryBController {
@Resource
private ISdFishDictoryBService sdFishDictoryBService;
@GetMapping("/queryPageList")
@Operation(summary = "分页查询鱼类字典列表")
public ResponseResult queryPageList(
@RequestParam(required = false) String name,
@RequestParam(required = false) String code,
@RequestParam(required = false) Integer type,
@RequestParam(required = false) Integer rare,
@RequestParam(defaultValue = "1") Long pageNum,
@RequestParam(defaultValue = "10") Long pageSize) {
Page<SdFishDictoryB> page = new Page<>(pageNum, pageSize);
Page<SdFishDictoryB> result = sdFishDictoryBService.selectPage(name, code, type, rare, page);
return ResponseResult.successData(result);
}
@GetMapping("/list")
@Operation(summary = "查询所有鱼类字典")
public ResponseResult list() {
return ResponseResult.successData(sdFishDictoryBService.list());
}
@GetMapping("/getById")
@Operation(summary = "根据ID查询鱼类字典")
public ResponseResult getById(@RequestParam String id) {
return ResponseResult.successData(sdFishDictoryBService.getById(id));
}
@Log(module = "鱼类字典管理", value = "新增鱼类字典")
@PostMapping("/add")
@Operation(summary = "新增鱼类字典")
public ResponseResult add(@RequestBody SdFishDictoryB fishDictoryB) {
boolean result = sdFishDictoryBService.add(fishDictoryB);
return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败");
}
@Log(module = "鱼类字典管理", value = "修改鱼类字典")
@PostMapping("/update")
@Operation(summary = "修改鱼类字典")
public ResponseResult update(@RequestBody SdFishDictoryB fishDictoryB) {
boolean result = sdFishDictoryBService.updateById(fishDictoryB);
return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败");
}
@Log(module = "鱼类字典管理", value = "删除鱼类字典")
@PostMapping("/delete")
@Operation(summary = "删除鱼类字典")
public ResponseResult delete(@RequestParam String id) {
boolean result = sdFishDictoryBService.deleteById(id);
return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
}
}

View File

@ -0,0 +1,83 @@
package com.yfd.platform.env.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.annotation.Log;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.env.domain.SdFpssBH;
import com.yfd.platform.env.service.ISdFpssBHService;
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.*;
import java.util.List;
/**
* <p>
* 过鱼设施表 前端控制器
* </p>
*/
@RestController
@RequestMapping("/env/fpss")
@Tag(name = "过鱼设施管理")
public class SdFpssBHController {
@Resource
private ISdFpssBHService sdFpssBHService;
@GetMapping("/queryPageList")
@Operation(summary = "分页查询过鱼设施列表")
public ResponseResult queryPageList(
@RequestParam(required = false) String stcd,
@RequestParam(required = false) String sttp,
@RequestParam(required = false) String rstcd,
@RequestParam(required = false) Integer usfl,
@RequestParam(defaultValue = "1") Long pageNum,
@RequestParam(defaultValue = "10") Long pageSize) {
Page<SdFpssBH> page = new Page<>(pageNum, pageSize);
Page<SdFpssBH> result = sdFpssBHService.selectPage(stcd, sttp, rstcd, usfl, page);
return ResponseResult.successData(result);
}
@GetMapping("/list")
@Operation(summary = "查询所有过鱼设施")
public ResponseResult list() {
return ResponseResult.successData(sdFpssBHService.list());
}
@GetMapping("/getById")
@Operation(summary = "根据编码查询过鱼设施")
public ResponseResult getById(@RequestParam String stcd, @RequestParam String sttp) {
return ResponseResult.successData(sdFpssBHService.getDetail(stcd, sttp));
}
@GetMapping("/getByRstcd")
@Operation(summary = "根据电站编码查询过鱼设施")
public ResponseResult getByRstcd(@RequestParam String rstcd) {
return ResponseResult.successData(sdFpssBHService.getByRstcd(rstcd));
}
@Log(module = "过鱼设施管理", value = "新增过鱼设施")
@PostMapping("/add")
@Operation(summary = "新增过鱼设施")
public ResponseResult add(@RequestBody SdFpssBH sdFpssBH) {
boolean result = sdFpssBHService.add(sdFpssBH);
return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败");
}
@Log(module = "过鱼设施管理", value = "修改过鱼设施")
@PostMapping("/update")
@Operation(summary = "修改过鱼设施")
public ResponseResult update(@RequestBody SdFpssBH sdFpssBH) {
boolean result = sdFpssBHService.updateById(sdFpssBH);
return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败");
}
@Log(module = "过鱼设施管理", value = "删除过鱼设施")
@PostMapping("/delete")
@Operation(summary = "删除过鱼设施")
public ResponseResult delete(@RequestParam String stcd, @RequestParam String sttp) {
boolean result = sdFpssBHService.deleteById(stcd, sttp);
return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
}
}

View File

@ -0,0 +1,272 @@
package com.yfd.platform.env.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 鱼类字典信息表
* </p>
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("SD_FISHDICTORY_B")
public class SdFishDictoryB implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(type = IdType.INPUT)
private String id;
/**
* 编码
*/
private String code;
/**
* 名称
*/
private String name;
/**
* 英文名称
*/
private String nameEn;
/**
* 俗名
*/
private String alias;
/**
* LOGO
*/
private String logo;
/**
* 介绍
*/
private String introduce;
/**
* 介绍弹窗图片
*/
private String inffile;
/**
*
*/
private String orders;
/**
*
*/
private String family;
/**
*
*/
private String genus;
/**
*
*/
private String species;
/**
* 分类1=淡水 2=海水
*/
private Integer type;
/**
* 成鱼大小单位cm
*/
private String fsz;
/**
* 是否珍稀鱼类0= 1=
*/
private Integer rare;
/**
* 物种来源1=本土物种 2=外来物种
*/
private Integer specOrigin;
/**
* 保护类型1=濒危 2=极危 3=近危 4=易危 5=重点保护 6=无危 7=国家二级 8=市二级保护
*/
private Integer ptype;
/**
* 所属流域
*/
private String rvcd;
/**
* 洄游习性
*/
private String habitMigrat;
/**
* 摄食习性
*/
private String feedingHabit;
/**
* 产卵特性
*/
private String spawnCharact;
/**
* 主要食物
*/
private String food;
/**
* 觅食时段
*/
private String timeFeed;
/**
* 产地及产期
*/
private String orignDate;
/**
* 适宜温度单位
*/
private String pretemp;
/**
* 适宜流速单位m/s
*/
private String flowRate;
/**
* 适宜水深单位m
*/
private String depth;
/**
* 适宜底质
*/
private String botmMater;
/**
* 水质要求1= 2= 3= 4= 5= 6=劣质V
*/
private String wqtq;
/**
* 主要生活环境 1=流水生境 2=静缓流生境 3=洞穴生境
*/
private Integer habitat;
/**
* 种群现状 1=优势种 2=常见种 3=少见种 4=记录种
*/
private Integer situation;
/**
* 资源类型 1=保护鱼类 2=特有鱼类 3=重要经济鱼类 4=濒危状况
*/
private Integer resourceType;
/**
* 形态描述
*/
private String shapedesc;
/**
* 保护级别
*/
private String protectlvl;
/**
* 栖息习性
*/
private String habitation;
/**
* 附件
*/
private String fid;
/**
* 描述
*/
private String description;
/**
* 是否启用0=禁用 1=启用
*/
private Integer enable;
/**
* 系统内置项0= 1=
*/
private Integer internal;
/**
* 排序
*/
private Integer orderIndex;
/**
* 创建人关联SYS_USER.ID
*/
private String recordUser;
/**
* 创建时间
*/
private Date recordTime;
/**
* 更新人关联SYS_USER.ID
*/
private String modifyUser;
/**
* 更新时间
*/
private Date modifyTime;
/**
* 是否已删除0=未删除 1=已删除
*/
private Integer isDeleted;
/**
* 删除人关联SYS_USER.ID
*/
private String deleteUser;
/**
* 删除时间
*/
private Date deleteTime;
/**
* 产卵月份多个月份以逗号分隔
*/
private String spawnMonth;
/**
* 数据来源
*/
private String vlsr;
/**
* 数据来源时间
*/
private Date vlsrTm;
}

View File

@ -0,0 +1,382 @@
package com.yfd.platform.env.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
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_B_H")
public class SdFpssBH implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 过鱼设施编码
*/
@TableId(type = IdType.INPUT)
private String stcd;
/**
* 设施名称
*/
private String stnm;
/**
* 数据时间
*/
private Date tm;
/**
* 过鱼设施类型字典编码sd_fpss_b_h.sttp
* FP_1=鱼道 FP_2=仿自然通道 FP_3=集运鱼系统 FP_4=升鱼机 FP_5=其它过鱼方式 FP_6=网捕过坝
*/
private String sttp;
/**
* 所属建设阶段 字典编码common.blprd
* 1001000=规划 1002000=预可研 1003000=环评 1004000=可研 1005000=在建 1006000=招标设计
* 1007000=施工详图 1009000=建设 1010000=蓄水阶段环保验收 1011000=竣工 1012000=竣工环保验收 1013000=环境影响后评价
*/
private Integer blprd;
/**
* 经度单位(°)
*/
private BigDecimal lgtd;
/**
* 纬度单位(°)
*/
private BigDecimal lttd;
/**
* 高程单位m
*/
private BigDecimal elev;
/**
* 站址/位置
*/
private String stlc;
/**
* 是否启用 字典编码common.enabled 0=禁用 1=启用
*/
private Integer usfl;
/**
* 数据是否接入 字典编码common.yn 0= 1=
*/
private Integer dtin;
/**
* 数据接入时间
*/
private Date dtinTm;
/**
* 排序按照业务规则"升序"
*/
private Integer orderIndex;
/**
* 所属电站编码关联SD_ENGINFO_B_H.STCD
*/
private String rstcd;
/**
* 规划设计日期
*/
private Date stdsdt;
/**
* 计划开工日期
*/
private Date pststdt;
/**
* 计划完工日期
*/
private Date pesstdt;
/**
* 开工日期
*/
private Date swdt;
/**
* 建成日期
*/
private Date jcdt;
/**
* 退役/拆除日期
*/
private Date wddt;
/**
* 建设状态分类0=未建/规划(3,4,5,6,为空) 1=在建(2,7,8) 2=已建(1,10,11)
*/
private Integer bldsttCode;
/**
* 简介
*/
private String introduce;
/**
* LOGO
*/
private String logo;
/**
* 介绍弹窗图片
*/
private String inffile;
/**
* 投资单位亿元
*/
private BigDecimal inv;
/**
* 鱼道型式
*/
private String ydxs;
/**
* 鱼道总长度单位m
*/
private BigDecimal ydzcd;
/**
* 鱼道进口运行设计水位单位m
*/
private BigDecimal ydjkz;
/**
* 鱼道进口数量单位
*/
private Integer ydjkcnt;
/**
* 鱼道或仿自然通道-进口高程单位m
*/
private BigDecimal jkhg;
/**
* 鱼道进口诱鱼型式
*/
private String ydyyxs;
/**
* 鱼道出口运行设计水位单位m
*/
private BigDecimal ydckz;
/**
* 鱼道出口数量单位
*/
private Integer ydckcnt;
/**
* 鱼道或仿自然通道-出口高程单位m
*/
private BigDecimal ckhg;
/**
* 鱼道池室设计流速单位m/s
*/
private BigDecimal ydcsv;
/**
* 鱼道每级池室长单位m
*/
private Integer ydcscd;
/**
* 鱼道每级池室宽单位m
*/
private Integer ydcskd;
/**
* 鱼道池室坡度
*/
private String ydcspd;
/**
* 鱼道池室数量单位
*/
private Integer ydcscnt;
/**
* 鱼道休息池个数
*/
private Integer ydxxccnt;
/**
* 鱼道或仿自然通道-流速单位m/s
*/
private BigDecimal v;
/**
* 仿自然通道断面形状
*/
private String fzrdmxz;
/**
* 仿自然通道长度*宽度
*/
private String fzrtdsz;
/**
* 仿自然通道运行水深单位m
*/
private BigDecimal fzryxwdp;
/**
* 仿自然通道坡降
*/
private BigDecimal fzrpj;
/**
* 集运鱼系统或升鱼机-上游码头位置
*/
private String symtlc;
/**
* 集运鱼系统或升鱼机-上游码头型式
*/
private String symtxs;
/**
* 集运鱼系统或升鱼机-下游码头位置
*/
private String xymtlc;
/**
* 集运鱼系统或升鱼机-下游码头型式
*/
private String xymtxs;
/**
* 集运鱼系统或升鱼机-集诱鱼方式
*/
private String jyfs;
/**
* 集运鱼系统或升鱼机-运鱼设施方式
*/
private String yyfs;
/**
* 升鱼机集鱼槽数量单位
*/
private Integer syjcnt;
/**
* 升鱼机集鱼槽进口高程单位m
*/
private BigDecimal syjhg;
/**
* 升鱼机集鱼槽流量单位m3/s
*/
private BigDecimal syjq;
/**
* 升鱼机断面尺寸**单位m
*/
private String syjsz;
/**
* 升鱼机集鱼槽水深单位m
*/
private BigDecimal syjwdp;
/**
* 设计过鱼规模单位
*/
private Long sjgycnt;
/**
* 主要过鱼对象{[code:鱼编码1,name:鱼名称1数量],[code:鱼编码2,name:鱼名称2]...}
*/
private String zygydx;
/**
* 主要过鱼对象描述
*/
private String zygydxms;
/**
* 兼顾过鱼对象{[code:鱼编码1,name:鱼名称1数量],[code:鱼编码2,name:鱼名称2]...}
*/
private String jggydx;
/**
* 兼顾过鱼对象描述
*/
private String jggydxms;
/**
* 过鱼时间
*/
private String gytm;
/**
* 运行时间
*/
private String yxtm;
/**
* 主要过鱼月份多个月份用,隔开
*/
private String fpssmn;
/**
* 数据监测频次单位min
*/
private Integer dtfrqcy;
/**
* 基本特性参数文字描述
*/
private String jbtxcs;
/**
* 设施是否实现鱼类上行 0= 1=
*/
private Integer isUp;
/**
* 设施是否实现鱼类下行 0= 1=
*/
private Integer isDown;
/**
* 备注
*/
private String remark;
/**
* 数据来源
*/
private String vlsr;
/**
* 数据来源时间
*/
private Date vlsrTm;
}

View File

@ -0,0 +1,9 @@
package com.yfd.platform.env.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.env.domain.SdFishDictoryB;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SdFishDictoryBMapper extends BaseMapper<SdFishDictoryB> {
}

View File

@ -0,0 +1,9 @@
package com.yfd.platform.env.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.env.domain.SdFpssBH;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SdFpssBHMapper extends BaseMapper<SdFpssBH> {
}

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.SdFishDictoryB;
public interface ISdFishDictoryBService extends IService<SdFishDictoryB> {
Page<SdFishDictoryB> selectPage(String name, String code, Integer type, Integer rare, Page<SdFishDictoryB> page);
boolean add(SdFishDictoryB fishDictoryB);
boolean updateById(SdFishDictoryB fishDictoryB);
boolean deleteById(String id);
SdFishDictoryB getById(String id);
}

View File

@ -0,0 +1,22 @@
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.SdFpssBH;
import java.util.List;
public interface ISdFpssBHService extends IService<SdFpssBH> {
Page<SdFpssBH> selectPage(String stcd, String sttp, String rstcd, Integer usfl, Page<SdFpssBH> page);
List<SdFpssBH> getByRstcd(String rstcd);
boolean add(SdFpssBH sdFpssBH);
boolean updateById(SdFpssBH sdFpssBH);
boolean deleteById(String stcd, String sttp);
SdFpssBH getDetail(String stcd, String sttp);
}

View File

@ -0,0 +1,65 @@
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.SdFishDictoryB;
import com.yfd.platform.env.mapper.SdFishDictoryBMapper;
import com.yfd.platform.env.service.ISdFishDictoryBService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@Service
public class SdFishDictoryBServiceImpl extends ServiceImpl<SdFishDictoryBMapper, SdFishDictoryB> implements ISdFishDictoryBService {
@Override
public Page<SdFishDictoryB> selectPage(String name, String code, Integer type, Integer rare, Page<SdFishDictoryB> page) {
LambdaQueryWrapper<SdFishDictoryB> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SdFishDictoryB::getIsDeleted, 0);
if (StringUtils.hasText(name)) {
wrapper.like(SdFishDictoryB::getName, name);
}
if (StringUtils.hasText(code)) {
wrapper.eq(SdFishDictoryB::getCode, code);
}
if (type != null) {
wrapper.eq(SdFishDictoryB::getType, type);
}
if (rare != null) {
wrapper.eq(SdFishDictoryB::getRare, rare);
}
wrapper.orderByDesc(SdFishDictoryB::getOrderIndex);
return page(page, wrapper);
}
@Override
public boolean add(SdFishDictoryB fishDictoryB) {
fishDictoryB.setIsDeleted(0);
return save(fishDictoryB);
}
@Override
public boolean updateById(SdFishDictoryB fishDictoryB) {
return updateById(fishDictoryB);
}
@Override
public boolean deleteById(String id) {
SdFishDictoryB entity = getById(id);
if (entity != null) {
entity.setIsDeleted(1);
return updateById(entity);
}
return false;
}
@Override
public SdFishDictoryB getById(String id) {
LambdaQueryWrapper<SdFishDictoryB> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SdFishDictoryB::getId, id)
.eq(SdFishDictoryB::getIsDeleted, 0);
return getOne(wrapper);
}
}

View File

@ -0,0 +1,73 @@
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.SdFpssBH;
import com.yfd.platform.env.mapper.SdFpssBHMapper;
import com.yfd.platform.env.service.ISdFpssBHService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
@Service
public class SdFpssBHServiceImpl extends ServiceImpl<SdFpssBHMapper, SdFpssBH> implements ISdFpssBHService {
@Override
public Page<SdFpssBH> selectPage(String stcd, String sttp, String rstcd, Integer usfl, Page<SdFpssBH> page) {
LambdaQueryWrapper<SdFpssBH> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.hasText(stcd)) {
wrapper.like(SdFpssBH::getStcd, stcd);
}
if (StringUtils.hasText(sttp)) {
wrapper.eq(SdFpssBH::getSttp, sttp);
}
if (StringUtils.hasText(rstcd)) {
wrapper.eq(SdFpssBH::getRstcd, rstcd);
}
if (usfl != null) {
wrapper.eq(SdFpssBH::getUsfl, usfl);
}
wrapper.orderByDesc(SdFpssBH::getOrderIndex);
return page(page, wrapper);
}
@Override
public List<SdFpssBH> getByRstcd(String rstcd) {
LambdaQueryWrapper<SdFpssBH> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SdFpssBH::getRstcd, rstcd);
return list(wrapper);
}
@Override
public boolean add(SdFpssBH sdFpssBH) {
return save(sdFpssBH);
}
@Override
public boolean updateById(SdFpssBH sdFpssBH) {
LambdaQueryWrapper<SdFpssBH> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SdFpssBH::getStcd, sdFpssBH.getStcd())
.eq(SdFpssBH::getSttp, sdFpssBH.getSttp());
return update(sdFpssBH, wrapper);
}
@Override
public boolean deleteById(String stcd, String sttp) {
LambdaQueryWrapper<SdFpssBH> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SdFpssBH::getStcd, stcd)
.eq(SdFpssBH::getSttp, sttp);
return remove(wrapper);
}
@Override
public SdFpssBH getDetail(String stcd, String sttp) {
LambdaQueryWrapper<SdFpssBH> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SdFpssBH::getStcd, stcd)
.eq(SdFpssBH::getSttp, sttp);
return getOne(wrapper);
}
}

View File

@ -4,8 +4,10 @@ import cn.hutool.core.util.StrUtil;
import com.yfd.platform.annotation.Log;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.system.domain.SysDictionary;
import com.yfd.platform.system.domain.SysDictionaryItems;
import com.yfd.platform.system.mapper.SysDictionaryItemsMapper;
import com.yfd.platform.system.service.ISysDictionaryService;
import com.yfd.platform.system.service.ISysDictionaryItemsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.util.StringUtils;
@ -31,6 +33,9 @@ public class SysDictionaryController {
@Resource
private ISysDictionaryService sysDictionaryService;
@Resource
private ISysDictionaryItemsService sysDictionaryItemsService;
/**********************************
* 用途说明: 获取数据字典列表
* 参数说明 dictType 字典类型
@ -139,4 +144,18 @@ public class SysDictionaryController {
}
@GetMapping("/getDictItemsByCode")
@Operation(summary = "根据字典编号查询字典项列表")
public ResponseResult getDictItemsByCode(@RequestParam String dictCode) {
if (StrUtil.isBlank(dictCode)) {
return ResponseResult.error("字典编号不能为空");
}
SysDictionary sysDictionary = sysDictionaryService.getByDictCode(dictCode);
if (sysDictionary == null) {
return ResponseResult.error("未找到对应的字典");
}
List<SysDictionaryItems> items = sysDictionaryItemsService.listByDictId(sysDictionary.getId());
return ResponseResult.successData(items);
}
}

View File

@ -44,4 +44,11 @@ public interface ISysDictionaryItemsService extends IService<SysDictionaryItems>
* 返回值说明: com.yfd.platform.config.ResponseResult 返回导出成功或失败
***********************************/
void exportExcel(List<SysDictionaryItems> records, HttpServletResponse response);
/**********************************
* 用途说明: 根据字典ID查询字典项列表
* 参数说明 dictId 字典ID
* 返回值说明: List<SysDictionaryItems> 字典项列表
***********************************/
List<SysDictionaryItems> listByDictId(String dictId);
}

View File

@ -42,4 +42,11 @@ public interface ISysDictionaryService extends IService<SysDictionary> {
* 返回值说明: com.yfd.platform.config.ResponseResult 返回拖动成功或者失败
***********************************/
boolean changeDictOrder(String fromID, String toID);
/**********************************
* 用途说明: 根据字典编号查询字典
* 参数说明 dictCode 字典编号
* 返回值说明: SysDictionary 字典对象
***********************************/
SysDictionary getByDictCode(String dictCode);
}

View File

@ -120,4 +120,11 @@ public class SysDictionaryItemsServiceImpl extends ServiceImpl<SysDictionaryItem
}
}
@Override
public List<SysDictionaryItems> listByDictId(String dictId) {
LambdaQueryWrapper<SysDictionaryItems> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysDictionaryItems::getDictId, dictId).orderByAsc(SysDictionaryItems::getOrderNo);
return sysDictionaryItemsMapper.selectList(queryWrapper);
}
}

View File

@ -111,4 +111,11 @@ public class SysDictionaryServiceImpl extends ServiceImpl<SysDictionaryMapper
return fromBool && toBool;
}
@Override
public SysDictionary getByDictCode(String dictCode) {
LambdaQueryWrapper<SysDictionary> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysDictionary::getDictCode, dictCode);
return sysDictionaryMapper.selectOne(queryWrapper);
}
}

View File

@ -71,6 +71,16 @@ public class SecurityUtils {
return new JSONObject(new JSONObject(userDetails).get("user")).get("id", Long.class);
}
/**
* 获取系统用户ID
* @return 系统用户ID
*/
public static String getUserId() {
UserDetails userDetails = getCurrentUser();
return new JSONObject(new JSONObject(userDetails).get("user")).get("id", String.class);
}
/**
* 获取当前用户的数据权限
* @return /

View File

@ -58,8 +58,8 @@ mybatis-plus:
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
# log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 登录相关配置