|
@@ -18,7 +18,6 @@ import com.hfln.portal.common.request.user.*;
|
|
|
import com.hfln.portal.common.response.user.UserInfoWxRes;
|
|
|
import com.hfln.portal.common.response.user.UserTokenInfo;
|
|
|
import com.hfln.portal.domain.customer.DeviceType;
|
|
|
-import com.hfln.portal.domain.customer.OssBusiType;
|
|
|
import com.hfln.portal.domain.customer.util.CopyUtils;
|
|
|
import com.hfln.portal.domain.customer.util.PasswordUtil;
|
|
|
import com.hfln.portal.domain.customer.util.WxOfficeAccountClient;
|
|
@@ -27,13 +26,7 @@ import com.hfln.portal.domain.gateway.UserGateway;
|
|
|
import com.hfln.portal.infrastructure.oss.OssClient;
|
|
|
import com.hfln.portal.infrastructure.oss.OssUtils;
|
|
|
import com.hfln.portal.infrastructure.po.*;
|
|
|
-import com.hfln.portal.infrastructure.service.DevGroupService;
|
|
|
-import com.hfln.portal.infrastructure.service.DevInfoService;
|
|
|
-import com.hfln.portal.infrastructure.service.DevShareService;
|
|
|
-import com.hfln.portal.infrastructure.service.GroupShareService;
|
|
|
-import com.hfln.portal.infrastructure.service.OssFileService;
|
|
|
-import com.hfln.portal.infrastructure.service.UserService;
|
|
|
-import com.hfln.portal.infrastructure.service.WxRelationService;
|
|
|
+import com.hfln.portal.infrastructure.service.*;
|
|
|
import lombok.SneakyThrows;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
|
|
@@ -54,7 +47,8 @@ import org.springframework.web.client.RestTemplate;
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
-import java.io.InputStream;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.List;
|
|
|
import java.util.Objects;
|
|
@@ -94,6 +88,9 @@ public class UserGatewayImpl implements UserGateway {
|
|
|
@Value("${lnxx.wechat.bind.callbackUrl}")
|
|
|
private String callbackUrl;
|
|
|
|
|
|
+ @Value("${oss.download-url-pre}")
|
|
|
+ private String downloadUrlPre;
|
|
|
+
|
|
|
@Autowired
|
|
|
private WxMpService wxMpService;
|
|
|
|
|
@@ -518,48 +515,48 @@ public class UserGatewayImpl implements UserGateway {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public void uploadCarousel(MultipartFile file) throws IOException {
|
|
|
- // 校验文件非空
|
|
|
- if (file.isEmpty()) {
|
|
|
- throw new BizException(ErrorEnum.FILE_IS_EMPTY.getErrorCode(), ErrorEnum.FILE_IS_EMPTY.getErrorMessage());
|
|
|
- }
|
|
|
-
|
|
|
- // 校验文件类型
|
|
|
- String contentType = file.getContentType();
|
|
|
- if (contentType == null || (!contentType.equalsIgnoreCase("image/png") && !contentType.equalsIgnoreCase("image/jpeg"))) {
|
|
|
- throw new BizException(ErrorEnum.FILE_ONLY_PNG_JPG.getErrorCode(), ErrorEnum.FILE_ONLY_PNG_JPG.getErrorMessage());
|
|
|
- }
|
|
|
-
|
|
|
- // 校验文件头
|
|
|
- byte[] fileHeader = new byte[8];
|
|
|
- try (InputStream is = file.getInputStream()) {
|
|
|
- int readBytes = is.read(fileHeader);
|
|
|
- if (readBytes < 8) {
|
|
|
- throw new BizException(ErrorEnum.FILE_NOT_COMPLETE.getErrorCode(), ErrorEnum.FILE_NOT_COMPLETE.getErrorMessage());
|
|
|
- }
|
|
|
- }
|
|
|
- boolean isPng = checkPngMagicNumber(fileHeader);
|
|
|
- boolean isJpeg = checkJpegMagicNumber(fileHeader);
|
|
|
-
|
|
|
- if (!isPng && !isJpeg) {
|
|
|
- throw new BizException(ErrorEnum.FILE_ONLY_PNG_JPG02.getErrorCode(), ErrorEnum.FILE_ONLY_PNG_JPG02.getErrorMessage());
|
|
|
- }
|
|
|
-
|
|
|
- // 生成OSS对象名称
|
|
|
- String objectName = OssUtils.getObjectName(OssBusiType.CAROUSEL.getCode(), file.getOriginalFilename());
|
|
|
-
|
|
|
- // 上传文件到OSS
|
|
|
- ossClient.upload(file.getInputStream(), OssUtils.BUCKET_NAME, objectName);
|
|
|
-
|
|
|
- // 保存文件记录到数据库
|
|
|
- TblOssFile ossFile = new TblOssFile();
|
|
|
- ossFile.setBusiType(OssBusiType.CAROUSEL.getCode());
|
|
|
- ossFile.setBusiKey("0");
|
|
|
- ossFile.setFileName(file.getOriginalFilename());
|
|
|
- ossFile.setOssUrl(OssUtils.BUCKET_NAME + "/" + objectName);
|
|
|
- ossFileService.save(ossFile);
|
|
|
- }
|
|
|
+// @Override
|
|
|
+// public void uploadCarousel(MultipartFile file) throws IOException {
|
|
|
+// // 校验文件非空
|
|
|
+// if (file.isEmpty()) {
|
|
|
+// throw new BizException(ErrorEnum.FILE_IS_EMPTY.getErrorCode(), ErrorEnum.FILE_IS_EMPTY.getErrorMessage());
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 校验文件类型
|
|
|
+// String contentType = file.getContentType();
|
|
|
+// if (contentType == null || (!contentType.equalsIgnoreCase("image/png") && !contentType.equalsIgnoreCase("image/jpeg"))) {
|
|
|
+// throw new BizException(ErrorEnum.FILE_ONLY_PNG_JPG.getErrorCode(), ErrorEnum.FILE_ONLY_PNG_JPG.getErrorMessage());
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 校验文件头
|
|
|
+// byte[] fileHeader = new byte[8];
|
|
|
+// try (InputStream is = file.getInputStream()) {
|
|
|
+// int readBytes = is.read(fileHeader);
|
|
|
+// if (readBytes < 8) {
|
|
|
+// throw new BizException(ErrorEnum.FILE_NOT_COMPLETE.getErrorCode(), ErrorEnum.FILE_NOT_COMPLETE.getErrorMessage());
|
|
|
+// }
|
|
|
+// }
|
|
|
+// boolean isPng = checkPngMagicNumber(fileHeader);
|
|
|
+// boolean isJpeg = checkJpegMagicNumber(fileHeader);
|
|
|
+//
|
|
|
+// if (!isPng && !isJpeg) {
|
|
|
+// throw new BizException(ErrorEnum.FILE_ONLY_PNG_JPG02.getErrorCode(), ErrorEnum.FILE_ONLY_PNG_JPG02.getErrorMessage());
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 生成OSS对象名称
|
|
|
+// String objectName = OssUtils.getObjectName(OssBusiType.CAROUSEL.getCode(), file.getOriginalFilename());
|
|
|
+//
|
|
|
+// // 上传文件到OSS
|
|
|
+// ossClient.upload(file.getInputStream(), OssUtils.BUCKET_NAME, objectName);
|
|
|
+//
|
|
|
+// // 保存文件记录到数据库
|
|
|
+// TblOssFile ossFile = new TblOssFile();
|
|
|
+// ossFile.setBusiType(OssBusiType.CAROUSEL.getCode());
|
|
|
+// ossFile.setBusiKey("0");
|
|
|
+// ossFile.setFileName(file.getOriginalFilename());
|
|
|
+// ossFile.setOssUrl(OssUtils.BUCKET_NAME + "/" + objectName);
|
|
|
+// ossFileService.save(ossFile);
|
|
|
+// }
|
|
|
|
|
|
@Override
|
|
|
public List<OssFileDTO> getFileList(String fileType) {
|
|
@@ -574,7 +571,7 @@ public class UserGatewayImpl implements UserGateway {
|
|
|
dto.setBusiType(ossFile.getBusiType());
|
|
|
dto.setFileName(ossFile.getFileName());
|
|
|
// 获取可访问的URL
|
|
|
- dto.setFileUrl(ossClient.getDownloadUrl(ossFile.getOssUrl()));
|
|
|
+ dto.setOssUrl(ossFile.getOssUrl());
|
|
|
return dto;
|
|
|
})
|
|
|
.collect(Collectors.toList());
|
|
@@ -618,22 +615,75 @@ public class UserGatewayImpl implements UserGateway {
|
|
|
throw new BizException(ErrorEnum.FILE_TYPE_IS_NULL.getErrorCode(), ErrorEnum.FILE_TYPE_IS_NULL.getErrorMessage());
|
|
|
}
|
|
|
|
|
|
- // 生成OSS对象名称,直接使用文件类型作为业务类型
|
|
|
- String objectName = OssUtils.getObjectName(fileType, file.getOriginalFilename());
|
|
|
+ // 获取原始文件名
|
|
|
+ String originalFilename = file.getOriginalFilename();
|
|
|
+ if (originalFilename == null) {
|
|
|
+ throw new BizException(ErrorEnum.FILE_IS_EMPTY.getErrorCode(), "文件名不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成OSS对象名称,使用原始文件名
|
|
|
+ String objectName = generateCommonObjectName(fileType, originalFilename);
|
|
|
|
|
|
// 上传文件到OSS
|
|
|
ossClient.upload(file.getInputStream(), OssUtils.BUCKET_NAME, objectName);
|
|
|
|
|
|
- // 保存文件记录到数据库
|
|
|
- TblOssFile ossFile = new TblOssFile();
|
|
|
- ossFile.setBusiType(fileType); // 直接使用前端传入的文件类型作为业务类型
|
|
|
- ossFile.setBusiKey("0"); // 业务主键设为默认值
|
|
|
- ossFile.setFileName(file.getOriginalFilename());
|
|
|
- ossFile.setOssUrl(OssUtils.BUCKET_NAME + "/" + objectName);
|
|
|
- ossFileService.save(ossFile);
|
|
|
+ // 查询是否已存在相同文件名和业务类型的记录
|
|
|
+ TblOssFile existingFile = ossFileService.queryOneFile(fileType, "0");
|
|
|
+ if (existingFile != null && originalFilename.equals(existingFile.getFileName())) {
|
|
|
+ // 如果存在相同文件名和业务类型的记录,则更新现有记录
|
|
|
+ log.info("发现相同文件名和业务类型的记录,执行覆盖操作:文件名={}, 业务类型={}", originalFilename, fileType);
|
|
|
+
|
|
|
+ // 删除旧的OSS文件
|
|
|
+ try {
|
|
|
+ String oldOssUrl = existingFile.getOssUrl();
|
|
|
+ if (oldOssUrl != null && oldOssUrl.contains("/")) {
|
|
|
+ // 从完整URL中提取objectName
|
|
|
+ String oldObjectName = oldOssUrl.substring(oldOssUrl.indexOf("/") + 1);
|
|
|
+ // 使用bucketName/objectName格式删除
|
|
|
+ String deleteUrl = OssUtils.BUCKET_NAME + "/" + oldObjectName;
|
|
|
+ ossClient.delete(deleteUrl);
|
|
|
+ log.info("已删除旧的OSS文件:{}", oldObjectName);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("删除旧OSS文件失败,继续执行覆盖操作:{}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新数据库记录
|
|
|
+ String fullOssUrl = downloadUrlPre + objectName;
|
|
|
+ existingFile.setOssUrl(fullOssUrl);
|
|
|
+ ossFileService.updateById(existingFile);
|
|
|
+
|
|
|
+ log.info("文件覆盖成功:文件名={}, 业务类型={}", originalFilename, fileType);
|
|
|
+ } else {
|
|
|
+ // 如果不存在,则创建新记录
|
|
|
+ TblOssFile ossFile = new TblOssFile();
|
|
|
+ ossFile.setBusiType(fileType); // 直接使用前端传入的文件类型作为业务类型
|
|
|
+ ossFile.setBusiKey("0"); // 业务主键设为默认值
|
|
|
+ ossFile.setFileName(originalFilename); // 使用原始文件名
|
|
|
+ String fullOssUrl = downloadUrlPre + objectName;
|
|
|
+ ossFile.setOssUrl(fullOssUrl);
|
|
|
+ ossFileService.save(ossFile);
|
|
|
+
|
|
|
+ log.info("新文件上传成功:文件名={}, OSS路径={}", originalFilename, objectName);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ /**
|
|
|
+ * 生成通用文件的OSS对象名称,保留原始文件名
|
|
|
+ * @param fileType 文件类型
|
|
|
+ * @param originalFilename 原始文件名
|
|
|
+ * @return OSS对象名称
|
|
|
+ */
|
|
|
+ private String generateCommonObjectName(String fileType, String originalFilename) {
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ sb.append(fileType)
|
|
|
+ .append("/")
|
|
|
+ .append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")))
|
|
|
+ .append("/")
|
|
|
+ .append(originalFilename); // 直接使用原始文件名
|
|
|
+
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
|
|
|
private boolean checkPngMagicNumber(byte[] fileHeader) {
|
|
|
byte[] pngMagicNumber = {(byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
|