Merge branch 'dev-tw'

This commit is contained in:
tangwei 2026-04-27 08:28:43 +08:00
commit 9d0fbd2cb0
7 changed files with 391 additions and 8 deletions

View File

@ -0,0 +1,176 @@
package com.yfd.platform.data.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Service
public class AttachmentUploadService {
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;
public AttachmentUploadService() {
this.httpClient = HttpClient.newBuilder()
.build();
}
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;
if (fileName.toLowerCase().endsWith(".mp4") || fileName.toLowerCase().endsWith(".avi") ||
fileName.toLowerCase().endsWith(".mov") || fileName.toLowerCase().endsWith(".wmv")) {
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);
} else {
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);
}
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(UPLOAD_URL))
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.POST(HttpRequest.BodyPublishers.ofByteArray(body))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
String responseBody = response.body();
return parseAttachmentId(responseBody);
} else {
log.error("上传文件失败: {}, 状态码: {}", fileName, response.statusCode());
return null;
}
}
public String uploadVideo(File file) throws IOException, InterruptedException {
return uploadFile(file);
}
public String uploadImage(File file) throws IOException, InterruptedException {
return uploadFile(file);
}
public Map<String, String> uploadImages(Map<String, String> imageMap) {
Map<String, String> result = new ConcurrentHashMap<>();
for (Map.Entry<String, String> entry : imageMap.entrySet()) {
String fileName = entry.getKey();
String filePath = entry.getValue();
try {
File file = new File(filePath);
if (file.exists()) {
String attachmentId = uploadFile(file);
if (attachmentId != null) {
result.put(fileName, attachmentId);
log.info("图片上传成功: {} -> {}", fileName, attachmentId);
} else {
log.warn("图片上传返回空ID: {}", fileName);
}
} else {
log.warn("图片文件不存在: {}", filePath);
}
} catch (Exception e) {
log.error("上传图片失败: {}", fileName, e);
}
}
return result;
}
public Map<String, String> uploadVideos(Map<String, String> videoMap) {
Map<String, String> result = new ConcurrentHashMap<>();
for (Map.Entry<String, String> entry : videoMap.entrySet()) {
String fileName = entry.getKey();
String filePath = entry.getValue();
try {
File file = new File(filePath);
if (file.exists()) {
String attachmentId = uploadFile(file);
if (attachmentId != null) {
result.put(fileName, attachmentId);
log.info("视频上传成功: {} -> {}", fileName, attachmentId);
} else {
log.warn("视频上传返回空ID: {}", fileName);
}
} else {
log.warn("视频文件不存在: {}", filePath);
}
} catch (Exception e) {
log.error("上传视频失败: {}", fileName, e);
}
}
return result;
}
private String parseAttachmentId(String jsonResponse) {
if (jsonResponse == null || jsonResponse.isEmpty()) {
return null;
}
try {
if (jsonResponse.contains("\"message\":")) {
int start = jsonResponse.indexOf("\"message\":\"") + 11;
int end = jsonResponse.indexOf("\"", start);
if (start > 10 && end > start) {
return jsonResponse.substring(start, end);
}
}
if (jsonResponse.contains("\"message\":\"")) {
int start = jsonResponse.indexOf("\"message\":\"") + 11;
int end = jsonResponse.indexOf("\"", start);
if (start > 10 && end > start) {
return jsonResponse.substring(start, end);
}
}
} catch (Exception e) {
log.error("解析附件ID失败: {}", jsonResponse, e);
}
return null;
}
public String uploadFileAndGetId(String filePath) {
if (filePath == null || filePath.isEmpty()) {
return null;
}
File file = new File(filePath);
if (!file.exists()) {
log.warn("文件不存在: {}", filePath);
return null;
}
try {
return uploadFile(file);
} catch (Exception e) {
log.error("上传文件失败: {}", filePath, e);
return null;
}
}
}

View File

@ -3,6 +3,7 @@ package com.yfd.platform.data.service.impl;
import com.yfd.platform.data.domain.FishDraftData; import com.yfd.platform.data.domain.FishDraftData;
import com.yfd.platform.data.domain.FishImportRequest; import com.yfd.platform.data.domain.FishImportRequest;
import com.yfd.platform.data.domain.FishImportResult; import com.yfd.platform.data.domain.FishImportResult;
import com.yfd.platform.data.service.AttachmentUploadService;
import com.yfd.platform.data.service.IFishImportService; import com.yfd.platform.data.service.IFishImportService;
import com.yfd.platform.data.utils.ZipFileUtil; import com.yfd.platform.data.utils.ZipFileUtil;
import com.yfd.platform.env.domain.*; import com.yfd.platform.env.domain.*;
@ -50,6 +51,9 @@ public class FishImportServiceImpl implements IFishImportService {
@Resource @Resource
private ISysDictionaryItemsService sysDictionaryItemsService; private ISysDictionaryItemsService sysDictionaryItemsService;
@Resource
private AttachmentUploadService attachmentUploadService;
private static final Map<String, String> EXCEL_COLUMN_MAPPING = new LinkedHashMap<>(); 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<Integer, String> EXCEL_COLUMN_INDEX_MAPPING = new LinkedHashMap<>();
@ -143,8 +147,6 @@ public class FishImportServiceImpl implements IFishImportService {
Map<Integer, String> columnIndexMap = new HashMap<>(EXCEL_COLUMN_INDEX_MAPPING); Map<Integer, String> columnIndexMap = new HashMap<>(EXCEL_COLUMN_INDEX_MAPPING);
int totalRows = sheet.getLastRowNum(); int totalRows = sheet.getLastRowNum();
result.setTotalCount(totalRows);
for (int i = 1; i <= totalRows; i++) { for (int i = 1; i <= totalRows; i++) {
Row row = sheet.getRow(i); Row row = sheet.getRow(i);
if (row == null || isRowEmpty(row)) { if (row == null || isRowEmpty(row)) {
@ -152,6 +154,7 @@ public class FishImportServiceImpl implements IFishImportService {
} }
FishImportResult.FishImportRow importRow = parseRow(row, columnIndexMap, i); FishImportResult.FishImportRow importRow = parseRow(row, columnIndexMap, i);
result.setTotalCount(result.getTotalCount() + 1);
if (importRow.getData() != null && importRow.getWarnings().isEmpty()) { if (importRow.getData() != null && importRow.getWarnings().isEmpty()) {
result.getSuccessRows().add(importRow); result.getSuccessRows().add(importRow);
result.setSuccessCount(result.getSuccessCount() + 1); result.setSuccessCount(result.getSuccessCount() + 1);
@ -160,9 +163,8 @@ public class FishImportServiceImpl implements IFishImportService {
result.setFailedCount(result.getFailedCount() + 1); result.setFailedCount(result.getFailedCount() + 1);
} }
} }
result.setSummary(String.format("共解析%d条数据失败%d条未识别字段%s",
result.setSummary(String.format("共解析%d条数据成功%d条失败%d条未识别字段%s", result.getSuccessCount(), result.getFailedCount(),
result.getTotalCount(), result.getSuccessCount(), result.getFailedCount(),
unrecognizedHeaders.isEmpty() ? "" : String.join(", ", unrecognizedHeaders))); unrecognizedHeaders.isEmpty() ? "" : String.join(", ", unrecognizedHeaders)));
return result; return result;
@ -714,6 +716,8 @@ public class FishImportServiceImpl implements IFishImportService {
result.setExcelFileName(zipContent.excelFileName); result.setExcelFileName(zipContent.excelFileName);
result.setExcelFilePath(zipContent.excelFilePath); result.setExcelFilePath(zipContent.excelFilePath);
processAttachments(result, zipContent);
result.setSummary(result.getSummary() + String.format("\nZIP内容: 发现%d张图片, %d个视频, 临时目录: %s", result.setSummary(result.getSummary() + String.format("\nZIP内容: 发现%d张图片, %d个视频, 临时目录: %s",
zipContent.images.size(), zipContent.videos.size(), zipContent.tempDir)); zipContent.images.size(), zipContent.videos.size(), zipContent.tempDir));
@ -726,4 +730,120 @@ public class FishImportServiceImpl implements IFishImportService {
return result; return result;
} }
} }
private void processAttachments(FishImportResult result, ZipFileUtil.ZipContent zipContent) {
if (result.getSuccessRows() == null || result.getSuccessRows().isEmpty()) {
return;
}
for (FishImportResult.FishImportRow importRow : result.getSuccessRows()) {
FishDraftData data = importRow.getData();
if (data == null) {
continue;
}
String vdpth = data.getVdpth();
String picpth = data.getPicpth();
if (StringUtils.hasText(vdpth)) {
String uploadedVdpth = processVideoAttachments(vdpth, zipContent.videos);
data.setVdpth(uploadedVdpth);
}
if (StringUtils.hasText(picpth)) {
String uploadedPicpth = processImageAttachments(picpth, zipContent.images);
data.setPicpth(uploadedPicpth);
}
}
}
private String processVideoAttachments(String videoNames, Map<String, String> videoMap) {
if (videoNames == null || videoNames.isEmpty() || videoMap == null || videoMap.isEmpty()) {
return videoNames;
}
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);
} else {
attachmentIds.add(fileName);
}
} catch (Exception e) {
attachmentIds.add(fileName);
}
} else {
attachmentIds.add(fileName);
}
}
return String.join(",", attachmentIds);
}
private String processImageAttachments(String imageNames, Map<String, String> imageMap) {
if (imageNames == null || imageNames.isEmpty() || imageMap == null || imageMap.isEmpty()) {
return imageNames;
}
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);
} else {
attachmentIds.add(fileName);
}
} catch (Exception e) {
attachmentIds.add(fileName);
}
} else {
attachmentIds.add(fileName);
}
}
return String.join(",", attachmentIds);
}
private String findFilePath(String fileName, Map<String, String> fileMap) {
if (fileName == null || fileMap == null || fileMap.isEmpty()) {
return null;
}
for (Map.Entry<String, String> entry : fileMap.entrySet()) {
String entryName = entry.getKey();
if (entryName.equals(fileName) || entryName.endsWith("/" + fileName) || entryName.endsWith("\\" + fileName)) {
return entry.getValue();
}
String entryFileName = entryName;
int lastSep = Math.max(entryName.lastIndexOf('/'), entryName.lastIndexOf('\\'));
if (lastSep >= 0) {
entryFileName = entryName.substring(lastSep + 1);
}
if (entryFileName.equals(fileName)) {
return entry.getValue();
}
}
return null;
}
} }

View File

@ -2,9 +2,11 @@ package com.yfd.platform.env.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.annotation.Log; import com.yfd.platform.annotation.Log;
import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.env.domain.SdRvcdDic; import com.yfd.platform.env.domain.SdRvcdDic;
import com.yfd.platform.env.service.ISdRvcdDicService; import com.yfd.platform.env.service.ISdRvcdDicService;
import com.yfd.platform.utils.DataSourceRequestUtil;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -43,6 +45,13 @@ public class SdRvcdDicController {
return ResponseResult.successData(rvcdDicService.list()); return ResponseResult.successData(rvcdDicService.list());
} }
@PostMapping("/queryList")
@Operation(summary = "查询流域")
public ResponseResult queryList(@RequestBody DataSourceRequest dataSourceRequest) {
List<SdRvcdDic> sdRvcdDics = DataSourceRequestUtil.executeList(dataSourceRequest, SdRvcdDic.class, rvcdDicService);
return ResponseResult.successData(sdRvcdDics);
}
@GetMapping("/getByPrvcd") @GetMapping("/getByPrvcd")
@Operation(summary = "根据父编码查询流域") @Operation(summary = "根据父编码查询流域")
public ResponseResult getByPrvcd(@RequestParam(required = false) String prvcd) { public ResponseResult getByPrvcd(@RequestParam(required = false) String prvcd) {
@ -62,6 +71,14 @@ public class SdRvcdDicController {
return ResponseResult.successData(rvcdDicService.getById(rvcd)); return ResponseResult.successData(rvcdDicService.getById(rvcd));
} }
@GetMapping("/tree")
@Operation(summary = "获取流域树形结构")
public ResponseResult getTree(
@RequestParam(required = false) String rvcd,
@RequestParam(required = false) String rvnm) {
return ResponseResult.successData(rvcdDicService.getTree(rvcd, rvnm));
}
// @Log(module = "流域管理", value = "新增流域") // @Log(module = "流域管理", value = "新增流域")
@PostMapping("/add") @PostMapping("/add")
@Operation(summary = "新增流域") @Operation(summary = "新增流域")

View File

@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* <p> * <p>
@ -114,4 +115,10 @@ public class SdRvcdDic implements Serializable {
* 地图专题流域标识1= 0否 * 地图专题流域标识1= 0否
*/ */
private Integer ismap; private Integer ismap;
/**
* 子节点用于树形结构不映射数据库字段
*/
@TableField(exist = false)
private List<SdRvcdDic> children;
} }

View File

@ -42,4 +42,11 @@ public interface ISdRvcdDicService extends IService<SdRvcdDic> {
* 删除流域 * 删除流域
*/ */
boolean deleteRvcdDic(String rvcd); boolean deleteRvcdDic(String rvcd);
/**
* 获取流域树形结构
* @param rvcd 流域编码可选为空则返回全部
* @param rvnm 流域名称可选用于模糊搜索
*/
List<SdRvcdDic> getTree(String rvcd, String rvnm);
} }

View File

@ -6,8 +6,10 @@ import com.yfd.platform.env.domain.SdRvcdDic;
import com.yfd.platform.env.mapper.SdRvcdDicMapper; import com.yfd.platform.env.mapper.SdRvcdDicMapper;
import com.yfd.platform.env.service.ISdRvcdDicService; import com.yfd.platform.env.service.ISdRvcdDicService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List; import java.util.*;
import java.util.stream.Collectors;
/** /**
* <p> * <p>
@ -58,4 +60,58 @@ public class SdRvcdDicServiceImpl extends ServiceImpl<SdRvcdDicMapper, SdRvcdDic
public boolean deleteRvcdDic(String rvcd) { public boolean deleteRvcdDic(String rvcd) {
return this.removeById(rvcd); return this.removeById(rvcd);
} }
}
@Override
public List<SdRvcdDic> getTree(String rvcd, String rvnm) {
List<SdRvcdDic> result = new ArrayList<>();
List<SdRvcdDic> rootList;
Set<String> rootRvcdSet = new HashSet<>();
if (StringUtils.hasText(rvcd)) {
SdRvcdDic singleRvcd = this.getById(rvcd);
if (singleRvcd != null) {
rootList = new ArrayList<>();
rootList.add(singleRvcd);
rootRvcdSet.add(singleRvcd.getRvcd());
} else {
return result;
}
} else {
rootList = getRootList();
for (SdRvcdDic root : rootList) {
rootRvcdSet.add(root.getRvcd());
}
}
List<SdRvcdDic> allList = this.lambdaQuery()
.like(StringUtils.hasText(rvnm), SdRvcdDic::getRvnm, rvnm)
.orderByAsc(SdRvcdDic::getOrderIndex)
.list();
Map<String, List<SdRvcdDic>> childrenMap = allList.stream()
.filter(item -> item.getPrvcd() != null)
.collect(Collectors.groupingBy(SdRvcdDic::getPrvcd));
for (SdRvcdDic root : rootList) {
if (rootRvcdSet.contains(root.getRvcd())) {
buildTreeRecursive(root, childrenMap, rootRvcdSet);
result.add(root);
}
}
return result;
}
private void buildTreeRecursive(SdRvcdDic parent, Map<String, List<SdRvcdDic>> childrenMap, Set<String> rootRvcdSet) {
List<SdRvcdDic> children = childrenMap.get(parent.getRvcd());
if (children != null && !children.isEmpty()) {
for (SdRvcdDic child : children) {
buildTreeRecursive(child, childrenMap, rootRvcdSet);
}
parent.setChildren(children);
} else {
parent.setChildren(new ArrayList<>());
}
}
}

View File

@ -234,7 +234,7 @@
<select id="selectByBaseId" resultMap="BaseResultMap"> <select id="selectByBaseId" resultMap="BaseResultMap">
SELECT * FROM SD_ENGINFO_B_H SELECT * FROM SD_ENGINFO_B_H
WHERE BASE_ID = #{baseId} WHERE BASE_ID = #{baseId}
ORDER BY ORDER_INDEX ASC ORDER BY ORDER_INDEX,STCD ASC
</select> </select>
<select id="selectByHycd" resultMap="BaseResultMap"> <select id="selectByHycd" resultMap="BaseResultMap">