diff --git a/nflg-wms-shipment/src/test/java/com/nflg/wms/shipment/MaterialImageUploadTest.java b/nflg-wms-shipment/src/test/java/com/nflg/wms/shipment/MaterialImageUploadTest.java new file mode 100644 index 00000000..f5be1db8 --- /dev/null +++ b/nflg-wms-shipment/src/test/java/com/nflg/wms/shipment/MaterialImageUploadTest.java @@ -0,0 +1,210 @@ +package com.nflg.wms.shipment; + +import cn.hutool.core.io.FileUtil; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.nflg.wms.repository.entity.WmsShipmentMaterial; +import com.nflg.wms.repository.mapper.WmsShipmentMaterialMapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.*; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.io.File; + +/** + * 物料图片批量上传测试 + * 从桌面的Output文件夹读取所有图片并上传,然后更新物料表的image字段 + */ +@Slf4j +@SpringBootTest +@ContextConfiguration(classes = ShipmentApplication.class) +public class MaterialImageUploadTest { + + @Resource + private WmsShipmentMaterialMapper materialMapper; + + @Resource + private RestTemplate restTemplate; + + // 文件上传接口地址 + private static final String UPLOAD_URL = "https://pomp.nflg.net/api/admin/file/uploadSingleFile1"; + + @Test + public void testUploadImagesFromZip() { + // 桌面路径 + String desktopPath = System.getProperty("user.home") + File.separator + "Desktop"; + String outputDirPath = desktopPath + File.separator + "Output"; + + log.info("开始处理Output文件夹: {}", outputDirPath); + + // 检查文件夹是否存在 + File outputDir = new File(outputDirPath); + if (!outputDir.exists()) { + log.error("Output文件夹不存在: {}", outputDirPath); + throw new RuntimeException("Output文件夹不存在: " + outputDirPath); + } + + if (!outputDir.isDirectory()) { + log.error("路径不是文件夹: {}", outputDirPath); + throw new RuntimeException("路径不是文件夹: " + outputDirPath); + } + + // 递归获取所有图片文件 + java.util.List imageFiles = new java.util.ArrayList<>(); + collectImageFiles(outputDir, imageFiles); + + if (imageFiles.isEmpty()) { + log.warn("Output文件夹中没有找到图片文件"); + return; + } + + log.info("找到 {} 个图片文件", imageFiles.size()); + + // 处理每个图片文件 + int successCount = 0; + int notFoundCount = 0; + int errorCount = 0; + + for (File imageFile : imageFiles) { + try { + // 获取文件名(不带后缀) + String fileNameWithoutExt = FileUtil.getPrefix(imageFile.getName()); + log.info("处理文件: {}, 文件名(无后缀): {}", imageFile.getName(), fileNameWithoutExt); + + // 上传文件 + String url = uploadFile(imageFile); + log.info("文件上传成功, url: {}", url); + + // 根据no字段查找物料 + WmsShipmentMaterial material = materialMapper.selectOne( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(WmsShipmentMaterial::getNo, fileNameWithoutExt) + ); + + if (material != null) { + // 更新image字段 + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(WmsShipmentMaterial::getNo, fileNameWithoutExt) + .set(WmsShipmentMaterial::getImage, url); + + int updateCount = materialMapper.update(null, updateWrapper); + if (updateCount > 0) { + imageFile.delete(); + log.info("成功更新物料 {} 的图片url", fileNameWithoutExt); + successCount++; + } else { + log.error("更新物料 {} 的图片url失败", fileNameWithoutExt); + errorCount++; + } + } else { + log.warn("未找到物料编号为 {} 的物料记录", fileNameWithoutExt); + notFoundCount++; + } + } catch (Exception e) { + log.error("处理文件 {} 时发生错误: {}", imageFile.getName(), e.getMessage(), e); + errorCount++; + } + } + + // 输出统计信息 + log.info("========================================"); + log.info("处理完成!"); + log.info("总文件数: {}", imageFiles.size()); + log.info("成功更新: {}", successCount); + log.info("未找到物料: {}", notFoundCount); + log.info("处理错误: {}", errorCount); + log.info("========================================"); + } + + /** + * 上传文件 - 调用HTTP接口 + */ + private String uploadFile(File file) { + // 构建multipart请求 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + headers.add("authorization", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiM3pCT2dQT203ZmZTVEY5S0gxYldaZ0w0ZmJGVW85TnoiLCJuYW1lIjoi6LaF57qn566h55CG5ZGYIiwiY29kZSI6ImFkbWluIiwicm9sZXMiOlsiU3VwZXJBZG1pbiJdLCJ0eXBlIjoxfQ.Ircp8zNaLX7Wly7IZxEEdQrFo2BVfufXxXDhn7wSdrk"); + + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("file", new FileSystemResource(file)); + + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + + // 使用String接收响应,避免Jackson反序列化LocalDateTime的问题 + ResponseEntity responseEntity = restTemplate.postForEntity(UPLOAD_URL, requestEntity, String.class); + + // 检查响应 + if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody() == null) { + throw new RuntimeException("文件上传失败,HTTP状态码: " + responseEntity.getStatusCode()); + } + + // 手动解析JSON + String responseBody = responseEntity.getBody(); + log.debug("上传响应: {}", responseBody); + + cn.hutool.json.JSONObject jsonObject = cn.hutool.json.JSONUtil.parseObj(responseBody); + int code = jsonObject.getInt("code", -1); + + if (code != 200) { + String message = jsonObject.getStr("message", "未知错误"); + throw new RuntimeException("文件上传失败: " + message); + } + + // 提取url + cn.hutool.json.JSONObject result = jsonObject.getJSONObject("result"); + if (result == null) { + throw new RuntimeException("文件上传失败: 返回结果为空"); + } + + String url = result.getStr("url"); + if (url == null || url.isEmpty()) { + throw new RuntimeException("文件上传失败: URL为空"); + } + + return url; + } + + /** + * 递归收集所有图片文件 + */ + private void collectImageFiles(File dir, java.util.List imageFiles) { + File[] files = dir.listFiles(); + if (files == null) { + return; + } + + for (File file : files) { + if (file.isDirectory()) { + collectImageFiles(file, imageFiles); + } else { + String lowerName = file.getName().toLowerCase(); + if (lowerName.endsWith(".jpg") || lowerName.endsWith(".jpeg") || + lowerName.endsWith(".png") || lowerName.endsWith(".gif") || + lowerName.endsWith(".bmp")) { + imageFiles.add(file); + } + } + } + } + + /** + * 递归删除目录 + */ + private void deleteDirectory(File file) { + if (file.isDirectory()) { + File[] files = file.listFiles(); + if (files != null) { + for (File f : files) { + deleteDirectory(f); + } + } + } + file.delete(); + } +}