feat(material): 通过base64字符串支持图片上传

- 在FileUploadService接口中新增支持base64字符串上传的方法
- 在OSSFileUploadServiceImpl和RustFSServiceImpl实现类中添加base64上传实现
- 在MaterialController新增base64图片上传功能,自动转换并上传图片
- 生成图片文件路径,支持动态日期、随机字符串及UUID组合
- 在ShipmentMaterialSyncSaveQO中新增imageBase64字段支持传递base64图片数据
- 添加日志记录上传失败的异常信息,保证上传错误可追踪
This commit is contained in:
曹鹏飞 2026-05-11 15:06:03 +08:00
parent 99ce826d1c
commit f330ca4117
5 changed files with 80 additions and 4 deletions

View File

@ -35,6 +35,11 @@ public class ShipmentMaterialSyncSaveQO {
*/
private String image;
/**
* base64格式的图片
*/
private String imageBase64;
/**
* 重量
*/

View File

@ -2,6 +2,8 @@ package com.nflg.wms.shipment.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -12,6 +14,7 @@ import com.nflg.wms.common.pojo.qo.ShipmentMaterialAddQO;
import com.nflg.wms.common.pojo.qo.ShipmentMaterialSearchQO;
import com.nflg.wms.common.pojo.qo.ShipmentMaterialSyncSaveQO;
import com.nflg.wms.common.pojo.qo.ShipmentMaterialUpdateQO;
import com.nflg.wms.common.util.DateTimeUtil;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.WmsShipmentMaterial;
@ -19,11 +22,13 @@ import com.nflg.wms.repository.service.IWmsShipmentMaterialService;
import com.nflg.wms.shipment.service.ShipmentMaterialControllerService;
import com.nflg.wms.starter.BaseController;
import com.nflg.wms.starter.service.BomMaterialService;
import com.nflg.wms.starter.service.FileUploadService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@ -33,6 +38,7 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@ -41,6 +47,7 @@ import java.util.stream.Collectors;
/**
* 图纸管理
*/
@Slf4j
@RestController
@RequestMapping("material")
public class MaterialController extends BaseController {
@ -54,6 +61,9 @@ public class MaterialController extends BaseController {
@Resource
private ShipmentMaterialControllerService shipmentMaterialControllerService;
@Resource
private FileUploadService fileUploadService;
/**
* 新增图纸
*/
@ -164,7 +174,11 @@ public class MaterialController extends BaseController {
dbMaterial.setDescribe(data.getDescribe());
dbMaterial.setDescribeEn(data.getDescribeEn());
dbMaterial.setDrawingNo(data.getDrawingNo());
dbMaterial.setImage(data.getImage());
if (StrUtil.isNotBlank(data.getImageBase64())) {
dbMaterial.setImage(uploadBase64(data.getImageBase64()));
}else {
dbMaterial.setImage(data.getImage());
}
dbMaterial.setWeight(data.getWeight());
dbMaterial.setLength(data.getLength());
dbMaterial.setWidth(data.getWidth());
@ -173,7 +187,7 @@ public class MaterialController extends BaseController {
dbMaterial.setUpdateTime(LocalDateTime.now());
shipmentMaterialService.updateById(dbMaterial);
});
if (CollectionUtil.isNotEmpty(dbMaterials)){
if (CollectionUtil.isNotEmpty(dbMaterials)) {
shipmentMaterialService.updateBatchById(dbMaterials);
}
datas.removeIf(data -> dbMaterials.stream().anyMatch(dbMaterial -> dbMaterial.getNo().equals(data.getNo())));
@ -188,6 +202,24 @@ public class MaterialController extends BaseController {
return ApiResult.success();
}
private String uploadBase64(String base64) {
try {
return fileUploadService.upload(buildFilePath(base64), base64);
} catch (Exception e) {
log.error("上传图片失败", e);
return null;
}
}
private String buildFilePath(String base64) {
return StrUtil.format("admin/{}/{}/{}{}", DateTimeUtil.format(LocalDate.now())
, RandomUtil.randomString(4), IdUtil.fastUUID(), getFileType(base64));
}
private String getFileType(String base64) {
return "."+base64.substring(base64.indexOf("/") + 1, base64.indexOf(";"));
}
/**
* 同步-删除
* @param nos 物料编号列表

View File

@ -9,7 +9,6 @@ public interface FileUploadService {
/**
* 上传文件
*
* @param filePath 文件完整路径: /cfs/xxx.jpg
* @param file 文件
* @return 可访问的url
@ -19,7 +18,6 @@ public interface FileUploadService {
/**
* 上传文件
*
* @param filePath 文件完整路径: /cfs/xxx.jpg
* @param stream 文件流
* @return 可访问的url
@ -27,4 +25,13 @@ public interface FileUploadService {
*/
String upload(String filePath, InputStream stream, String contentType) throws Exception;
/**
* 上传文件
* @param filePath 文件完整路径: /cfs/xxx.jpg
* @param base64 base64字符串
* @return 可访问的url
* @throws IOException
*/
String upload(String filePath, String base64) throws Exception;
}

View File

@ -12,8 +12,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
@Service
@ConditionalOnProperty(name = "file.upload.type", havingValue = "oss")
@ -41,4 +43,18 @@ public class OSSFileUploadServiceImpl implements FileUploadService {
//log.debug("上传文件结果: " + result);
return StrUtil.format("{}/{}", domain, filePath);
}
@Override
public String upload(String filePath, String base64) throws Exception {
String contentType = "";
// 去掉前缀
if (base64.contains(",")) {
String header = base64.substring(0, base64.indexOf(","));
if (header.startsWith("data:") && header.contains(";")) {
contentType = header.substring(5, header.indexOf(";"));
}
base64 = base64.substring(base64.indexOf(",") + 1);
}
return upload(filePath, new ByteArrayInputStream(Base64.getDecoder().decode(base64)), contentType);
}
}

View File

@ -15,7 +15,9 @@ import software.amazon.awssdk.services.s3.model.HeadBucketRequest;
import software.amazon.awssdk.services.s3.model.NoSuchBucketException;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Base64;
@Slf4j
@Service
@ -50,6 +52,20 @@ public class RustFSServiceImpl implements FileUploadService {
return StrUtil.format("{}/{}/{}", domain, bucketName, filePath);
}
@Override
public String upload(String filePath, String base64) throws Exception {
String contentType = "";
// 去掉前缀
if (base64.contains(",")) {
String header = base64.substring(0, base64.indexOf(","));
if (header.startsWith("data:") && header.contains(";")) {
contentType = header.substring(5, header.indexOf(";"));
}
base64 = base64.substring(base64.indexOf(",") + 1);
}
return upload(filePath, new ByteArrayInputStream(Base64.getDecoder().decode(base64)), contentType);
}
private void ensureBucketExists() {
try {
s3Client.headBucket(HeadBucketRequest.builder().bucket(bucketName).build());