feat:添加APP版本管理相关代码
This commit is contained in:
@@ -29,6 +29,7 @@ package org.springblade.auth;
|
|||||||
import org.springblade.core.cloud.client.BladeCloudApplication;
|
import org.springblade.core.cloud.client.BladeCloudApplication;
|
||||||
import org.springblade.core.launch.BladeApplication;
|
import org.springblade.core.launch.BladeApplication;
|
||||||
import org.springblade.core.launch.constant.AppConstant;
|
import org.springblade.core.launch.constant.AppConstant;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,6 +39,7 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR
|
|||||||
*/
|
*/
|
||||||
@EnableRedisHttpSession
|
@EnableRedisHttpSession
|
||||||
@BladeCloudApplication
|
@BladeCloudApplication
|
||||||
|
@ComponentScan({"org.springblade.auth", "org.springblade.**.feign"})
|
||||||
public class AuthApplication {
|
public class AuthApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -27,6 +27,18 @@
|
|||||||
<artifactId>blade-core-auto</artifactId>
|
<artifactId>blade-core-auto</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.huaweicloud</groupId>
|
||||||
|
<artifactId>esdk-obs-java-bundle</artifactId>
|
||||||
|
<version>3.24.9</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.11.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -0,0 +1,277 @@
|
|||||||
|
package org.springblade.common.utils;
|
||||||
|
|
||||||
|
import com.alibaba.cloud.commons.lang.StringUtils;
|
||||||
|
import com.obs.services.ObsClient;
|
||||||
|
import com.obs.services.exception.ObsException;
|
||||||
|
import com.obs.services.model.*;
|
||||||
|
import jakarta.activation.MimetypesFileTypeMap;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName: OBSUtil
|
||||||
|
* @Description:
|
||||||
|
* @Author: zhaowei
|
||||||
|
* @Date: 2024/8/22
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ObsUtil {
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(ObsUtil.class);
|
||||||
|
|
||||||
|
private static MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
|
||||||
|
/**
|
||||||
|
* 华为云OBS
|
||||||
|
*/
|
||||||
|
public static String obsEndpoint;
|
||||||
|
public static String obsAccessKeyId;
|
||||||
|
public static String obsAccessKeySecret;
|
||||||
|
public static String obsBucketName;
|
||||||
|
public static String obsRootDirectory;
|
||||||
|
|
||||||
|
@Value("${obs.endpoint}")
|
||||||
|
public void setObsEndpoint(String endpoint) {
|
||||||
|
ObsUtil.obsEndpoint = endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value("${obs.access-key-id}")
|
||||||
|
public void setObsAccessKeyId(String accessKeyId) {
|
||||||
|
ObsUtil.obsAccessKeyId = accessKeyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value("${obs.access-key-secret}")
|
||||||
|
public void setObsAccessKeySecret(String accessKeySecret) {
|
||||||
|
ObsUtil.obsAccessKeySecret = accessKeySecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value("${obs.bucket-name}")
|
||||||
|
public void setObsBucketName(String bucketName) {
|
||||||
|
ObsUtil.obsBucketName = bucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value("${obs.root-directory}")
|
||||||
|
public void setObsRootDirectory(String rootDirectory) {
|
||||||
|
ObsUtil.obsRootDirectory = rootDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 如果Bucket不存在,则创建它。
|
||||||
|
private static void ensureBucket(ObsClient client, String bucketName) throws ObsException {
|
||||||
|
|
||||||
|
if (client.headBucket(bucketName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 创建bucket
|
||||||
|
client.createBucket(bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 把Bucket设置为所有人可读
|
||||||
|
private static void setBucketPublicReadable(String bucketName) throws ObsException {
|
||||||
|
//华为云OBS
|
||||||
|
ObsClient obsClient = new ObsClient(obsAccessKeyId, obsAccessKeySecret, obsEndpoint);
|
||||||
|
if (obsClient.doesObjectExist(obsBucketName, obsRootDirectory)) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
obsClient.createBucket(obsBucketName);
|
||||||
|
}
|
||||||
|
obsClient.setBucketAcl(obsBucketName, com.obs.services.model.AccessControlList.REST_CANNED_PUBLIC_READ_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传一个Object
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param content
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
*/
|
||||||
|
public static String putObject(String key, InputStream content) throws IOException {
|
||||||
|
//华为云OBS
|
||||||
|
ObsClient obsClient = new ObsClient(obsAccessKeyId, obsAccessKeySecret, obsEndpoint);
|
||||||
|
try {
|
||||||
|
obsClient.putObject(obsBucketName, key, content);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("obs put object error", e);
|
||||||
|
throw new RuntimeException("obs eror" + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
obsClient.close();
|
||||||
|
}
|
||||||
|
return getExpireUrl(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
* @param objectKey 上传到OBS起的名
|
||||||
|
* @param filename 文件下载到本地保存的路径
|
||||||
|
* @throws ObsException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void downloadFile(String objectKey, String filename) throws ObsException, IOException {
|
||||||
|
//华为云OBS
|
||||||
|
ObsClient obsClient = new ObsClient(obsAccessKeyId, obsAccessKeySecret, obsEndpoint);
|
||||||
|
try {
|
||||||
|
obsClient.getObject(obsBucketName, objectKey);
|
||||||
|
} finally {
|
||||||
|
obsClient.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除一个Bucket和其中的Objects
|
||||||
|
*
|
||||||
|
* @param bucketName Bucket名
|
||||||
|
* @throws ObsException
|
||||||
|
*/
|
||||||
|
private static void deleteBucket(String bucketName) throws ObsException {
|
||||||
|
ObsClient obsClient = new ObsClient(obsAccessKeyId, obsAccessKeySecret, obsEndpoint);
|
||||||
|
com.obs.services.model.ObjectListing objectListing = obsClient.listObjects(bucketName);
|
||||||
|
List<ObsObject> listObject = objectListing.getObjects();
|
||||||
|
for (ObsObject o : listObject) {
|
||||||
|
obsClient.deleteObject(bucketName, o.getObjectKey());
|
||||||
|
}
|
||||||
|
obsClient.deleteBucket(bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除Object
|
||||||
|
* @param objList Object的key(目录路径/文件名)
|
||||||
|
*/
|
||||||
|
public static void delelteObjectList(List<String> objList) {
|
||||||
|
ObsClient obsClient = new ObsClient(obsAccessKeyId, obsAccessKeySecret, obsEndpoint);
|
||||||
|
for (String key : objList) {
|
||||||
|
obsClient.deleteObject(obsBucketName, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除Object
|
||||||
|
* @param key 目录路径/文件名
|
||||||
|
*/
|
||||||
|
public static void delelteObject(String key) {
|
||||||
|
ObsClient obsClient = new ObsClient(obsAccessKeyId, obsAccessKeySecret, obsEndpoint);
|
||||||
|
obsClient.deleteObject(obsBucketName, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过key获取带签名的url
|
||||||
|
*/
|
||||||
|
public static String getExpireUrl(String key) {
|
||||||
|
String fileUrl = "";
|
||||||
|
ObsClient obsClient = new ObsClient(obsAccessKeyId, obsAccessKeySecret, obsEndpoint);
|
||||||
|
// URL有效期,3600秒.5分钟
|
||||||
|
// long expireSeconds = 3600L;
|
||||||
|
// 约等于1年
|
||||||
|
long expireSeconds = 31536000L;
|
||||||
|
TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expireSeconds);
|
||||||
|
request.setBucketName(obsBucketName);
|
||||||
|
request.setObjectKey(key);
|
||||||
|
TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
|
||||||
|
fileUrl = response.getSignedUrl();
|
||||||
|
return fileUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件至OSS并且返回链接地址
|
||||||
|
* @param url 远程路径
|
||||||
|
* @param ossDir OSS目录
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @return 文件OSS链接
|
||||||
|
* @modify
|
||||||
|
*/
|
||||||
|
public static String uploadFile2Oss(URL url, String ossDir, String fileName) {
|
||||||
|
InputStream is;
|
||||||
|
String key = ossDir + fileName;
|
||||||
|
try {
|
||||||
|
is = url.openStream();
|
||||||
|
return uploadFile2OSS(is, key);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("上传失败!", ex);
|
||||||
|
}
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传到OSS服务器 如果同名文件会覆盖服务器上的
|
||||||
|
*
|
||||||
|
* @param inputStream 文件流
|
||||||
|
* @return 返回文件访问路径
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public static String uploadFile2OSS(InputStream inputStream, String key) {
|
||||||
|
ObjectMetadata objectMetadata = new ObjectMetadata();
|
||||||
|
objectMetadata.setCacheControl("no-cache");
|
||||||
|
String fileName = FilenameUtils.getName(key);
|
||||||
|
objectMetadata.setContentType(fileTypeMap.getContentType(fileName));
|
||||||
|
objectMetadata.addUserMetadata("filename", fileName);
|
||||||
|
|
||||||
|
ObsClient obsClient = new ObsClient(obsAccessKeyId,
|
||||||
|
obsAccessKeySecret, obsEndpoint);
|
||||||
|
try {
|
||||||
|
obsClient.putObject(obsBucketName, obsRootDirectory + key, inputStream, objectMetadata);
|
||||||
|
return obsRootDirectory + "/" + key;
|
||||||
|
} finally {
|
||||||
|
obsClient.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public Boolean checkObjectExist(String key) {
|
||||||
|
Boolean existsFlag = false;
|
||||||
|
ObsClient obsClient = new ObsClient(obsAccessKeyId, obsAccessKeySecret, obsEndpoint);
|
||||||
|
try {
|
||||||
|
existsFlag = obsClient.doesObjectExist(obsBucketName, key);
|
||||||
|
} finally {
|
||||||
|
obsClient.close();
|
||||||
|
}
|
||||||
|
return existsFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
* @param objectKey 上传到OBS起的名
|
||||||
|
* @param filename 文件下载到本地保存的路径
|
||||||
|
* @throws ObsException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void downloadFileNew(String objectKey, String filename){
|
||||||
|
//华为云OBS
|
||||||
|
ObsClient obsClient = new ObsClient(obsAccessKeyId, obsAccessKeySecret, obsEndpoint);
|
||||||
|
try {
|
||||||
|
ObsObject ossObject = obsClient.getObject(obsBucketName, objectKey);
|
||||||
|
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
try {
|
||||||
|
outputStream = new BufferedOutputStream(new FileOutputStream(filename));
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = ossObject.getObjectContent().read(buffer)) != -1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
} finally {
|
||||||
|
if (outputStream != null) {
|
||||||
|
try {
|
||||||
|
outputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (obsClient != null) {
|
||||||
|
try {
|
||||||
|
obsClient.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,3 @@ knife4j:
|
|||||||
- blade-admin
|
- blade-admin
|
||||||
- blade-gateway
|
- blade-gateway
|
||||||
- blade-log
|
- blade-log
|
||||||
|
|
||||||
server:
|
|
||||||
port: 28080
|
|
||||||
|
|||||||
22
blade-service-api/blade-file-api/pom.xml
Normal file
22
blade-service-api/blade-file-api/pom.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springblade</groupId>
|
||||||
|
<artifactId>blade-service-api</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>blade-file-api</artifactId>
|
||||||
|
<name>${project.artifactId}</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springblade</groupId>
|
||||||
|
<artifactId>blade-ocr-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.springblade.file.callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压回调接口
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/11/8
|
||||||
|
*/
|
||||||
|
public interface UnzipCallback {
|
||||||
|
/**
|
||||||
|
* 解压任务的业务编码
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getBizCode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调接口
|
||||||
|
* @param bizId 业务id
|
||||||
|
* @param event 事件 org.springblade.file.callback.UnzipEventType name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean callback(Long bizId, String event);
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.springblade.file.callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压事件类型
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/11/15
|
||||||
|
*/
|
||||||
|
public enum UnzipEventType {
|
||||||
|
/**
|
||||||
|
* 开始解压
|
||||||
|
*/
|
||||||
|
START,
|
||||||
|
/**
|
||||||
|
* 解压成功
|
||||||
|
*/
|
||||||
|
SUCCESS,
|
||||||
|
/**
|
||||||
|
* 解压失败
|
||||||
|
*/
|
||||||
|
FAIL,
|
||||||
|
;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.springblade.file.config;
|
||||||
|
|
||||||
|
import feign.codec.Encoder;
|
||||||
|
import feign.form.spring.SpringFormEncoder;
|
||||||
|
import org.springframework.beans.factory.ObjectFactory;
|
||||||
|
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||||
|
import org.springframework.cloud.openfeign.support.SpringEncoder;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2025/4/9
|
||||||
|
*/
|
||||||
|
public class FeignFileUploadClientConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Encoder feignFormEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
|
||||||
|
return new SpringFormEncoder(new SpringEncoder(messageConverters));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
package org.springblade.file.feign;
|
||||||
|
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import org.springblade.core.launch.constant.AppConstant;
|
||||||
|
import org.springblade.core.tool.api.FR;
|
||||||
|
import org.springblade.file.pojo.dto.*;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
import org.springblade.file.pojo.vo.*;
|
||||||
|
import org.springblade.thirdparty.ocr.pojo.vo.TransportCertificateVO;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.cloud.openfeign.SpringQueryMap;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/21
|
||||||
|
*/
|
||||||
|
@FeignClient(
|
||||||
|
value = AppConstant.APPLICATION_FILE_NAME,
|
||||||
|
fallback = IFileClientFallback.class
|
||||||
|
)
|
||||||
|
public interface IFileClient {
|
||||||
|
|
||||||
|
String API_PREFIX = "/feign/client/file";
|
||||||
|
String ATTACHMENT = API_PREFIX + "/attachment";
|
||||||
|
String ATTACHMENT_DETAIL = API_PREFIX + "/attachment-detail";
|
||||||
|
String BUSINESS_ATTACHMENT_SAVE_REMOVE = API_PREFIX + "/businessAttachment-save-remove";
|
||||||
|
String BUSINESS_ATTACHMENT_BATCH_SAVE_REMOVE = API_PREFIX + "/businessAttachment-batch-save-remove";
|
||||||
|
String BUSINESS_ATTACHMENT_BATCH_SAVE_REMOVE_BY_PARAM = API_PREFIX + "/businessAttachment-batch-save-remove-by-param";
|
||||||
|
String BUSINESS_ATTACHMENT_BATCH_SAVE_REMOVE_NO_BIZ_ID = API_PREFIX + "/businessAttachment-batch-save-remove-no-bizId";
|
||||||
|
String BUSINESS_ATTACHMENT_REMOVE = API_PREFIX + "/businessAttachment-remove";
|
||||||
|
String BUSINESS_ATTACHMENT_LIST = API_PREFIX + "/businessAttachment-list";
|
||||||
|
String BUSINESS_UNZIP_TASK_SAVE = API_PREFIX + "/businessUnzipTask-save";
|
||||||
|
String BUSINESS_UNZIP_TASK_UPDATE = API_PREFIX + "/businessUnzipTask-update";
|
||||||
|
String BUSINESS_UNZIP_TASK_CANCEL = API_PREFIX + "/businessUnzipTask-cancel";
|
||||||
|
String BUSINESS_UNZIP_TASK_REMOVE = API_PREFIX + "/businessUnzipTask-remove";
|
||||||
|
String BUSINESS_UNZIP_TASK_LIST = API_PREFIX + "/businessUnzipTask-list";
|
||||||
|
String BUSINESS_UNZIP_DETAIL_LIST = API_PREFIX + "/businessUnzipDetail-list";
|
||||||
|
String RECOGNITION_TRANSPORT_CERTIFICATE = API_PREFIX + "/recognitionTransportCertificate";
|
||||||
|
String FILE_URLS = API_PREFIX + "/getFileUrls";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取附件,多个附件id用逗号分割
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return List<Attachment>
|
||||||
|
*/
|
||||||
|
@GetMapping(ATTACHMENT)
|
||||||
|
FR<List<Attachment>> getAttachment(@RequestParam("id") String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取附件详情
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return List<Attachment>
|
||||||
|
*/
|
||||||
|
@GetMapping(ATTACHMENT_DETAIL)
|
||||||
|
FR<AttachmentDetailVO> getAttachmentDetail(@RequestParam("id") Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存并删除业务附件,remove为true,先用bizId删除,再新增
|
||||||
|
*
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_ATTACHMENT_SAVE_REMOVE)
|
||||||
|
FR saveAndRemoveBusinessAttachment(@RequestBody @Validated BusinessAttachmentBatchAddDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量保存并删除业务附件,先删除附件,再新增,业务id为空,从params中获取bizId,先删除
|
||||||
|
*
|
||||||
|
* @param params 参数为空不新增
|
||||||
|
* @param bizId 业务id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_ATTACHMENT_BATCH_SAVE_REMOVE)
|
||||||
|
FR batchSaveAndRemoveBusinessAttachment(@RequestBody List<@Valid BusinessAttachmentAddDTO> params, @RequestParam(value = "bizId", required = false) Long bizId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量保存并删除业务附件,deleteParam为空,从params获取bizId删除,不为空,使用bizIds和bizCodes删除附件,bizCodes为空删除所有bizIds的附件
|
||||||
|
* deleteParam 中 delete 为false,不删除
|
||||||
|
*
|
||||||
|
* @param params 参数为空不新增
|
||||||
|
* @param deleteParam 删除参数,支持只删除业务编码参数的附件
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_ATTACHMENT_BATCH_SAVE_REMOVE_BY_PARAM)
|
||||||
|
FR batchSaveAndRemoveByParamBusinessAttachment(@RequestBody List<@Valid BusinessAttachmentAddDTO> params, @Valid @SpringQueryMap BusinessAttachmentDeleteDTO deleteParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量保存并删除业务附件,从参数中提取所有bizId
|
||||||
|
*
|
||||||
|
* @param params 参数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_ATTACHMENT_BATCH_SAVE_REMOVE_NO_BIZ_ID)
|
||||||
|
FR batchSaveAndRemoveBusinessAttachment(@RequestBody List<@Valid BusinessAttachmentAddDTO> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据业务id删除业务附件
|
||||||
|
*
|
||||||
|
* @param bizId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_ATTACHMENT_REMOVE)
|
||||||
|
FR removeBusinessAttachment(@NotNull(message = "业务id不能为空") @RequestParam(value = "bizId", required = false) Long bizId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询业务附件列表
|
||||||
|
*
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_ATTACHMENT_LIST)
|
||||||
|
FR<List<BusinessAttachmentVO>> getBusinessAttachments(@Validated @RequestBody BusinessAttachmentQueryDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存业务解压任务
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_UNZIP_TASK_SAVE)
|
||||||
|
FR saveBusinessUnzipTask(@Validated @RequestBody BusinessUnzipTaskAddDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新业务解压任务(重新上传)
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_UNZIP_TASK_UPDATE)
|
||||||
|
FR updateBusinessUnzipTask(@Validated @RequestBody BusinessUnzipTaskUpdateDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消业务解压任务
|
||||||
|
* @param bizId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_UNZIP_TASK_CANCEL)
|
||||||
|
FR cancelBusinessUnzipTask(@NotNull(message = "业务id不能为空") @RequestParam("bizId") Long bizId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除业务解压任务
|
||||||
|
* @param bizId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_UNZIP_TASK_REMOVE)
|
||||||
|
FR removeBusinessUnzipTask(@NotNull(message = "业务id不能为空") @RequestParam("bizId") Long bizId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据业务id列表查询业务解压任务列表
|
||||||
|
* @param bizIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(BUSINESS_UNZIP_TASK_LIST)
|
||||||
|
FR<List<BusinessUnzipTaskListVO>> getBusinessUnzipTasksByBizIds(@Validated @NotEmpty(message = "业务id列表不能为空") @RequestBody List<Long> bizIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询解压明细列表
|
||||||
|
* @param bizId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping(BUSINESS_UNZIP_DETAIL_LIST)
|
||||||
|
FR<List<BusinessUnzipDetailListVO>> queryBusinessUnzipDetail(@NotNull(message = "业务id不能为空") @RequestParam("bizId") Long bizId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 识别车辆运输凭证
|
||||||
|
*
|
||||||
|
* @param param 同一车牌文件夹下的附件objectKey列表
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(RECOGNITION_TRANSPORT_CERTIFICATE)
|
||||||
|
FR<TransportCertificateVO> recognitionTransportCertificates(@Validated @RequestBody FileCertificateBatchRecognitionDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量获取附件下载地址
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(FILE_URLS)
|
||||||
|
FR<List<FileUrlVO>> getFileUrls(@Validated @RequestBody IdsDTO param);
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package org.springblade.file.feign;
|
||||||
|
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springblade.core.tool.api.FR;
|
||||||
|
import org.springblade.file.pojo.dto.*;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
import org.springblade.file.pojo.vo.*;
|
||||||
|
import org.springblade.thirdparty.ocr.pojo.vo.TransportCertificateVO;
|
||||||
|
import org.springframework.cloud.openfeign.SpringQueryMap;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/21
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class IFileClientFallback implements IFileClient, IFileUploadClient {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<Attachment>> getAttachment(String id) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<AttachmentDetailVO> getAttachmentDetail(Long id) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR saveAndRemoveBusinessAttachment(BusinessAttachmentBatchAddDTO param) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR batchSaveAndRemoveBusinessAttachment(List<BusinessAttachmentAddDTO> params, Long bizId) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR batchSaveAndRemoveByParamBusinessAttachment(List<@Valid BusinessAttachmentAddDTO> params, @Valid @SpringQueryMap BusinessAttachmentDeleteDTO deleteParam) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR batchSaveAndRemoveBusinessAttachment(List<@Valid BusinessAttachmentAddDTO> params) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR removeBusinessAttachment(Long bizId) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<BusinessAttachmentVO>> getBusinessAttachments(BusinessAttachmentQueryDTO param) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR saveBusinessUnzipTask(BusinessUnzipTaskAddDTO param) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR updateBusinessUnzipTask(BusinessUnzipTaskUpdateDTO param) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR cancelBusinessUnzipTask(Long bizId) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR removeBusinessUnzipTask(Long bizId) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<BusinessUnzipTaskListVO>> getBusinessUnzipTasksByBizIds(List<Long> bizIds) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<BusinessUnzipDetailListVO>> queryBusinessUnzipDetail(Long bizId) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<TransportCertificateVO> recognitionTransportCertificates(@Validated @RequestBody FileCertificateBatchRecognitionDTO param) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<FileUrlVO>> getFileUrls(IdsDTO param) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<Attachment>> ossUpload(MultipartFile[] files) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<TempFileUrlVO> ossUploadTemp(MultipartFile file, Integer expires) {
|
||||||
|
return FR.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.springblade.file.feign;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import org.springblade.core.launch.constant.AppConstant;
|
||||||
|
import org.springblade.core.tool.api.FR;
|
||||||
|
import org.springblade.file.config.FeignFileUploadClientConfig;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
import org.springblade.file.pojo.vo.TempFileUrlVO;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/21
|
||||||
|
*/
|
||||||
|
@FeignClient(
|
||||||
|
value = AppConstant.APPLICATION_FILE_NAME,
|
||||||
|
fallback = IFileClientFallback.class,
|
||||||
|
configuration = FeignFileUploadClientConfig.class
|
||||||
|
)
|
||||||
|
public interface IFileUploadClient {
|
||||||
|
|
||||||
|
String API_PREFIX = "/feign/client/file";
|
||||||
|
String UPLOAD = API_PREFIX + "/ossUpload";
|
||||||
|
String UPLOAD_TEMP = API_PREFIX + "/ossUploadTemp";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
* @param files
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(value = UPLOAD, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
FR<List<Attachment>> ossUpload(@RequestPart("files") MultipartFile[] files);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传临时文件,不保存到附件表,过期后自动删除
|
||||||
|
* @param file
|
||||||
|
* @param expires 过期时间,单位天,过期后自动删除
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(value = UPLOAD_TEMP, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
FR<TempFileUrlVO> ossUploadTemp(@RequestPart("file") MultipartFile file, @NotNull(message = "过期时间不能为空") @RequestParam(name = "expires", required = false) Integer expires);
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 数据传输对象实体类
|
||||||
|
*
|
||||||
|
* @author BladeX
|
||||||
|
* @since 2024-09-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务附件新增参数")
|
||||||
|
@Builder
|
||||||
|
public class BusinessAttachmentAddDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "业务id不能为空")
|
||||||
|
@Schema(description = "业务id")
|
||||||
|
private Long bizId;
|
||||||
|
/**
|
||||||
|
* 业务code
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "业务code不能为空")
|
||||||
|
@Schema(description = "业务code")
|
||||||
|
private String bizCode;
|
||||||
|
/**
|
||||||
|
* 附件id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "附件id不能为空")
|
||||||
|
@Schema(description = "附件id")
|
||||||
|
private Long attachmentId;
|
||||||
|
/**
|
||||||
|
* 附件描述
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件描述")
|
||||||
|
private String desc;
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
@Schema(description = "排序")
|
||||||
|
private Integer sort;
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 数据传输对象实体类
|
||||||
|
*
|
||||||
|
* @author BladeX
|
||||||
|
* @since 2024-09-04
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务附件批量新增参数")
|
||||||
|
public class BusinessAttachmentBatchAddDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "业务id不能为空")
|
||||||
|
@Schema(description = "业务id")
|
||||||
|
private Long bizId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 明细列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "明细列表")
|
||||||
|
private List<@Valid BusinessAttachmentBatchAddDetailDTO> details;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否先删除,默认 是
|
||||||
|
*/
|
||||||
|
@Schema(description = "是否先删除,默认 是")
|
||||||
|
private boolean remove = true;
|
||||||
|
|
||||||
|
public BusinessAttachmentBatchAddDTO(Long bizId) {
|
||||||
|
this.bizId = bizId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessAttachmentBatchAddDTO(Long bizId, String bizCode, Long attachmentId) {
|
||||||
|
this.bizId = bizId;
|
||||||
|
this.details = Lists.newArrayList(new BusinessAttachmentBatchAddDetailDTO(bizCode, attachmentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessAttachmentBatchAddDTO addDetail(BusinessAttachmentBatchAddDetailDTO detail) {
|
||||||
|
if (this.details == null) {
|
||||||
|
this.details = new ArrayList<>();
|
||||||
|
}
|
||||||
|
this.details.add(detail);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessAttachmentBatchAddDTO addDetail(String bizCode, Long attachmentId) {
|
||||||
|
return this.addDetail(new BusinessAttachmentBatchAddDetailDTO(bizCode, attachmentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessAttachmentBatchAddDTO addDetail(String bizCode, List<Long> attachmentIds) {
|
||||||
|
return this.addDetail(new BusinessAttachmentBatchAddDetailDTO(bizCode, attachmentIds));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 数据传输对象实体类
|
||||||
|
*
|
||||||
|
* @author BladeX
|
||||||
|
* @since 2024-09-04
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务附件批量新增明细参数")
|
||||||
|
@Builder
|
||||||
|
public class BusinessAttachmentBatchAddDetailDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 业务code
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "业务编码不能为空")
|
||||||
|
@Schema(description = "业务code")
|
||||||
|
private String bizCode;
|
||||||
|
/**
|
||||||
|
* 附件id列表
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "附件id列表不能为空")
|
||||||
|
@Schema(description = "附件id列表")
|
||||||
|
private List<@NotNull(message = "附件id不能为空") Long> attachmentIds;
|
||||||
|
|
||||||
|
public BusinessAttachmentBatchAddDetailDTO(String bizCode, Long attachmentId) {
|
||||||
|
this.bizCode = bizCode;
|
||||||
|
this.attachmentIds = Lists.newArrayList(attachmentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springblade.core.tool.utils.StringUtil;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件删除参数
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2024/12/3
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务附件删除参数")
|
||||||
|
public class BusinessAttachmentDeleteDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 业务id列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务id列表")
|
||||||
|
private List<Long> bizIds;
|
||||||
|
/**
|
||||||
|
* 业务code列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务code列表")
|
||||||
|
private List<String> bizCodes;
|
||||||
|
/**
|
||||||
|
* 是否删除
|
||||||
|
*/
|
||||||
|
@Schema(description = "是否删除")
|
||||||
|
private boolean delete = true;
|
||||||
|
|
||||||
|
public BusinessAttachmentDeleteDTO(Long bizId) {
|
||||||
|
this.bizIds = Lists.newArrayList(bizId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessAttachmentDeleteDTO(Long bizId, String bizCode) {
|
||||||
|
this.bizIds = Lists.newArrayList(bizId);
|
||||||
|
if (StringUtil.isNotBlank(bizCode)) {
|
||||||
|
this.bizCodes = Lists.newArrayList(bizCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 数据传输对象实体类
|
||||||
|
*
|
||||||
|
* @author BladeX
|
||||||
|
* @since 2024-09-04
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务附件查询参数")
|
||||||
|
public class BusinessAttachmentQueryDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 业务id列表
|
||||||
|
*/
|
||||||
|
@NotNull(message = "业务id列表不能为空")
|
||||||
|
@Schema(description = "业务id列表")
|
||||||
|
private List<@NotNull(message = "业务id不能为空") Long> bizIds;
|
||||||
|
/**
|
||||||
|
* 业务code
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务code")
|
||||||
|
private String bizCode;
|
||||||
|
/**
|
||||||
|
* 业务code列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务code列表")
|
||||||
|
private List<String> bizCodes;
|
||||||
|
|
||||||
|
public BusinessAttachmentQueryDTO(Long bizId) {
|
||||||
|
this.bizIds = List.of(bizId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessAttachmentQueryDTO(List<Long> bizIds) {
|
||||||
|
this.bizIds = bizIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容历史参数
|
||||||
|
* @param bizId
|
||||||
|
*/
|
||||||
|
public void setBizId(Long bizId) {
|
||||||
|
if (this.bizIds == null) {
|
||||||
|
this.bizIds = new ArrayList<>();
|
||||||
|
}
|
||||||
|
this.bizIds.add(bizId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.file.pojo.enums.UnzipTask;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务解压任务新增参数
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务解压任务新增参数")
|
||||||
|
public class BusinessUnzipTaskAddDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 业务id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "业务id不能为空")
|
||||||
|
@Schema(description = "业务id")
|
||||||
|
private Long bizId;
|
||||||
|
/**
|
||||||
|
* 部门名称ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "部门名称ID")
|
||||||
|
private Long departmentId;
|
||||||
|
/**
|
||||||
|
* 业务code
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "业务code不能为空")
|
||||||
|
@Schema(description = "业务code")
|
||||||
|
private String bizCode = UnzipTask.BizCode.WAYBILL.getCode();
|
||||||
|
/**
|
||||||
|
* 文档编号
|
||||||
|
*/
|
||||||
|
@Schema(description = "文档编号")
|
||||||
|
private String docCode;
|
||||||
|
/**
|
||||||
|
* 关联类型,file_task 文件任务,attachment 附件
|
||||||
|
*/
|
||||||
|
@Schema(description = "关联类型,file_task 文件任务,attachment 附件")
|
||||||
|
private String relateType = UnzipTask.RelateType.FILE_TASK.getCode();
|
||||||
|
/**
|
||||||
|
* 关联id,文件任务id或附件id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "关联id不能为空")
|
||||||
|
@Schema(description = "关联id,文件任务id或附件id")
|
||||||
|
private Long relateId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务解压任务查询参数
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务解压任务查询参数")
|
||||||
|
public class BusinessUnzipTaskQueryDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 文档编号(凭证批次号)
|
||||||
|
*/
|
||||||
|
@Schema(description = "文档编号(凭证批次号)")
|
||||||
|
private String docCode;
|
||||||
|
/**
|
||||||
|
* 附件名称
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件名称")
|
||||||
|
private String attachmentName;
|
||||||
|
/**
|
||||||
|
* 状态 uploading:正在上传 completed:上传完成 failed:上传失败 paused:已暂停
|
||||||
|
*/
|
||||||
|
@Schema(description = "状态 uploading:正在上传 completed:上传完成 failed:上传失败 paused:已暂停")
|
||||||
|
private String status;
|
||||||
|
/**
|
||||||
|
* 关联类型,file_task 文件任务,attachment 附件
|
||||||
|
*/
|
||||||
|
@Schema(description = "关联类型,file_task 文件任务,attachment 附件", hidden = true)
|
||||||
|
private String relateType;
|
||||||
|
/**
|
||||||
|
* 是否只查询当前用户
|
||||||
|
*/
|
||||||
|
@Schema(description = "是否只查询当前用户")
|
||||||
|
private boolean currentUser;
|
||||||
|
/**
|
||||||
|
* 当前登录人id
|
||||||
|
*/
|
||||||
|
@Schema(hidden = true)
|
||||||
|
private Long currentUserId;
|
||||||
|
/**
|
||||||
|
* 业务id列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务id列表", hidden = true)
|
||||||
|
private List<Long> bizIds;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.file.pojo.enums.UnzipTask;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务解压任务更新参数
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务解压任务更新参数")
|
||||||
|
public class BusinessUnzipTaskUpdateDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 业务id
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务id")
|
||||||
|
private Long bizId;
|
||||||
|
/**
|
||||||
|
* 关联id,文件任务id或附件id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "关联id不能为空")
|
||||||
|
@Schema(description = "关联id,文件任务id或附件id")
|
||||||
|
private Long relateId;
|
||||||
|
/**
|
||||||
|
* 关联类型,file_task 文件任务,attachment 附件
|
||||||
|
*/
|
||||||
|
@Schema(description = "关联类型,file_task 文件任务,attachment 附件", hidden = true)
|
||||||
|
private String relateType = UnzipTask.RelateType.FILE_TASK.getCode();
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 凭证识别参数,依次调用单张识别
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2024/12/13
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "凭证附件参数")
|
||||||
|
public class CertificateAttachmentDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 磅单ObjectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "磅单ObjectKey")
|
||||||
|
private String poundObjectKey;
|
||||||
|
/**
|
||||||
|
* 车头ObjectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "车头ObjectKey")
|
||||||
|
private String carFrontObjectKey;
|
||||||
|
/**
|
||||||
|
* 驾驶证ObjectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "驾驶证ObjectKey")
|
||||||
|
private String driverLicenseObjectKey;
|
||||||
|
/**
|
||||||
|
* 行驶证ObjectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "行驶证ObjectKey")
|
||||||
|
private String vehicleLicenseObjectKey;
|
||||||
|
/**
|
||||||
|
* 项目简称
|
||||||
|
*/
|
||||||
|
@Schema(description = "项目简称")
|
||||||
|
private String projectAbbreviation;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 凭证批量识别参数,所有图像链接统一识别,不分类
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2025/3/13
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public class FileCertificateBatchRecognitionDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 所有图像 obs key列表
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "图像 obs key列表不能为空")
|
||||||
|
private List<String> objectKeys;
|
||||||
|
/**
|
||||||
|
* 项目简称
|
||||||
|
*/
|
||||||
|
private String projectAbbreviation;
|
||||||
|
/**
|
||||||
|
* 凭证编码
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
/**
|
||||||
|
* 目录名称
|
||||||
|
*/
|
||||||
|
private String dirName;
|
||||||
|
|
||||||
|
public FileCertificateBatchRecognitionDTO(List<String> objectKeys) {
|
||||||
|
this.objectKeys = objectKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件任务创建对象
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "文件任务创建对象")
|
||||||
|
public class FileTaskCreateDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Md5
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "Md5不能为空")
|
||||||
|
@Schema(description = "Md5")
|
||||||
|
private String md5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件名
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "附件名不能为空")
|
||||||
|
@Schema(description = "附件名")
|
||||||
|
private String attachmentName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件大小(单位:B)
|
||||||
|
*/
|
||||||
|
@NotNull(message = "附件大小不能为空")
|
||||||
|
@Schema(description = "附件大小(单位:B)")
|
||||||
|
private Long size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分段大小
|
||||||
|
*/
|
||||||
|
@NotNull(message = "分段大小不能为空")
|
||||||
|
@Schema(description = "分段大小")
|
||||||
|
private Integer chunkSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分段数量
|
||||||
|
*/
|
||||||
|
@NotNull(message = "分段数量不能为空")
|
||||||
|
@Schema(description = "分段数量")
|
||||||
|
private Integer chunkTotal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否强制创建新任务,默认 false,如果存在相同md5的任务,会创建失败,true则新创建一个任务
|
||||||
|
*/
|
||||||
|
@Schema(description = "是否强制创建新任务,默认 false,如果存在相同md5的任务,会创建失败,true则新创建一个任务")
|
||||||
|
private boolean force;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.file.pojo.vo.PartEtagVO;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件任务更新对象
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "文件任务更新对象")
|
||||||
|
public class FileTaskUpdateDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件任务id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "文件任务id不能为空")
|
||||||
|
@Schema(description = "主键id")
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 段的ETag值。分段的Base64编码的128位MD5摘要,长度为32的字符串
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "etag不能为空")
|
||||||
|
@Schema(description = "etag")
|
||||||
|
private String etag;
|
||||||
|
/**
|
||||||
|
* 段号。分段号可以是不连续的。取值范围是[1,10000]的非负整数
|
||||||
|
*/
|
||||||
|
@NotNull(message = "段号不能为空")
|
||||||
|
@Schema(description = "段号")
|
||||||
|
private Integer partNumber;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "分段上传文件对象")
|
||||||
|
public class FileUploadDTO {
|
||||||
|
private MultipartFile multipartFile; // 文件对象
|
||||||
|
private String md5; // 文件md5值
|
||||||
|
private Long chunkTotal; // 分段总数
|
||||||
|
private Long chunkSize; // 分段大小
|
||||||
|
private Integer index; // 当前分段的位置
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.springblade.file.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* id批量参数
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/29
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
@Schema(description = "id批量参数")
|
||||||
|
public class IdsDTO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* id列表
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "id列表不能为空")
|
||||||
|
@Schema(description = "id列表")
|
||||||
|
private @Valid List<@NotNull(message = "id不能为空") Long> ids;
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package org.springblade.file.pojo.entity;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.core.tool.utils.DateUtil;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhaowei
|
||||||
|
* @date 2024/8/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("blade_attachment")
|
||||||
|
@Schema(description = "附件对象")
|
||||||
|
public class Attachment implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "主键id")
|
||||||
|
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件名
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件名")
|
||||||
|
private String attachmentName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩文件所在压缩包相对路径
|
||||||
|
*/
|
||||||
|
@Schema(description = "压缩文件所在压缩包相对路径")
|
||||||
|
private String dir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件大小(单位:B)
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件大小(单位:B)")
|
||||||
|
private long size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* objectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "华为OBS objectKey")
|
||||||
|
private String objectKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人-用户名称
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人-用户名称")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private String createUserName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Long createUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人-用户名称
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人-用户名称")
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private String updateUserName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Long updateUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "更新时间")
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态[0:未删除,1:删除]
|
||||||
|
*/
|
||||||
|
@TableLogic
|
||||||
|
@Schema(description = "是否已删除 [0:未删除,1:删除]")
|
||||||
|
private Integer isDeleted;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package org.springblade.file.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.core.tool.utils.DateUtil;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 实体类
|
||||||
|
*
|
||||||
|
* @author BladeX
|
||||||
|
* @since 2024-09-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("blade_business_attachment")
|
||||||
|
@Schema(description = "BusinessAttachment对象")
|
||||||
|
public class BusinessAttachment implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务id
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务id")
|
||||||
|
private Long bizId;
|
||||||
|
/**
|
||||||
|
* 业务code
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务code")
|
||||||
|
private String bizCode;
|
||||||
|
/**
|
||||||
|
* 附件id
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件id")
|
||||||
|
private Long attachmentId;
|
||||||
|
/**
|
||||||
|
* 附件描述
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件描述")
|
||||||
|
@TableField(value = "`desc`")
|
||||||
|
private String desc;
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
@Schema(description = "排序")
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 租户ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "租户ID")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private String tenantId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "主键id")
|
||||||
|
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人", hidden = true)
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Long createUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "创建时间", hidden = true)
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "更新人", hidden = true)
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Long updateUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "更新时间", hidden = true)
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态[0:未删除,1:删除]
|
||||||
|
*/
|
||||||
|
@TableLogic
|
||||||
|
@Schema(description = "是否已删除", hidden = true)
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Integer isDeleted;
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package org.springblade.file.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.core.tool.utils.DateUtil;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 业务解压明细表
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2024-10-30
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("blade_business_unzip_detail")
|
||||||
|
@Schema(description = "BusinessUnzipDetail对象")
|
||||||
|
public class BusinessUnzipDetail implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 业务解压任务id
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务解压任务id")
|
||||||
|
private Long businessUnzipTaskId;
|
||||||
|
/**
|
||||||
|
* 附件id
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件id")
|
||||||
|
private Long attachmentId;
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Long createUser;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Date createTime;
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Long updateUser;
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "更新时间")
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Date updateTime;
|
||||||
|
/**
|
||||||
|
* 状态[0:未删除,1:删除]
|
||||||
|
*/
|
||||||
|
@TableLogic
|
||||||
|
@Schema(description = "是否已删除 [0:未删除,1:删除]")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Integer isDeleted;
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package org.springblade.file.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.core.tool.utils.DateUtil;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 业务解压任务表
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2024-10-28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("blade_business_unzip_task")
|
||||||
|
@Schema(description = "业务解压任务表")
|
||||||
|
public class BusinessUnzipTask implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "业务id")
|
||||||
|
private Long bizId;
|
||||||
|
/**
|
||||||
|
* 部门名称ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "部门名称ID")
|
||||||
|
private Long departmentId;
|
||||||
|
|
||||||
|
@Schema(description = "业务code")
|
||||||
|
private String bizCode;
|
||||||
|
|
||||||
|
@Schema(description = "文档编号")
|
||||||
|
private String docCode;
|
||||||
|
|
||||||
|
@Schema(description = "关联类型,file_task 文件任务,attachment 附件")
|
||||||
|
private String relateType;
|
||||||
|
|
||||||
|
@Schema(description = "关联id,文件任务id或附件id")
|
||||||
|
private Long relateId;
|
||||||
|
|
||||||
|
@Schema(description = "状态 uploading:正在上传 unzipping:解压中 finished:已完成")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "租户ID")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private String tenantId;
|
||||||
|
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人", hidden = true)
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Long createUser;
|
||||||
|
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "创建时间", hidden = true)
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "更新人", hidden = true)
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Long updateUser;
|
||||||
|
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "更新时间", hidden = true)
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
@Schema(description = "是否已删除", hidden = true)
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
@TableLogic
|
||||||
|
private Integer isDeleted;
|
||||||
|
}
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
package org.springblade.file.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.core.tool.utils.DateUtil;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhaowei
|
||||||
|
* @date 2024/8/23
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("blade_file_task")
|
||||||
|
@Schema(description = "文件上传任务对象")
|
||||||
|
public class FileTask implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "主键id")
|
||||||
|
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Md5
|
||||||
|
*/
|
||||||
|
@Schema(description = "Md5")
|
||||||
|
private String md5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OBS objectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "OBS objectKey")
|
||||||
|
private String objectKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件名
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件名")
|
||||||
|
private String attachmentName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件类型
|
||||||
|
*/
|
||||||
|
@Schema(description = "文件类型")
|
||||||
|
private String suffix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件大小(单位:B)
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件大小(单位:B)")
|
||||||
|
private Long size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分段大小
|
||||||
|
*/
|
||||||
|
@Schema(description = "分段大小")
|
||||||
|
private Integer chunkSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分段数量
|
||||||
|
*/
|
||||||
|
@Schema(description = "分段数量")
|
||||||
|
private Integer chunkTotal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前分段的位置(已上传完成的分段),从0开始,上传完第1段,为1
|
||||||
|
*/
|
||||||
|
@Schema(description = "当前分段的位置(已上传完成的分段),从0开始,上传完第1段,为1")
|
||||||
|
private Integer currentIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 华为云初始化上传任务生成的uploadId
|
||||||
|
*/
|
||||||
|
@Schema(description = "华为云初始化上传任务生成的uploadId")
|
||||||
|
private String uploadId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态 uploading:正在上传 completed:上传完成 failed:上传失败 paused:已暂停
|
||||||
|
*/
|
||||||
|
@Schema(description = "状态 uploading:正在上传 completed:上传完成 failed:上传失败 paused:已暂停")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人-用户名称
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人-用户名称")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private String createUserName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Long createUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人-用户名称
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人-用户名称")
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private String updateUserName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Long updateUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "更新时间")
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态[0:未删除,1:删除]
|
||||||
|
*/
|
||||||
|
@TableLogic
|
||||||
|
@Schema(description = "是否已删除 [0:未删除,1:删除]")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Integer isDeleted;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package org.springblade.file.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.core.tool.utils.DateUtil;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhaowei
|
||||||
|
* @date 2024/8/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("blade_file_task_part")
|
||||||
|
@Schema(description = "文件任务分段表")
|
||||||
|
public class FileTaskPart implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "主键id")
|
||||||
|
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件任务Id
|
||||||
|
*/
|
||||||
|
@Schema(description = "文件任务Id")
|
||||||
|
private Long fileTaskId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 段号。分段号可以是不连续的。取值范围是[1,10000]的非负整数
|
||||||
|
*/
|
||||||
|
@Schema(description = "段号。分段号可以是不连续的。取值范围是[1,10000]的非负整数")
|
||||||
|
private Integer partNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 段的ETag值。分段的Base64编码的128位MD5摘要,长度为32的字符串
|
||||||
|
*/
|
||||||
|
@Schema(description = "段的ETag值。分段的Base64编码的128位MD5摘要,长度为32的字符串")
|
||||||
|
private String etag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Long createUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package org.springblade.file.pojo.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件任务状态
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/22
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum FileTaskStatus {
|
||||||
|
/**
|
||||||
|
* 正在上传
|
||||||
|
*/
|
||||||
|
UPLOADING("uploading", "正在上传"),
|
||||||
|
/**
|
||||||
|
* 上传完成
|
||||||
|
*/
|
||||||
|
COMPLETED("completed", "上传完成"),
|
||||||
|
/**
|
||||||
|
* 上传失败
|
||||||
|
*/
|
||||||
|
FAILED("failed", "上传失败"),
|
||||||
|
/**
|
||||||
|
* 已暂停
|
||||||
|
*/
|
||||||
|
PAUSED("paused", "已暂停"),
|
||||||
|
;
|
||||||
|
/**
|
||||||
|
* 编码
|
||||||
|
*/
|
||||||
|
private final String code;
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package org.springblade.file.pojo.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压任务枚举类
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/27
|
||||||
|
*/
|
||||||
|
public class UnzipTask {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务编码枚举
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum BizCode {
|
||||||
|
/**
|
||||||
|
* 运单
|
||||||
|
*/
|
||||||
|
WAYBILL("waybill", "运单"),
|
||||||
|
/**
|
||||||
|
* 基地
|
||||||
|
*/
|
||||||
|
WAREHOUSE("warehouse", "基地"),
|
||||||
|
;
|
||||||
|
/**
|
||||||
|
* 编码
|
||||||
|
*/
|
||||||
|
private final String code;
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联类型枚举
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum RelateType {
|
||||||
|
/**
|
||||||
|
* 文件任务
|
||||||
|
*/
|
||||||
|
FILE_TASK("file_task", "文件任务"),
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
ATTACHMENT("attachment", "附件"),
|
||||||
|
;
|
||||||
|
/**
|
||||||
|
* 编码
|
||||||
|
*/
|
||||||
|
private final String code;
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态枚举
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum Status {
|
||||||
|
/**
|
||||||
|
* 正在上传
|
||||||
|
*/
|
||||||
|
UPLOADING("uploading", "正在上传"),
|
||||||
|
/**
|
||||||
|
* 上传完成
|
||||||
|
*/
|
||||||
|
UPLOADED("uploaded", "上传完成"),
|
||||||
|
/**
|
||||||
|
* 正在解压
|
||||||
|
*/
|
||||||
|
UNZIPPING("unzipping", "正在解压"),
|
||||||
|
/**
|
||||||
|
* 解压失败
|
||||||
|
*/
|
||||||
|
UNZIP_FAIL("unzip_fail", "解压失败"),
|
||||||
|
/**
|
||||||
|
* 已完成
|
||||||
|
*/
|
||||||
|
FINISHED("finished", "已完成"),
|
||||||
|
;
|
||||||
|
/**
|
||||||
|
* 编码
|
||||||
|
*/
|
||||||
|
private final String code;
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件详情对象
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/30
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "附件详情对象")
|
||||||
|
public class AttachmentDetailVO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
@Schema(description = "主键id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件名
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件名")
|
||||||
|
private String attachmentName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* objectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "华为OBS objectKey")
|
||||||
|
private String objectKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件大小(单位:B)
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件大小(单位:B)")
|
||||||
|
private long size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private Long createUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private Long updateUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@Schema(description = "更新时间")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载链接
|
||||||
|
*/
|
||||||
|
@Schema(description = "下载链接")
|
||||||
|
private String url;
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.core.tool.utils.DateUtil;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 视图实体类
|
||||||
|
*
|
||||||
|
* @author BladeX
|
||||||
|
* @since 2024-09-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务附件响应参数")
|
||||||
|
public class BusinessAttachmentVO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "主键id")
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 业务id
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务id")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long bizId;
|
||||||
|
/**
|
||||||
|
* 业务code
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务code")
|
||||||
|
private String bizCode;
|
||||||
|
/**
|
||||||
|
* 业务code名称
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务code名称")
|
||||||
|
private String bizCodeStr;
|
||||||
|
/**
|
||||||
|
* 附件id
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件id")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long attachmentId;
|
||||||
|
/**
|
||||||
|
* 附件名
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件名")
|
||||||
|
private String attachmentName;
|
||||||
|
/**
|
||||||
|
* 附件大小(单位:B)
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件大小(单位:B)")
|
||||||
|
private long size;
|
||||||
|
/**
|
||||||
|
* objectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "华为OBS objectKey")
|
||||||
|
private String objectKey;
|
||||||
|
/**
|
||||||
|
* 附件描述
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件描述")
|
||||||
|
@Size(max = 100, message = "附件描述长度不能超过100")
|
||||||
|
private String desc;
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
@Schema(description = "排序")
|
||||||
|
private Integer sort;
|
||||||
|
/**
|
||||||
|
* 上传人id
|
||||||
|
*/
|
||||||
|
@Schema(description = "上传人id")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long uploadUserId;
|
||||||
|
/**
|
||||||
|
* 上传人姓名
|
||||||
|
*/
|
||||||
|
@Schema(description = "上传人姓名")
|
||||||
|
private String uploadUserName;
|
||||||
|
/**
|
||||||
|
* 上传人姓名
|
||||||
|
*/
|
||||||
|
@Schema(description = "上传人姓名")
|
||||||
|
private String createUserName;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_TIME_MINI)
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.core.tool.utils.DateUtil;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务解压任务明细对象
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/11/08
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务解压任务明细对象")
|
||||||
|
public class BusinessUnzipDetailListVO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 附件id
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件id")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long attachmentId;
|
||||||
|
|
||||||
|
//==========================附件属性=============================
|
||||||
|
/**
|
||||||
|
* 压缩文件所在压缩包相对路径
|
||||||
|
*/
|
||||||
|
@Schema(description = "压缩文件所在压缩包相对路径")
|
||||||
|
private String dir;
|
||||||
|
/**
|
||||||
|
* 附件名
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件名")
|
||||||
|
private String attachmentName;
|
||||||
|
/**
|
||||||
|
* 附件大小(单位:B)
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件大小(单位:B)")
|
||||||
|
private long size;
|
||||||
|
/**
|
||||||
|
* objectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "华为OBS objectKey")
|
||||||
|
private String objectKey;
|
||||||
|
/**
|
||||||
|
* 附件描述
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件描述")
|
||||||
|
@Size(max = 100, message = "附件描述长度不能超过100")
|
||||||
|
private String desc;
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
@Schema(description = "排序")
|
||||||
|
private Integer sort;
|
||||||
|
/**
|
||||||
|
* 上传人id
|
||||||
|
*/
|
||||||
|
@Schema(description = "上传人id")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long uploadUserId;
|
||||||
|
/**
|
||||||
|
* 上传人姓名
|
||||||
|
*/
|
||||||
|
@Schema(description = "上传人姓名")
|
||||||
|
private String uploadUserName;
|
||||||
|
/**
|
||||||
|
* 上传人姓名
|
||||||
|
*/
|
||||||
|
@Schema(description = "上传人姓名")
|
||||||
|
private String createUserName;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_TIME_MINI)
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.core.tool.utils.DateUtil;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务解压任务分页对象
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "业务解压任务分页对象")
|
||||||
|
public class BusinessUnzipTaskListVO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "主键")
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 业务id
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "业务id")
|
||||||
|
private Long bizId;
|
||||||
|
/**
|
||||||
|
* 业务code
|
||||||
|
*/
|
||||||
|
@Schema(description = "业务code")
|
||||||
|
private String bizCode;
|
||||||
|
/**
|
||||||
|
* 文档编号
|
||||||
|
*/
|
||||||
|
@Schema(description = "文档编号")
|
||||||
|
private String docCode;
|
||||||
|
/**
|
||||||
|
* 关联类型,file_task 文件任务,attachment 附件
|
||||||
|
*/
|
||||||
|
@Schema(description = "关联类型,file_task 文件任务,attachment 附件")
|
||||||
|
private String relateType;
|
||||||
|
/**
|
||||||
|
* 关联id,文件任务id或附件id
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "关联id,文件任务id或附件id")
|
||||||
|
private Long relateId;
|
||||||
|
|
||||||
|
//==========================文件任务属性=============================
|
||||||
|
/**
|
||||||
|
* Md5
|
||||||
|
*/
|
||||||
|
@Schema(description = "Md5")
|
||||||
|
private String md5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OBS objectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "OBS objectKey")
|
||||||
|
private String objectKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件名
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件名")
|
||||||
|
private String attachmentName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件类型
|
||||||
|
*/
|
||||||
|
@Schema(description = "文件类型")
|
||||||
|
private String suffix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件大小(单位:B)
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件大小(单位:B)")
|
||||||
|
private Long size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分段大小
|
||||||
|
*/
|
||||||
|
@Schema(description = "分段大小")
|
||||||
|
private Integer chunkSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分段数量
|
||||||
|
*/
|
||||||
|
@Schema(description = "分段数量")
|
||||||
|
private Integer chunkTotal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前分段的位置(已上传完成的分段),从0开始,上传完第1段,为1
|
||||||
|
*/
|
||||||
|
@Schema(description = "当前分段的位置(已上传完成的分段),从0开始,上传完第1段,为1")
|
||||||
|
private Integer currentIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 华为云初始化上传任务生成的uploadId
|
||||||
|
*/
|
||||||
|
@Schema(description = "华为云初始化上传任务生成的uploadId")
|
||||||
|
private String uploadId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态 uploading:正在上传 completed:上传完成 failed:上传失败 paused:已暂停
|
||||||
|
*/
|
||||||
|
@Schema(description = "状态 uploading:正在上传 completed:上传完成 failed:上传失败 paused:已暂停")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态名称
|
||||||
|
*/
|
||||||
|
@Schema(description = "状态名称")
|
||||||
|
private String statusStr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人-用户名称
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人-用户名称")
|
||||||
|
private String createUserName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private Long createUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人-用户名称
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人-用户名称")
|
||||||
|
private String updateUserName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private Long updateUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "更新时间")
|
||||||
|
private Date updateTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件处理结果对象
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/30
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "文件处理结果对象")
|
||||||
|
public class FileHandleVO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 下载的压缩文件
|
||||||
|
*/
|
||||||
|
@Schema(description = "下载的压缩文件")
|
||||||
|
private File downloadFile;
|
||||||
|
/**
|
||||||
|
* 解压目录
|
||||||
|
*/
|
||||||
|
@Schema(description = "解压目录")
|
||||||
|
private File unzippedDir;
|
||||||
|
/**
|
||||||
|
* 解压后的文件列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "解压后的文件列表")
|
||||||
|
private List<File> unzippedFiles;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件任务更新结果
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/28
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@Schema(description = "文件任务更新结果")
|
||||||
|
public class FileTaskUpdateVO extends FileTaskVO {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 文档编号(凭证批次号),如果有则返回,没有为空
|
||||||
|
*/
|
||||||
|
@Schema(description = "文档编号(凭证批次号),如果有则返回,没有为空")
|
||||||
|
private String docCode;
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springblade.core.tool.utils.DateUtil;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件任务对象
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "文件任务对象")
|
||||||
|
public class FileTaskVO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "主键id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Md5
|
||||||
|
*/
|
||||||
|
@Schema(description = "Md5")
|
||||||
|
private String md5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OBS objectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "OBS objectKey")
|
||||||
|
private String objectKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件名
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件名")
|
||||||
|
private String attachmentName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件类型
|
||||||
|
*/
|
||||||
|
@Schema(description = "文件类型")
|
||||||
|
private String suffix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件大小(单位:B)
|
||||||
|
*/
|
||||||
|
@Schema(description = "附件大小(单位:B)")
|
||||||
|
private Long size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分段大小
|
||||||
|
*/
|
||||||
|
@Schema(description = "分段大小")
|
||||||
|
private Integer chunkSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分段数量
|
||||||
|
*/
|
||||||
|
@Schema(description = "分段数量")
|
||||||
|
private Integer chunkTotal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前分段的位置(已上传完成的分段),从0开始,上传完第1段,为1
|
||||||
|
*/
|
||||||
|
@Schema(description = "当前分段的位置(已上传完成的分段),从0开始,上传完第1段,为1")
|
||||||
|
private Integer currentIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 华为云初始化上传任务生成的uploadId
|
||||||
|
*/
|
||||||
|
@Schema(description = "华为云初始化上传任务生成的uploadId")
|
||||||
|
private String uploadId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态 uploading:正在上传 completed:上传完成 failed:上传失败 paused:已暂停
|
||||||
|
*/
|
||||||
|
@Schema(description = "状态 uploading:正在上传 completed:上传完成 failed:上传失败 paused:已暂停")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人-用户名称
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人-用户名称")
|
||||||
|
private String createUserName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人")
|
||||||
|
private Long createUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人-用户名称
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "创建人-用户名称")
|
||||||
|
private String updateUserName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@Schema(description = "更新人")
|
||||||
|
private Long updateUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@JsonFormat(pattern = DateUtil.PATTERN_DATETIME)
|
||||||
|
@Schema(description = "更新时间")
|
||||||
|
private Date updateTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件下载地址对象
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2025/4/22
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
@Schema(description = "文件下载地址对象")
|
||||||
|
public class FileUrlVO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
@Schema(description = "主键id")
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 文件下载地址
|
||||||
|
*/
|
||||||
|
@Schema(description ="文件下载地址")
|
||||||
|
private String url;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件对象
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/11/19
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
@Schema(description = "文件对象")
|
||||||
|
public class FileVO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OBS objectKey
|
||||||
|
*/
|
||||||
|
@Schema(description = "OBS objectKey")
|
||||||
|
private String objectKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Md5
|
||||||
|
*/
|
||||||
|
@Schema(description = "Md5")
|
||||||
|
private String md5;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 待合并的段
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/21
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public class PartEtagVO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* 段的ETag值。分段的Base64编码的128位MD5摘要,长度为32的字符串
|
||||||
|
*/
|
||||||
|
private String etag;
|
||||||
|
/**
|
||||||
|
* 段号。分段号可以是不连续的。取值范围是[1,10000]的非负整数
|
||||||
|
*/
|
||||||
|
private Integer partNumber;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.springblade.file.pojo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件下载地址对象
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2025/4/22
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
@Schema(description = "临时文件下载地址对象")
|
||||||
|
public class TempFileUrlVO implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
/**
|
||||||
|
* obs key
|
||||||
|
*/
|
||||||
|
@Schema(description = "obs key")
|
||||||
|
private String objectKey;
|
||||||
|
/**
|
||||||
|
* 文件下载地址
|
||||||
|
*/
|
||||||
|
@Schema(description ="文件下载地址")
|
||||||
|
private String url;
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.system.pojo.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.SqlCondition;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.springblade.core.tenant.mp.TenantEntity;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "APP版本管理")
|
||||||
|
@TableName("t_app_version")
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class AppVersion extends TenantEntity {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@NotEmpty
|
||||||
|
@Schema(description = "更新类型")
|
||||||
|
protected String updateType;
|
||||||
|
|
||||||
|
@TableField(condition = SqlCondition.LIKE)
|
||||||
|
@NotEmpty
|
||||||
|
@Schema(description = "版本号")
|
||||||
|
protected String version;
|
||||||
|
|
||||||
|
@TableField(condition = SqlCondition.LIKE)
|
||||||
|
@NotEmpty
|
||||||
|
@Schema(description = "子版本号")
|
||||||
|
protected String subVersion;
|
||||||
|
|
||||||
|
@NotEmpty
|
||||||
|
@Schema(description = "强制更新(是/否)")
|
||||||
|
protected String isForceUpdate;
|
||||||
|
|
||||||
|
@NotEmpty
|
||||||
|
@Schema(description = "安装方式")
|
||||||
|
protected String installMethod;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "安装包(附件Id)")
|
||||||
|
protected Long installAttachmentId;
|
||||||
|
|
||||||
|
@TableField(condition = SqlCondition.LIKE)
|
||||||
|
@NotEmpty
|
||||||
|
@Schema(description = "更新说明")
|
||||||
|
protected String updateExplanation;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
<module>blade-system-api</module>
|
<module>blade-system-api</module>
|
||||||
<module>blade-user-api</module>
|
<module>blade-user-api</module>
|
||||||
<module>blade-record-api</module>
|
<module>blade-record-api</module>
|
||||||
|
<module>blade-file-api</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|||||||
19
blade-service/blade-file/Dockerfile
Normal file
19
blade-service/blade-file/Dockerfile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
FROM bladex/alpine-java:openjdk17_cn_slim
|
||||||
|
ARG ACTIVE
|
||||||
|
|
||||||
|
LABEL maintainer="bladejava@qq.com"
|
||||||
|
|
||||||
|
# 设置时区为上海
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
# 设置时区信息
|
||||||
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||||
|
|
||||||
|
COPY ./target/blade-file.jar /opt/app.jar
|
||||||
|
|
||||||
|
WORKDIR /opt
|
||||||
|
|
||||||
|
EXPOSE 8107
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "--add-opens", "java.base/java.lang=ALL-UNNAMED", "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED", "-Djava.security.egd=file:/dev/./urandom", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/opt/logs", "-XX:ErrorFile=/opt/logs/hs_err_pid%p.log", "-Xlog:gc*:file=/opt/logs/gc.log:time,uptime,level,tags:filecount=5,filesize=50M", "-XX:MaxDirectMemorySize=512m", "-Xms1024m", "-Xmx4096m", "-jar", "app.jar"]
|
||||||
|
|
||||||
|
CMD ["--spring.profiles.active=${ACTIVE}","--logging.path=/opt/logs"]
|
||||||
19
blade-service/blade-file/Dockerfile-rt
Normal file
19
blade-service/blade-file/Dockerfile-rt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#FROM 10.38.16.129/bladex/alpine-java:openjdk17_cn_slim
|
||||||
|
#FROM registry.cn-hangzhou.aliyuncs.com/vic_person/alpine-java:openjdk17_cn_slim
|
||||||
|
FROM 10.38.16.129:80/bladex/alpine-java:openjdk17_cn_slim
|
||||||
|
ARG ACTIVE
|
||||||
|
|
||||||
|
LABEL maintainer="bladejava@qq.com"
|
||||||
|
|
||||||
|
RUN apk add --no-cache tzdata
|
||||||
|
|
||||||
|
# 设置时区为上海
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
# 设置时区信息
|
||||||
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||||
|
|
||||||
|
COPY ./target/*.jar /opt/app.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "--add-opens", "java.base/java.lang=ALL-UNNAMED", "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/opt/app.jar"]
|
||||||
|
|
||||||
|
CMD ["--spring.profiles.active=${ACTIVE}"]
|
||||||
19
blade-service/blade-file/Dockerfile-zh-dev
Normal file
19
blade-service/blade-file/Dockerfile-zh-dev
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
FROM bladex/alpine-java:openjdk17_cn_slim
|
||||||
|
ARG ACTIVE
|
||||||
|
|
||||||
|
LABEL maintainer="bladejava@qq.com"
|
||||||
|
|
||||||
|
# 设置时区为上海
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
# 设置时区信息
|
||||||
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||||
|
|
||||||
|
COPY ./target/blade-file.jar /opt/app.jar
|
||||||
|
|
||||||
|
WORKDIR /opt
|
||||||
|
|
||||||
|
EXPOSE 8107
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "--add-opens", "java.base/java.lang=ALL-UNNAMED", "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED", "-Djava.security.egd=file:/dev/./urandom", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/opt/logs", "-XX:ErrorFile=/opt/logs/hs_err_pid%p.log", "-Xlog:gc*:file=/opt/logs/gc.log:time,uptime,level,tags:filecount=5,filesize=50M", "-XX:MaxDirectMemorySize=512m", "-Xms1024m", "-Xmx1024m", "-jar", "app.jar"]
|
||||||
|
|
||||||
|
CMD ["--spring.profiles.active=${ACTIVE}","--logging.path=/opt/logs"]
|
||||||
139
blade-service/blade-file/pom.xml
Normal file
139
blade-service/blade-file/pom.xml
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>blade-service</artifactId>
|
||||||
|
<groupId>org.springblade</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>blade-file</artifactId>
|
||||||
|
<name>${project.artifactId}</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<commons-compress.version>1.27.1</commons-compress.version>
|
||||||
|
<xz.version>1.10</xz.version>
|
||||||
|
|
||||||
|
<!-- 其他依赖版本 -->
|
||||||
|
<lombok.version>1.18.30</lombok.version>
|
||||||
|
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
|
||||||
|
<junrar.version>7.5.5</junrar.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springblade</groupId>
|
||||||
|
<artifactId>blade-core-boot</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springblade</groupId>
|
||||||
|
<artifactId>blade-starter-swagger</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springblade</groupId>
|
||||||
|
<artifactId>blade-file-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springblade</groupId>
|
||||||
|
<artifactId>blade-wps-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springblade</groupId>
|
||||||
|
<artifactId>blade-ocr-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--zip解压缩-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.lingala.zip4j</groupId>
|
||||||
|
<artifactId>zip4j</artifactId>
|
||||||
|
<version>1.3.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 解压 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-compress</artifactId>
|
||||||
|
<version>${commons-compress.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.tukaani</groupId>
|
||||||
|
<artifactId>xz</artifactId>
|
||||||
|
<version>${xz.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.junrar</groupId>
|
||||||
|
<artifactId>junrar</artifactId>
|
||||||
|
<version>${junrar.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.csp</groupId>
|
||||||
|
<artifactId>sentinel-datasource-nacos</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct</artifactId>
|
||||||
|
<version>${org.mapstruct.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.fabric8</groupId>
|
||||||
|
<artifactId>docker-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>${docker.fabric.skip}</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven.plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
<compilerArgs>
|
||||||
|
<arg>-parameters</arg>
|
||||||
|
</compilerArgs>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
<version>${org.mapstruct.version}</version>
|
||||||
|
</path>
|
||||||
|
<!-- other annotation processors -->
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.file;
|
||||||
|
|
||||||
|
import org.springblade.core.cloud.client.BladeCloudApplication;
|
||||||
|
import org.springblade.core.launch.BladeApplication;
|
||||||
|
import org.springblade.core.launch.constant.AppConstant;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Desk启动器
|
||||||
|
*
|
||||||
|
* @author Chill
|
||||||
|
*/
|
||||||
|
@BladeCloudApplication
|
||||||
|
@ComponentScan({"org.springblade.file", "org.springblade.**.feign"})
|
||||||
|
public class FileApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
BladeApplication.run(AppConstant.APPLICATION_FILE_NAME, FileApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.springblade.file.config;
|
||||||
|
|
||||||
|
import com.obs.services.ObsClient;
|
||||||
|
import org.springblade.common.utils.ObsUtil;
|
||||||
|
import org.springblade.file.service.impl.ObsFileServiceImpl;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件配置类
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/21
|
||||||
|
*/
|
||||||
|
@Import(ObsUtil.class)
|
||||||
|
@Configuration
|
||||||
|
public class FileConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ObsProperties obsProperties() {
|
||||||
|
return new ObsProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ObsClient obsClient(ObsProperties properties) {
|
||||||
|
return new ObsClient(properties.getAccessKeyId(), properties.getAccessKeySecret(), properties.getEndpoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ObsFileServiceImpl fileService(ObsProperties properties, ObsClient obsClient) {
|
||||||
|
return new ObsFileServiceImpl(properties, obsClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package org.springblade.file.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* obs 配置
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/21
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ConfigurationProperties(prefix = "obs")
|
||||||
|
public class ObsProperties {
|
||||||
|
/**
|
||||||
|
* OBS endpoint
|
||||||
|
*/
|
||||||
|
public String endpoint;
|
||||||
|
/**
|
||||||
|
* AK in the access key
|
||||||
|
*/
|
||||||
|
public String accessKeyId;
|
||||||
|
/**
|
||||||
|
* SK in the access key
|
||||||
|
*/
|
||||||
|
public String accessKeySecret;
|
||||||
|
/**
|
||||||
|
* 桶名
|
||||||
|
*/
|
||||||
|
public String bucketName;
|
||||||
|
/**
|
||||||
|
* 根目录
|
||||||
|
*/
|
||||||
|
public String rootDirectory;
|
||||||
|
/**
|
||||||
|
* 过期时间,默认1小时
|
||||||
|
*/
|
||||||
|
public Long expires = Duration.ofHours(1).toSeconds();
|
||||||
|
/**
|
||||||
|
* 本地临时下载文件目录
|
||||||
|
*/
|
||||||
|
public String tmpDownloadDir = "tmp" + File.separator + "download";
|
||||||
|
/**
|
||||||
|
* 本地临时解压文件目录
|
||||||
|
*/
|
||||||
|
public String tmpUnzipDir = "tmp" + File.separator + "unzip";
|
||||||
|
/**
|
||||||
|
* obs上压缩文件上传目录
|
||||||
|
*/
|
||||||
|
public String zipUploadDir = "part";
|
||||||
|
/**
|
||||||
|
* obs上解压后的文件上传目录
|
||||||
|
*/
|
||||||
|
public String unzipUploadDir = "unzip";
|
||||||
|
/**
|
||||||
|
* obs上设置了过期时间自动删除的上传目录
|
||||||
|
*/
|
||||||
|
public String tmpUploadDir = "tmp";
|
||||||
|
/**
|
||||||
|
* 下载进度间隔,默认 10m
|
||||||
|
*/
|
||||||
|
public Long downloadProgressInterval = 10 * 1024 * 1024L;
|
||||||
|
/**
|
||||||
|
* 上传进度间隔,默认 10m
|
||||||
|
*/
|
||||||
|
public Long uploadProgressInterval = 10 * 1024 * 1024L;
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package org.springblade.file.controller;
|
||||||
|
|
||||||
|
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springblade.core.tool.api.R;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentAddDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentBatchAddDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentQueryDTO;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessAttachmentVO;
|
||||||
|
import org.springblade.file.service.IBusinessAttachmentService;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 控制器
|
||||||
|
*
|
||||||
|
* @author BladeX
|
||||||
|
* @since 2024-09-04
|
||||||
|
*/
|
||||||
|
@Valid
|
||||||
|
@RestController
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RequestMapping("businessAttachment")
|
||||||
|
@Tag(name = "业务附件信息表", description = "业务附件信息表接口")
|
||||||
|
public class BusinessAttachmentController {
|
||||||
|
|
||||||
|
private final IBusinessAttachmentService businessAttachmentService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 新增
|
||||||
|
*/
|
||||||
|
@PostMapping("/batchSave")
|
||||||
|
@ApiOperationSupport(order = 1)
|
||||||
|
@Operation(summary = "批量新增", description = "批量新增")
|
||||||
|
public R batchSave(@Validated @RequestBody List<BusinessAttachmentAddDTO> params) {
|
||||||
|
return R.status(businessAttachmentService.saveAndRemove(params, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 新增
|
||||||
|
*/
|
||||||
|
@PostMapping("/save")
|
||||||
|
@ApiOperationSupport(order = 2)
|
||||||
|
@Operation(summary = "新增", description = "新增")
|
||||||
|
public R save(@Validated @RequestBody BusinessAttachmentBatchAddDTO param) {
|
||||||
|
return R.status(businessAttachmentService.saveAndRemove(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 删除
|
||||||
|
*/
|
||||||
|
@PostMapping("/remove")
|
||||||
|
@ApiOperationSupport(order = 3)
|
||||||
|
@Operation(summary = "逻辑删除", description = "传入bizId")
|
||||||
|
public R remove(@Parameter(description = "bizId", required = true) @RequestParam Long bizId) {
|
||||||
|
return R.status(businessAttachmentService.removeByBizIds(List.of(bizId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询业务附件信息列表
|
||||||
|
*/
|
||||||
|
@PostMapping("/queryList")
|
||||||
|
@ApiOperationSupport(order = 4)
|
||||||
|
@Operation(summary = "查询业务附件信息列表", description = "查询业务附件信息列表")
|
||||||
|
public R<List<BusinessAttachmentVO>> queryList(@Validated @RequestBody BusinessAttachmentQueryDTO param) {
|
||||||
|
return R.data(businessAttachmentService.queryList(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package org.springblade.file.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springblade.core.log.annotation.ApiLog;
|
||||||
|
import org.springblade.core.log.utils.AssertUtils;
|
||||||
|
import org.springblade.core.mp.support.Condition;
|
||||||
|
import org.springblade.core.mp.support.Query;
|
||||||
|
import org.springblade.core.secure.annotation.PreAuth;
|
||||||
|
import org.springblade.core.secure.utils.AuthUtil;
|
||||||
|
import org.springblade.core.tool.api.R;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessUnzipTaskQueryDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessUnzipTaskUpdateDTO;
|
||||||
|
import org.springblade.file.pojo.enums.UnzipTask;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessUnzipTaskListVO;
|
||||||
|
import org.springblade.file.service.IBusinessUnzipTaskService;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/28
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RequestMapping("/businessUnzipTask")
|
||||||
|
@Tag(name = "业务文件解压任务", description = "业务文件解压任务")
|
||||||
|
public class BusinessUnzipTaskController {
|
||||||
|
|
||||||
|
private final IBusinessUnzipTaskService unzipTaskService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件任务列表
|
||||||
|
* @param param
|
||||||
|
* @param query
|
||||||
|
*/
|
||||||
|
@GetMapping("/list")
|
||||||
|
@Operation(summary = "业务文件解压任务分页查询", description = "业务文件解压任务分页查询")
|
||||||
|
@PreAuth("hasPermission('waybill:uploadTask:list')")
|
||||||
|
public R<IPage<BusinessUnzipTaskListVO>> list(BusinessUnzipTaskQueryDTO param, Query query) {
|
||||||
|
if (param == null) {
|
||||||
|
param = new BusinessUnzipTaskQueryDTO();
|
||||||
|
}
|
||||||
|
// 只查文件任务类型
|
||||||
|
param.setRelateType(UnzipTask.RelateType.FILE_TASK.getCode());
|
||||||
|
if (param.isCurrentUser()) {
|
||||||
|
// 只查自己的
|
||||||
|
param.setCurrentUserId(AuthUtil.getUserId());
|
||||||
|
}
|
||||||
|
IPage<BusinessUnzipTaskListVO> pages = unzipTaskService.selectPage(Condition.getPage(query), param);
|
||||||
|
return R.data(pages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务文件解压任务更新(重新上传)
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ApiLog("上传任务-重新上传")
|
||||||
|
@PostMapping("/update")
|
||||||
|
@Operation(summary = "业务文件解压任务更新(重新上传)", description = "业务文件解压任务更新(重新上传)")
|
||||||
|
@PreAuth("hasPermission('waybill:uploadTask:update')")
|
||||||
|
public R update(@Validated @RequestBody BusinessUnzipTaskUpdateDTO param) {
|
||||||
|
AssertUtils.notNull(param.getId(), "id不能为空");
|
||||||
|
return R.status(unzipTaskService.updateReupload(param));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
package org.springblade.file.controller;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.annotation.SentinelResource;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springblade.core.boot.ctrl.BladeController;
|
||||||
|
import org.springblade.core.log.annotation.ApiLog;
|
||||||
|
import org.springblade.core.tenant.annotation.NonDS;
|
||||||
|
import org.springblade.core.tool.api.R;
|
||||||
|
import org.springblade.core.tool.utils.StringUtil;
|
||||||
|
import org.springblade.file.listener.FileEvent;
|
||||||
|
import org.springblade.file.pojo.dto.CertificateAttachmentDTO;
|
||||||
|
import org.springblade.file.pojo.dto.FileCertificateBatchRecognitionDTO;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
import org.springblade.file.service.IAttachmentService;
|
||||||
|
import org.springblade.file.service.IFileService;
|
||||||
|
import org.springblade.file.service.IOCRConvertService;
|
||||||
|
import org.springblade.thirdparty.ocr.pojo.dto.CertificateRecognitionDTO;
|
||||||
|
import org.springblade.thirdparty.ocr.pojo.vo.TransportCertificateVO;
|
||||||
|
import org.springblade.thirdparty.ocr.service.IOCRService;
|
||||||
|
import org.springblade.thirdparty.wps.service.IWpsService;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName: fileUploadController
|
||||||
|
* @Author: zhaowei
|
||||||
|
* @Date: 2024/8/22
|
||||||
|
*/
|
||||||
|
@Valid
|
||||||
|
@NonDS
|
||||||
|
@RestController
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RequestMapping("/file")
|
||||||
|
@Tag(name = "文件相关管理", description = "文件相关管理")
|
||||||
|
public class FileController extends BladeController {
|
||||||
|
|
||||||
|
private final IAttachmentService attachmentService;
|
||||||
|
private final IFileService fileService;
|
||||||
|
private final IWpsService wpsService;
|
||||||
|
private final IOCRService ocrService;
|
||||||
|
private final IOCRConvertService ocrConvertService;
|
||||||
|
private final ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@ApiLog("附件管理-批量上传")
|
||||||
|
@Operation(summary = "OBS批量上传", description = "OBS批量上传,参数名:files")
|
||||||
|
@PostMapping("/ossUpload")
|
||||||
|
public R ossUpload(MultipartFile[] files, @RequestParam(value = "fileName", required = false) String fileName) {
|
||||||
|
return attachmentService.batchOssUpload(files, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "上传", description = "上传,参数名:file")
|
||||||
|
@PostMapping("/upload")
|
||||||
|
public R upload(MultipartFile file) {
|
||||||
|
MultipartFile[] files = {file};
|
||||||
|
R<List<Attachment>> result = attachmentService.batchOssUpload(files, null);
|
||||||
|
List<Attachment> data = result.getData();
|
||||||
|
if(data != null && !data.isEmpty())return R.data(data.get(0));
|
||||||
|
return R.fail("上传失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取附件,多个附件id用逗号分割", description = "获取附件,多个附件id用逗号分割")
|
||||||
|
@GetMapping("/getAttachment")
|
||||||
|
public R getAttachment(@RequestParam(value = "id") String id) {
|
||||||
|
return R.data(attachmentService.getAttachment(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取文件url", description = "获取文件url,参数:objectKey")
|
||||||
|
@GetMapping("/getFileUrl")
|
||||||
|
public R getFileUrl(@RequestParam(value = "objectKey") String objectKey, @RequestParam(value = "attachmentName", required = false) String attachmentName) {
|
||||||
|
if (StringUtil.isBlank(attachmentName)) {
|
||||||
|
// 附件名为空,查询附件名
|
||||||
|
Attachment attachment = attachmentService.getOne(Wrappers.<Attachment>lambdaQuery()
|
||||||
|
.eq(Attachment::getObjectKey, objectKey)
|
||||||
|
.last("limit 1")
|
||||||
|
);
|
||||||
|
attachmentName = Optional.ofNullable(attachment)
|
||||||
|
.map(Attachment::getAttachmentName)
|
||||||
|
.orElse(null);
|
||||||
|
if (attachmentName != null) {
|
||||||
|
// 附件名中如果有逗号,则替换为下划线
|
||||||
|
attachmentName = attachmentName.replaceAll(",", "_");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return R.data(fileService.getFileUrl(objectKey, attachmentName, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取wps文件预览url
|
||||||
|
* @param attachmentId * @param attachmentName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "获取wps文件预览url", description = "获取wps文件预览url")
|
||||||
|
@GetMapping("/getWpsFilePreviewUrl")
|
||||||
|
public R getWpsFilePreviewUrl(@NotNull(message = "附件id不能为空") @RequestParam(value = "attachmentId", required = false) String attachmentId,
|
||||||
|
@NotBlank(message = "附件名称不能为空") @RequestParam(value = "attachmentName", required = false) String attachmentName) {
|
||||||
|
return R.data(wpsService.getFilePreviewUrl(attachmentId, attachmentName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取wps文件编辑url
|
||||||
|
* @param attachmentId
|
||||||
|
* @param attachmentName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Operation(summary = "获取wps文件编辑url", description = "获取wps文件编辑url")
|
||||||
|
@GetMapping("/getWpsFileEditUrl")
|
||||||
|
public R getWpsFileEditUrl(@NotNull(message = "附件id不能为空") @RequestParam(value = "attachmentId", required = false) String attachmentId,
|
||||||
|
@NotBlank(message = "附件名称不能为空") @RequestParam(value = "attachmentName", required = false) String attachmentName) {
|
||||||
|
return R.data(wpsService.getWpsFileEditUrl(attachmentId, attachmentName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "批量获取文件url", description = "批量获取文件url,参数:objectKey数组")
|
||||||
|
@PostMapping("/getFileUrls")
|
||||||
|
public R getFileUrls(@RequestBody List<String> objectKeys) {
|
||||||
|
return R.data(fileService.getFileUrls(objectKeys, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiLog("OCR识别-识别身份证")
|
||||||
|
@Operation(summary = "识别身份证信息支持正反面", description = "参数:objectKey")
|
||||||
|
@GetMapping("/recognitionIDCard")
|
||||||
|
public R recognitionIDCard(@NotNull(message = "objectKey不能为空") @RequestParam(value = "objectKey", required = false) String objectKey) {
|
||||||
|
String fileUrl = fileService.getFileUrl(objectKey, null);
|
||||||
|
return R.data(ocrService.recognitionIDCard(List.of(fileUrl)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SentinelResource("ocr:batchCards")
|
||||||
|
@ApiLog("OCR识别-识别车辆运输凭证(不知道类型)")
|
||||||
|
@Operation(summary = "识别车辆运输凭证,不知道类型", description = "参数:objectKeylist")
|
||||||
|
@PostMapping("/recognitionTransportCertificates")
|
||||||
|
public R<TransportCertificateVO> recognitionTransportCertificates(@RequestBody List<String> objectKeys, @RequestParam(value = "projectAbbreviation", required = false) String projectAbbreviation, @RequestParam(value = "code", required = false) String code) {
|
||||||
|
return R.data(ocrConvertService.recognitionTransportCertificate(new FileCertificateBatchRecognitionDTO(objectKeys, projectAbbreviation, code, null)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiLog("OCR识别-识别车辆运输凭证(知道类型)")
|
||||||
|
@Operation(summary = "识别车辆运输凭证,知道类型", description = "参数:objectKeylist")
|
||||||
|
@PostMapping("/recognitionTransportCertificatesByType")
|
||||||
|
public R<TransportCertificateVO> recognitionTransportCertificatesByType(@RequestBody CertificateAttachmentDTO param, @RequestParam(value = "code", required = false) String code) {
|
||||||
|
CertificateRecognitionDTO recognitionParam = new CertificateRecognitionDTO();
|
||||||
|
recognitionParam.setPoundUrl(fileService.getFileUrl(param.getPoundObjectKey(), null));
|
||||||
|
recognitionParam.setCarFrontUrl(fileService.getFileUrl(param.getCarFrontObjectKey(), null));
|
||||||
|
recognitionParam.setDriverLicenseUrl(fileService.getFileUrl(param.getDriverLicenseObjectKey(), null));
|
||||||
|
recognitionParam.setVehicleLicenseUrl(fileService.getFileUrl(param.getVehicleLicenseObjectKey(), null));
|
||||||
|
recognitionParam.setName(param.getProjectAbbreviation());
|
||||||
|
return R.data(ocrService.recognitionTransportCertificate(recognitionParam, code));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(hidden = true)
|
||||||
|
@PostMapping("/publishEvent")
|
||||||
|
public R<Boolean> publishEvent(String code, Long id) {
|
||||||
|
ApplicationEvent event = FileEvent.createEvent(code, id);
|
||||||
|
if (event == null) {
|
||||||
|
return R.fail("事件名称错误");
|
||||||
|
}
|
||||||
|
applicationContext.publishEvent(event);
|
||||||
|
return R.status(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package org.springblade.file.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameters;
|
||||||
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springblade.core.boot.ctrl.BladeController;
|
||||||
|
import org.springblade.core.log.annotation.ApiLog;
|
||||||
|
import org.springblade.core.tenant.annotation.NonDS;
|
||||||
|
import org.springblade.core.tool.api.R;
|
||||||
|
import org.springblade.file.pojo.dto.FileTaskCreateDTO;
|
||||||
|
import org.springblade.file.pojo.dto.FileTaskUpdateDTO;
|
||||||
|
import org.springblade.file.pojo.dto.IdsDTO;
|
||||||
|
import org.springblade.file.pojo.vo.FileTaskUpdateVO;
|
||||||
|
import org.springblade.file.service.IFileTaskService;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName: FileTaskController
|
||||||
|
* @Author: zhaowei
|
||||||
|
* @Date: 2024/8/28
|
||||||
|
*/
|
||||||
|
@Valid
|
||||||
|
@NonDS
|
||||||
|
@RestController
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RequestMapping("/fileTask")
|
||||||
|
@Tag(name = "文件任务", description = "文件任务")
|
||||||
|
public class FileTaskController extends BladeController {
|
||||||
|
|
||||||
|
private final IFileTaskService fileTaskService;
|
||||||
|
|
||||||
|
@GetMapping("/queryFileTask")
|
||||||
|
@Operation(summary = "根据文件的MD5值查询文件任务", description = "文件的MD5值检查分段,参数名:md5")
|
||||||
|
public R<FileTaskUpdateVO> queryFileTask(@RequestParam(value = "md5") String md5) {
|
||||||
|
FileTaskUpdateVO fileTask = fileTaskService.queryFileTask(null, md5);
|
||||||
|
return R.data(fileTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiLog("上传任务-创建文件任务")
|
||||||
|
@PostMapping("/createFileTask")
|
||||||
|
@Operation(summary = "创建文件任务", description = "创建文件任务")
|
||||||
|
public R<FileTaskUpdateVO> createFileTask(@RequestBody FileTaskCreateDTO param) {
|
||||||
|
Long id = fileTaskService.createFileTask(param);
|
||||||
|
return R.data(fileTaskService.queryFileTask(id, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiLog("上传任务-更新文件任务进度")
|
||||||
|
@PostMapping("/updateFileTask")
|
||||||
|
@Operation(summary = "更新文件任务进度", description = "更新文件任务进度")
|
||||||
|
public R<FileTaskUpdateVO> updateFileTask(@RequestBody FileTaskUpdateDTO param) {
|
||||||
|
return R.data(fileTaskService.updateFileTask(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiLog("上传任务-修改文件任务状态为失败")
|
||||||
|
@PostMapping("/updateFailed")
|
||||||
|
@Operation(summary = "更新文件任务为失败", description = "更新文件任务为失败")
|
||||||
|
public R<FileTaskUpdateVO> updateFailed(@NotNull(message = "文件任务id不能为空") Long id) {
|
||||||
|
return R.data(fileTaskService.updateFailed(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiLog("上传任务-暂停文件任务")
|
||||||
|
@PostMapping("/updatePaused")
|
||||||
|
@Operation(summary = "更新文件任务为暂停", description = "更新文件任务为暂停")
|
||||||
|
public R<Boolean> updatePaused(@Validated @RequestBody IdsDTO param) {
|
||||||
|
return R.status(fileTaskService.updatePaused(param.getIds()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/getUploadUrl")
|
||||||
|
@Parameters({
|
||||||
|
@Parameter(name = "id", description = "文件任务id", in = ParameterIn.QUERY, schema = @Schema(type = "string")),
|
||||||
|
@Parameter(name = "partNumber", description = "分段编号", in = ParameterIn.QUERY, schema = @Schema(type = "int"))
|
||||||
|
})
|
||||||
|
@Operation(summary = "根据文件任务id查询上传链接", description = "根据文件任务id查询上传链接")
|
||||||
|
public R<String> getUploadUrl(Long id, Integer partNumber) {
|
||||||
|
String uploadUrl = fileTaskService.getUploadUrl(id, partNumber);
|
||||||
|
return R.data(uploadUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package org.springblade.file.convert;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingConstants;
|
||||||
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentAddDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentBatchAddDTO;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessAttachment;
|
||||||
|
import org.springblade.file.pojo.vo.AttachmentDetailVO;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/9/4
|
||||||
|
*/
|
||||||
|
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||||
|
public interface BusinessAttachmentConvert {
|
||||||
|
BusinessAttachment dto2entity(BusinessAttachmentAddDTO dto);
|
||||||
|
|
||||||
|
List<BusinessAttachment> dtos2entities(List<BusinessAttachmentAddDTO> dtos);
|
||||||
|
|
||||||
|
AttachmentDetailVO entity2vo(Attachment entity);
|
||||||
|
|
||||||
|
default List<BusinessAttachment> dto2entities(BusinessAttachmentBatchAddDTO dto) {
|
||||||
|
if (dto == null || dto.getDetails() == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
AtomicInteger sort = new AtomicInteger(1);
|
||||||
|
return dto.getDetails().stream()
|
||||||
|
.flatMap(detail -> detail.getAttachmentIds().stream().map(attachmentId -> {
|
||||||
|
BusinessAttachment businessAttachment = new BusinessAttachment();
|
||||||
|
businessAttachment.setAttachmentId(attachmentId);
|
||||||
|
businessAttachment.setBizId(dto.getBizId());
|
||||||
|
businessAttachment.setBizCode(detail.getBizCode());
|
||||||
|
businessAttachment.setSort(sort.getAndIncrement());
|
||||||
|
return businessAttachment;
|
||||||
|
})).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.springblade.file.convert;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingConstants;
|
||||||
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessUnzipTaskAddDTO;
|
||||||
|
import org.springblade.file.pojo.dto.FileTaskCreateDTO;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessUnzipTask;
|
||||||
|
import org.springblade.file.pojo.entity.FileTask;
|
||||||
|
import org.springblade.file.pojo.entity.FileTaskPart;
|
||||||
|
import org.springblade.file.pojo.vo.FileTaskUpdateVO;
|
||||||
|
import org.springblade.file.pojo.vo.FileTaskVO;
|
||||||
|
import org.springblade.file.pojo.vo.PartEtagVO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/22
|
||||||
|
*/
|
||||||
|
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||||
|
public interface FileTaskConvert {
|
||||||
|
|
||||||
|
FileTaskVO entity2vo(FileTask entity);
|
||||||
|
|
||||||
|
FileTaskUpdateVO entity2updateVo(FileTask entity);
|
||||||
|
|
||||||
|
FileTask dto2entity(FileTaskCreateDTO dto);
|
||||||
|
|
||||||
|
PartEtagVO entity2vo(FileTaskPart entity);
|
||||||
|
|
||||||
|
BusinessUnzipTask dto2entity(BusinessUnzipTaskAddDTO dto);
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package org.springblade.file.convert;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingConstants;
|
||||||
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
import org.springblade.file.pojo.dto.FileCertificateBatchRecognitionDTO;
|
||||||
|
import org.springblade.thirdparty.ocr.pojo.dto.CertificateBatchRecognitionDTO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2025/3/13
|
||||||
|
*/
|
||||||
|
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||||
|
public interface OCRConverter {
|
||||||
|
|
||||||
|
CertificateBatchRecognitionDTO dto2ocr(FileCertificateBatchRecognitionDTO dto);
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package org.springblade.file.exception;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件解压失败异常
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/11/11
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class UnzipFailException extends RuntimeException{
|
||||||
|
/**
|
||||||
|
* 解压目录
|
||||||
|
*/
|
||||||
|
private final File unzipDir;
|
||||||
|
|
||||||
|
public UnzipFailException(Throwable cause, File unzipDir) {
|
||||||
|
super(cause);
|
||||||
|
this.unzipDir = unzipDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnzipFailException(String message, File unzipDir) {
|
||||||
|
super(message);
|
||||||
|
this.unzipDir = unzipDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package org.springblade.file.feign;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.annotation.SentinelResource;
|
||||||
|
import io.swagger.v3.oas.annotations.Hidden;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springblade.core.log.utils.AssertUtils;
|
||||||
|
import org.springblade.core.tool.api.FR;
|
||||||
|
import org.springblade.core.tool.api.R;
|
||||||
|
import org.springblade.file.config.ObsProperties;
|
||||||
|
import org.springblade.file.pojo.dto.*;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
import org.springblade.file.pojo.vo.*;
|
||||||
|
import org.springblade.file.service.*;
|
||||||
|
import org.springblade.file.util.ObjectKeyUtils;
|
||||||
|
import org.springblade.thirdparty.ocr.pojo.vo.TransportCertificateVO;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/21
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Valid
|
||||||
|
@Hidden
|
||||||
|
@RestController
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class FileClient implements IFileClient, IFileUploadClient {
|
||||||
|
|
||||||
|
private final IAttachmentService attachmentService;
|
||||||
|
private final IBusinessAttachmentService businessAttachmentService;
|
||||||
|
private final IBusinessUnzipTaskService businessUnzipTaskService;
|
||||||
|
private final IOCRConvertService ocrConvertService;
|
||||||
|
private final IFileService fileService;
|
||||||
|
private final ObsProperties obsProperties;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@GetMapping(ATTACHMENT)
|
||||||
|
public FR<List<Attachment>> getAttachment(String id) {
|
||||||
|
return FR.data(attachmentService.getAttachment(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<AttachmentDetailVO> getAttachmentDetail(Long id) {
|
||||||
|
return FR.data(attachmentService.getDetail(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR saveAndRemoveBusinessAttachment(@RequestBody @Validated BusinessAttachmentBatchAddDTO param) {
|
||||||
|
return FR.status(businessAttachmentService.saveAndRemove(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR batchSaveAndRemoveBusinessAttachment(@RequestBody List<@Valid BusinessAttachmentAddDTO> params, @RequestParam(value = "bizId", required = false) Long bizId) {
|
||||||
|
return FR.status(businessAttachmentService.saveAndRemove(params, new BusinessAttachmentDeleteDTO(bizId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR batchSaveAndRemoveByParamBusinessAttachment(@RequestBody List<@Valid BusinessAttachmentAddDTO> params, @Valid BusinessAttachmentDeleteDTO deleteParam) {
|
||||||
|
return FR.status(businessAttachmentService.saveAndRemove(params, deleteParam));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR batchSaveAndRemoveBusinessAttachment(List<@Valid BusinessAttachmentAddDTO> params) {
|
||||||
|
return FR.status(businessAttachmentService.saveAndRemove(params, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR removeBusinessAttachment(@NotNull(message = "业务id不能为空") @RequestParam(value = "bizId", required = false) Long bizId) {
|
||||||
|
businessAttachmentService.removeByBizIds(List.of(bizId));
|
||||||
|
return FR.data(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<BusinessAttachmentVO>> getBusinessAttachments(@Validated @RequestBody BusinessAttachmentQueryDTO param) {
|
||||||
|
return FR.data(businessAttachmentService.queryList(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR saveBusinessUnzipTask(BusinessUnzipTaskAddDTO param) {
|
||||||
|
return FR.status(businessUnzipTaskService.save(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR updateBusinessUnzipTask(BusinessUnzipTaskUpdateDTO param) {
|
||||||
|
AssertUtils.notNull(param.getBizId(), "业务id不能为空");
|
||||||
|
return FR.status(businessUnzipTaskService.updateReupload(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR cancelBusinessUnzipTask(@NotNull(message = "业务id不能为空") Long bizId) {
|
||||||
|
return FR.status(businessUnzipTaskService.cancelBusinessUnzipTask(bizId, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR removeBusinessUnzipTask(Long bizId) {
|
||||||
|
return FR.status(businessUnzipTaskService.cancelBusinessUnzipTask(bizId, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<BusinessUnzipTaskListVO>> getBusinessUnzipTasksByBizIds(List<Long> bizIds) {
|
||||||
|
return FR.data(businessUnzipTaskService.getBusinessUnzipTasksByBizIds(bizIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<BusinessUnzipDetailListVO>> queryBusinessUnzipDetail(@NotNull(message = "业务id不能为空") Long bizId) {
|
||||||
|
return FR.data(businessUnzipTaskService.queryBusinessUnzipDetail(bizId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SentinelResource("ocr:batchCards")
|
||||||
|
@Override
|
||||||
|
public FR<TransportCertificateVO> recognitionTransportCertificates(@Validated @RequestBody FileCertificateBatchRecognitionDTO param) {
|
||||||
|
return FR.data(ocrConvertService.recognitionTransportCertificate(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<FileUrlVO>> getFileUrls(IdsDTO param) {
|
||||||
|
List<FileUrlVO> list = attachmentService.listByIds(param.getIds()).stream()
|
||||||
|
.map(attachment -> {
|
||||||
|
String fileUrl = fileService.getFileUrl(attachment.getObjectKey(), attachment.getAttachmentName(), null);
|
||||||
|
return new FileUrlVO(attachment.getId(), fileUrl);
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
return FR.data(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<List<Attachment>> ossUpload(MultipartFile[] files) {
|
||||||
|
R<List<Attachment>> r = attachmentService.batchOssUpload(files, null);
|
||||||
|
return R.isNotSuccess(r) ? FR.fail(r.getCode(), r.getMsg()) : FR.data(r.getData(), r.getMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FR<TempFileUrlVO> ossUploadTemp(MultipartFile file, Integer expires) {
|
||||||
|
if (expires == null) {
|
||||||
|
// 默认1天过期
|
||||||
|
expires = 1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String objectKey = ObjectKeyUtils.generateObjectKey(obsProperties.getTmpUploadDir(), file.getOriginalFilename());
|
||||||
|
String fileUrl = fileService.uploadTempFile(objectKey, file.getInputStream(), expires);
|
||||||
|
return FR.data(new TempFileUrlVO(objectKey, fileUrl));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("上传临时文件异常", e);
|
||||||
|
return FR.fail("上传临时文件异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package org.springblade.file.listener;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件事件枚举
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2024/11/22
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum FileEvent {
|
||||||
|
/**
|
||||||
|
* 上传完成事件
|
||||||
|
*/
|
||||||
|
UPLOADED(FileUploadedEvent::new),
|
||||||
|
/**
|
||||||
|
* 解压开始事件
|
||||||
|
*/
|
||||||
|
UNZIP_START(UnzipStartEvent::new),
|
||||||
|
/**
|
||||||
|
* 解压完成事件
|
||||||
|
*/
|
||||||
|
UNZIP_COMPLETED(UnzipCompletedEvent::new),
|
||||||
|
/**
|
||||||
|
* 解压失败事件
|
||||||
|
*/
|
||||||
|
UNZIP_FAILED(UnzipFailEvent::new),
|
||||||
|
;
|
||||||
|
/**
|
||||||
|
* 事件函数
|
||||||
|
*/
|
||||||
|
private final Function<Long, ApplicationEvent> eventFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据编码创建事件
|
||||||
|
* @param code
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static ApplicationEvent createEvent(String code, Long id) {
|
||||||
|
if (code == null || code.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Stream.of(values())
|
||||||
|
.filter(event -> event.name().equalsIgnoreCase(code))
|
||||||
|
.findFirst()
|
||||||
|
.map(event -> event.getEventFunction().apply(id))
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
package org.springblade.file.listener;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springblade.core.log.exception.ServiceException;
|
||||||
|
import org.springblade.core.log.utils.AssertUtils;
|
||||||
|
import org.springblade.file.callback.UnzipCallback;
|
||||||
|
import org.springblade.file.callback.UnzipEventType;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessUnzipTask;
|
||||||
|
import org.springblade.file.pojo.enums.UnzipTask;
|
||||||
|
import org.springblade.file.pojo.vo.FileVO;
|
||||||
|
import org.springblade.file.service.IBusinessUnzipDetailService;
|
||||||
|
import org.springblade.file.service.IBusinessUnzipTaskService;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.event.TransactionPhase;
|
||||||
|
import org.springframework.transaction.event.TransactionalEventListener;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件监听器
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/11/8
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class FileListener {
|
||||||
|
|
||||||
|
private final IBusinessUnzipTaskService taskService;
|
||||||
|
private final IBusinessUnzipDetailService detailService;
|
||||||
|
private final Map<String, UnzipCallback> callbackMap;
|
||||||
|
|
||||||
|
public FileListener(IBusinessUnzipTaskService taskService, IBusinessUnzipDetailService detailService, List<UnzipCallback> callbacks) {
|
||||||
|
this.taskService = taskService;
|
||||||
|
this.detailService = detailService;
|
||||||
|
this.callbackMap = callbacks.stream()
|
||||||
|
.collect(Collectors.toMap(UnzipCallback::getBizCode, Function.identity(), (a, b) -> {
|
||||||
|
throw new ServiceException("重复的解压完成回调接口");
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传完成监听器
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
@Async
|
||||||
|
@TransactionalEventListener(value = FileUploadedEvent.class, phase = TransactionPhase.AFTER_COMMIT, fallbackExecution = true)
|
||||||
|
public void fileUploaded(FileUploadedEvent event) {
|
||||||
|
try {
|
||||||
|
Long fileTaskId = event.getFileTaskId();
|
||||||
|
log.info("文件上传任务完成事件 id:{}", fileTaskId);
|
||||||
|
BusinessUnzipTask businessUnzipTask = taskService.getOne(Wrappers.<BusinessUnzipTask>lambdaQuery()
|
||||||
|
.eq(BusinessUnzipTask::getRelateId, fileTaskId)
|
||||||
|
.last("limit 1")
|
||||||
|
);
|
||||||
|
if (businessUnzipTask != null) {
|
||||||
|
// 存在解压任务,更新任务为上传完成
|
||||||
|
BusinessUnzipTask updateParam = new BusinessUnzipTask();
|
||||||
|
updateParam.setId(businessUnzipTask.getId());
|
||||||
|
updateParam.setStatus(UnzipTask.Status.UPLOADED.getCode());
|
||||||
|
taskService.updateById(updateParam);
|
||||||
|
// 解压开始
|
||||||
|
this.unzipStart(new UnzipStartEvent(businessUnzipTask));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文件上传任务完成事件 异常", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压开始
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
@Async
|
||||||
|
@TransactionalEventListener(value = UnzipStartEvent.class, phase = TransactionPhase.AFTER_COMMIT, fallbackExecution = true)
|
||||||
|
public void unzipStart(UnzipStartEvent event) {
|
||||||
|
try {
|
||||||
|
Long unzipTaskId = event.getUnzipTaskId();
|
||||||
|
BusinessUnzipTask task = event.getTask();
|
||||||
|
log.info("解压开始事件 id:{} 业务解压任务:{}", unzipTaskId, JSON.toJSONString(task));
|
||||||
|
if (task == null) {
|
||||||
|
// 手动触发时,只有id
|
||||||
|
task = taskService.getById(unzipTaskId);
|
||||||
|
}
|
||||||
|
// 回调接口
|
||||||
|
callback(task, UnzipEventType.START);
|
||||||
|
// 解压并保存
|
||||||
|
detailService.unzipAndSaveAsync(task.getId(), taskService.getFile(task));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解压开始事件 异常", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压完成监听器
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
@Async
|
||||||
|
@EventListener(UnzipCompletedEvent.class)
|
||||||
|
public void unzipCompleted(UnzipCompletedEvent event) {
|
||||||
|
try {
|
||||||
|
Long unzipTaskId = event.getUnzipTaskId();
|
||||||
|
log.info("解压完成事件 id:{}", unzipTaskId);
|
||||||
|
// 查询解压任务
|
||||||
|
BusinessUnzipTask unzipTask = taskService.getById(unzipTaskId);
|
||||||
|
AssertUtils.notNull(unzipTask, "解压任务不存在");
|
||||||
|
// 更新解压任务状态
|
||||||
|
BusinessUnzipTask updateParam = new BusinessUnzipTask();
|
||||||
|
updateParam.setId(unzipTaskId);
|
||||||
|
updateParam.setStatus(UnzipTask.Status.FINISHED.getCode());
|
||||||
|
taskService.updateById(updateParam);
|
||||||
|
// 回调接口
|
||||||
|
callback(unzipTask, UnzipEventType.SUCCESS);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解压完成事件 异常", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压失败监听器
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
@Async
|
||||||
|
@EventListener(UnzipFailEvent.class)
|
||||||
|
public void unzipFail(UnzipFailEvent event) {
|
||||||
|
try {
|
||||||
|
Long unzipTaskId = event.getUnzipTaskId();
|
||||||
|
log.info("解压失败事件 id:{}", unzipTaskId);
|
||||||
|
// 查询解压任务
|
||||||
|
BusinessUnzipTask unzipTask = taskService.getById(unzipTaskId);
|
||||||
|
AssertUtils.notNull(unzipTask, "解压任务不存在");
|
||||||
|
// 更新解压任务状态
|
||||||
|
BusinessUnzipTask updateParam = new BusinessUnzipTask();
|
||||||
|
updateParam.setId(unzipTaskId);
|
||||||
|
updateParam.setStatus(UnzipTask.Status.UNZIP_FAIL.getCode());
|
||||||
|
taskService.updateById(updateParam);
|
||||||
|
// 回调接口
|
||||||
|
callback(unzipTask, UnzipEventType.FAIL);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解压失败事件 异常", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调接口
|
||||||
|
* @param unzipTask
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
private void callback(BusinessUnzipTask unzipTask, UnzipEventType event) {
|
||||||
|
if (unzipTask == null) {
|
||||||
|
log.warn("解压回调接口 解压任务为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UnzipCallback unzipCallback = callbackMap.get(unzipTask.getBizCode());
|
||||||
|
if (unzipCallback == null) {
|
||||||
|
log.error("未配置业务编码:{}对应的解压回调接口", unzipTask.getBizCode());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Boolean result = null;
|
||||||
|
try {
|
||||||
|
result = unzipCallback.callback(unzipTask.getBizId(), event.name());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解压回调接口异常", e);
|
||||||
|
}
|
||||||
|
log.info("解压回调接口参数:{} 业务编码:{} 事件:{} 结果:{}", unzipTask.getBizId(), unzipTask.getBizCode(), event.name(), result);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.springblade.file.listener;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/11/8
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class FileUploadedEvent extends ApplicationEvent {
|
||||||
|
/**
|
||||||
|
* 文件任务id
|
||||||
|
*/
|
||||||
|
private final Long fileTaskId;
|
||||||
|
|
||||||
|
public FileUploadedEvent(Long fileTaskId) {
|
||||||
|
super(fileTaskId);
|
||||||
|
this.fileTaskId = fileTaskId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.springblade.file.listener;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压完成事件
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/11/8
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class UnzipCompletedEvent extends ApplicationEvent {
|
||||||
|
/**
|
||||||
|
* 解压任务id
|
||||||
|
*/
|
||||||
|
private final Long unzipTaskId;
|
||||||
|
|
||||||
|
public UnzipCompletedEvent(Long unzipTaskId) {
|
||||||
|
super(unzipTaskId);
|
||||||
|
this.unzipTaskId = unzipTaskId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.springblade.file.listener;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压失败事件
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/11/8
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class UnzipFailEvent extends ApplicationEvent {
|
||||||
|
/**
|
||||||
|
* 解压任务id
|
||||||
|
*/
|
||||||
|
private final Long unzipTaskId;
|
||||||
|
|
||||||
|
public UnzipFailEvent(Long unzipTaskId) {
|
||||||
|
super(unzipTaskId);
|
||||||
|
this.unzipTaskId = unzipTaskId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package org.springblade.file.listener;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessUnzipTask;
|
||||||
|
import org.springblade.file.pojo.vo.FileVO;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压开始事件
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/11/8
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class UnzipStartEvent extends ApplicationEvent {
|
||||||
|
/**
|
||||||
|
* 解压任务id
|
||||||
|
*/
|
||||||
|
private final Long unzipTaskId;
|
||||||
|
/**
|
||||||
|
* 解压任务
|
||||||
|
*/
|
||||||
|
private final BusinessUnzipTask task;
|
||||||
|
|
||||||
|
public UnzipStartEvent(Long unzipTaskId) {
|
||||||
|
super(unzipTaskId);
|
||||||
|
this.unzipTaskId = unzipTaskId;
|
||||||
|
this.task = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnzipStartEvent(BusinessUnzipTask task) {
|
||||||
|
super(task);
|
||||||
|
this.task = task;
|
||||||
|
this.unzipTaskId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.file.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AttachmentMapper 接口
|
||||||
|
*
|
||||||
|
* @author zhaowei
|
||||||
|
*/
|
||||||
|
public interface AttachmentMapper extends BaseMapper<Attachment> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.springblade.file.mapper.AttachmentMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.springblade.file.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentQueryDTO;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessAttachment;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessAttachmentVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 Mapper 接口
|
||||||
|
*
|
||||||
|
* @author BladeX
|
||||||
|
* @since 2024-09-04
|
||||||
|
*/
|
||||||
|
public interface BusinessAttachmentMapper extends BaseMapper<BusinessAttachment> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询业务附件列表
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<BusinessAttachmentVO> queryList(BusinessAttachmentQueryDTO param);
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.springblade.file.mapper.BusinessAttachmentMapper">
|
||||||
|
|
||||||
|
<!-- 通用查询映射结果 -->
|
||||||
|
<resultMap id="businessAttachmentResultMap" type="org.springblade.file.pojo.entity.BusinessAttachment">
|
||||||
|
<result column="id" property="id"/>
|
||||||
|
<result column="tenant_id" property="tenantId"/>
|
||||||
|
<result column="biz_id" property="bizId"/>
|
||||||
|
<result column="biz_code" property="bizCode"/>
|
||||||
|
<result column="attachment_id" property="attachmentId"/>
|
||||||
|
<result column="`desc`" property="desc"/>
|
||||||
|
<result column="sort" property="sort"/>
|
||||||
|
<result column="create_user" property="createUser"/>
|
||||||
|
<result column="create_time" property="createTime"/>
|
||||||
|
<result column="update_user" property="updateUser"/>
|
||||||
|
<result column="update_time" property="updateTime"/>
|
||||||
|
<result column="is_deleted" property="isDeleted"/>
|
||||||
|
</resultMap>
|
||||||
|
<select id="queryList" resultType="org.springblade.file.pojo.vo.BusinessAttachmentVO">
|
||||||
|
select
|
||||||
|
bba.id,
|
||||||
|
bba.biz_id,
|
||||||
|
bba.biz_code,
|
||||||
|
bba.attachment_id,
|
||||||
|
bba.`desc`,
|
||||||
|
bba.sort,
|
||||||
|
ba.dir,
|
||||||
|
ba.attachment_name,
|
||||||
|
ba.size,
|
||||||
|
ba.object_key,
|
||||||
|
ba.create_user uploadUserId,
|
||||||
|
ba.create_user_name uploadUserName,
|
||||||
|
ba.create_time,
|
||||||
|
ba.create_user_name
|
||||||
|
from blade_business_attachment bba
|
||||||
|
left join blade_attachment ba on ba.id = bba.attachment_id
|
||||||
|
where bba.is_deleted = 0 and ba.is_deleted = 0 and bba.biz_id in <foreach collection="bizIds" item="item" open="(" close=")" separator=",">#{item}</foreach>
|
||||||
|
<if test="bizCode != null and bizCode != ''">
|
||||||
|
and bba.biz_code = #{bizCode}
|
||||||
|
</if>
|
||||||
|
<if test="bizCodes != null and bizCodes.size() > 0">
|
||||||
|
and bba.biz_code in <foreach collection="bizCodes" item="item" open="(" close=")" separator=",">#{item}</foreach>
|
||||||
|
</if>
|
||||||
|
order by bba.biz_id, bba.sort, bba.id
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.springblade.file.mapper;
|
||||||
|
|
||||||
|
import org.springblade.file.pojo.entity.BusinessUnzipDetail;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 业务解压明细表 Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2024-10-30
|
||||||
|
*/
|
||||||
|
public interface BusinessUnzipDetailMapper extends BaseMapper<BusinessUnzipDetail> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.springblade.file.mapper.BusinessUnzipDetailMapper">
|
||||||
|
|
||||||
|
<!-- 通用查询映射结果 -->
|
||||||
|
<resultMap id="BaseResultMap" type="org.springblade.file.pojo.entity.BusinessUnzipDetail">
|
||||||
|
<id column="id" property="id" />
|
||||||
|
<result column="business_unzip_task_id" property="businessUnzipTaskId" />
|
||||||
|
<result column="attachment_id" property="attachmentId" />
|
||||||
|
<result column="create_user" property="createUser" />
|
||||||
|
<result column="create_time" property="createTime" />
|
||||||
|
<result column="update_user" property="updateUser" />
|
||||||
|
<result column="update_time" property="updateTime" />
|
||||||
|
<result column="is_deleted" property="isDeleted" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<!-- 通用查询结果列 -->
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
id, business_unzip_task_id, attachment_id, create_user, create_time, update_user, update_time, is_deleted
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package org.springblade.file.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessUnzipTaskQueryDTO;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessUnzipTask;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessUnzipDetailListVO;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessUnzipTaskListVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 业务解压任务表 Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2024-10-28
|
||||||
|
*/
|
||||||
|
public interface BusinessUnzipTaskMapper extends BaseMapper<BusinessUnzipTask> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询列表
|
||||||
|
* @param page
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<BusinessUnzipTaskListVO> selectTaskList(IPage<BusinessUnzipTask> page, @Param("param") BusinessUnzipTaskQueryDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据业务id查询解压明细
|
||||||
|
* @param bizId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<BusinessUnzipDetailListVO> queryBusinessUnzipDetail(@Param("bizId") Long bizId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.springblade.file.mapper.BusinessUnzipTaskMapper">
|
||||||
|
|
||||||
|
<!-- 通用查询映射结果 -->
|
||||||
|
<resultMap id="BaseResultMap" type="org.springblade.file.pojo.entity.BusinessUnzipTask">
|
||||||
|
<id column="id" property="id" />
|
||||||
|
<result column="biz_id" property="bizId" />
|
||||||
|
<result column="department_id" property="departmentId" />
|
||||||
|
<result column="biz_code" property="bizCode" />
|
||||||
|
<result column="doc_code" property="docCode" />
|
||||||
|
<result column="relate_type" property="relateType" />
|
||||||
|
<result column="relate_id" property="relateId" />
|
||||||
|
<result column="status" property="status" />
|
||||||
|
<result column="tenant_id" property="tenantId" />
|
||||||
|
<result column="create_user" property="createUser" />
|
||||||
|
<result column="create_time" property="createTime" />
|
||||||
|
<result column="update_user" property="updateUser" />
|
||||||
|
<result column="update_time" property="updateTime" />
|
||||||
|
<result column="is_deleted" property="isDeleted" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<!-- 通用查询结果列 -->
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
id, biz_id, department_id, biz_code, doc_code, relate_type, relate_id, status, tenant_id, create_user, create_time, update_user, update_time, is_deleted
|
||||||
|
</sql>
|
||||||
|
<select id="selectTaskList" resultType="org.springblade.file.pojo.vo.BusinessUnzipTaskListVO">
|
||||||
|
select
|
||||||
|
but.id,
|
||||||
|
but.biz_id,
|
||||||
|
but.biz_code,
|
||||||
|
but.doc_code,
|
||||||
|
but.relate_type,
|
||||||
|
but.relate_id,
|
||||||
|
but.department_id,
|
||||||
|
but.create_user b_create_user,
|
||||||
|
ft.md5,
|
||||||
|
ft.object_key,
|
||||||
|
ft.attachment_name,
|
||||||
|
ft.suffix,
|
||||||
|
ft.size,
|
||||||
|
ft.chunk_size,
|
||||||
|
ft.chunk_total,
|
||||||
|
ft.current_index,
|
||||||
|
ft.upload_id,
|
||||||
|
ft.status,
|
||||||
|
ft.create_user,
|
||||||
|
ft.create_user_name,
|
||||||
|
ft.create_time,
|
||||||
|
ft.update_user,
|
||||||
|
ft.update_user_name,
|
||||||
|
ft.update_time
|
||||||
|
from blade_business_unzip_task but
|
||||||
|
left join blade_file_task ft on ft.id = but.relate_id
|
||||||
|
where but.is_deleted = 0 and ft.is_deleted = 0
|
||||||
|
<if test="param.bizIds != null and param.bizIds.size() > 0">
|
||||||
|
and but.biz_id in <foreach collection="param.bizIds" item="item" open="(" close=")" separator=",">#{item}</foreach>
|
||||||
|
</if>
|
||||||
|
<if test="param.docCode != null and param.docCode != ''">
|
||||||
|
and but.doc_code like concat('%',#{param.docCode},'%')
|
||||||
|
</if>
|
||||||
|
<if test="param.relateType != null and param.relateType != ''">
|
||||||
|
and but.relate_type = #{param.relateType}
|
||||||
|
</if>
|
||||||
|
<if test="param.currentUserId != null">
|
||||||
|
and but.create_user = #{param.currentUserId}
|
||||||
|
</if>
|
||||||
|
<if test="param.attachmentName != null and param.attachmentName != ''">
|
||||||
|
and ft.attachment_name like concat('%',#{param.attachmentName},'%')
|
||||||
|
</if>
|
||||||
|
<if test="param.status != null and param.status != ''">
|
||||||
|
and ft.status = #{param.status}
|
||||||
|
</if>
|
||||||
|
order by Field(ft.status, 'uploading','failed', 'completed'), but.id desc
|
||||||
|
</select>
|
||||||
|
<select id="queryBusinessUnzipDetail" resultType="org.springblade.file.pojo.vo.BusinessUnzipDetailListVO">
|
||||||
|
select
|
||||||
|
bbud.id,
|
||||||
|
bbud.attachment_id,
|
||||||
|
ba.dir,
|
||||||
|
ba.attachment_name,
|
||||||
|
ba.size,
|
||||||
|
ba.object_key,
|
||||||
|
ba.create_user uploadUserId,
|
||||||
|
ba.create_user_name uploadUserName,
|
||||||
|
ba.create_time,
|
||||||
|
ba.create_user_name
|
||||||
|
from blade_business_unzip_task bbut
|
||||||
|
left join blade_business_unzip_detail bbud on bbud.business_unzip_task_id = bbut.id
|
||||||
|
left join blade_attachment ba on bbud.attachment_id = ba.id
|
||||||
|
where bbut.is_deleted = 0 and bbud.is_deleted = 0 and ba.is_deleted = 0
|
||||||
|
and bbut.biz_id = #{bizId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.file.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.springblade.file.pojo.entity.FileTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FileTaskMapper 接口
|
||||||
|
*
|
||||||
|
* @author zhaowei
|
||||||
|
*/
|
||||||
|
public interface FileTaskMapper extends BaseMapper<FileTask> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.springblade.file.mapper.FileTaskMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.file.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.springblade.file.pojo.entity.FileTaskPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FileUploadRecordMapper 接口
|
||||||
|
*
|
||||||
|
* @author zhaowei
|
||||||
|
*/
|
||||||
|
public interface FileTaskPartMapper extends BaseMapper<FileTaskPart> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.springblade.file.mapper.FileTaskPartMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.file.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.springblade.core.tool.api.R;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
import org.springblade.file.pojo.vo.AttachmentDetailVO;
|
||||||
|
import org.springblade.file.pojo.vo.FileVO;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务类
|
||||||
|
*
|
||||||
|
* @author zhaowei
|
||||||
|
*/
|
||||||
|
public interface IAttachmentService extends IService<Attachment> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量上传
|
||||||
|
*
|
||||||
|
* @param files
|
||||||
|
* @param fileName 文件名,如果 files只有1个,且fileName不为空,设置文件名为 fileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
R<List<Attachment>> batchOssUpload(MultipartFile[] files, String fileName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取附件,多个附件id用逗号分割
|
||||||
|
* @param id
|
||||||
|
* @return List<Attachment>
|
||||||
|
*/
|
||||||
|
List<Attachment> getAttachment(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量上传解压缩文件并删除文件
|
||||||
|
*
|
||||||
|
* @param files
|
||||||
|
* @param workDir 工作目录,取文件相对于工作目录的相对路径作为前缀
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<Attachment> batchOssUploadUnzipFilesAndDelete(List<File> files, File workDir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新事务批量保存
|
||||||
|
* @param list
|
||||||
|
*/
|
||||||
|
void batchSaveWithNewTransaction(List<Attachment> list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取附件详情
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
AttachmentDetailVO getDetail(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解压文件并上传
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<Attachment> unzipAndUpload(FileVO file);
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package org.springblade.file.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentAddDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentBatchAddDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentDeleteDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentQueryDTO;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessAttachment;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessAttachmentVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 服务类
|
||||||
|
*
|
||||||
|
* @author BladeX
|
||||||
|
* @since 2024-09-04
|
||||||
|
*/
|
||||||
|
public interface IBusinessAttachmentService extends IService<BusinessAttachment> {
|
||||||
|
/**
|
||||||
|
* 保存
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean saveAndRemove(BusinessAttachmentBatchAddDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存并删除
|
||||||
|
*
|
||||||
|
* @param params
|
||||||
|
* @param deleteParam 业务id不为空,则先删除
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean saveAndRemove(List<BusinessAttachmentAddDTO> params, BusinessAttachmentDeleteDTO deleteParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据bizId列表删除
|
||||||
|
*
|
||||||
|
* @param bizIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean removeByBizIds(List<Long> bizIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询业务附件列表
|
||||||
|
*
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<BusinessAttachmentVO> queryList(BusinessAttachmentQueryDTO param);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package org.springblade.file.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessUnzipDetail;
|
||||||
|
import org.springblade.file.pojo.vo.FileVO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 业务解压明细表 服务类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2024-10-30
|
||||||
|
*/
|
||||||
|
public interface IBusinessUnzipDetailService extends IService<BusinessUnzipDetail> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步解压并保存解压明细
|
||||||
|
* @param unzipTaskId 解压任务id
|
||||||
|
* @param file obs对象存储的key合md5值,md5有可能为空
|
||||||
|
*/
|
||||||
|
void unzipAndSaveAsync(Long unzipTaskId, FileVO file);
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package org.springblade.file.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessUnzipTaskAddDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessUnzipTaskQueryDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessUnzipTaskUpdateDTO;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessUnzipTask;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessUnzipDetailListVO;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessUnzipTaskListVO;
|
||||||
|
import org.springblade.file.pojo.vo.FileVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 业务解压任务表 服务类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2024-10-28
|
||||||
|
*/
|
||||||
|
public interface IBusinessUnzipTaskService extends IService<BusinessUnzipTask> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存业务解压任务
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean save(BusinessUnzipTaskAddDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取obs对象存储的key
|
||||||
|
* @param task
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getObjectKey(BusinessUnzipTask task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件对象
|
||||||
|
* @param task
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
FileVO getFile(BusinessUnzipTask task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务解压任务分页查询
|
||||||
|
* @param page
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
IPage<BusinessUnzipTaskListVO> selectPage(IPage<BusinessUnzipTask> page, BusinessUnzipTaskQueryDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务文件解压任务更新(重新上传)
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean updateReupload(BusinessUnzipTaskUpdateDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据业务id删除业务文件解压任务
|
||||||
|
* @param bizId
|
||||||
|
* @param cancelFile 是否取消文件,如果取消,上传完成后取消会报错
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean cancelBusinessUnzipTask(Long bizId, boolean cancelFile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据业务id查询解压明细
|
||||||
|
* @param bizId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<BusinessUnzipDetailListVO> queryBusinessUnzipDetail(Long bizId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据业务id列表查询解压任务列表
|
||||||
|
* @param bizIds
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<BusinessUnzipTaskListVO> getBusinessUnzipTasksByBizIds(List<Long> bizIds);
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.springblade.file.service;
|
||||||
|
|
||||||
|
import org.springblade.file.pojo.vo.FileHandleVO;
|
||||||
|
import org.springblade.file.pojo.vo.FileVO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件处理
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/22
|
||||||
|
*/
|
||||||
|
public interface IFileHandleService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件并解压
|
||||||
|
*
|
||||||
|
* @param file obs对象存储的key合md5,md5可能为空
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
FileHandleVO downloadAndUnzip(FileVO file);
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
package org.springblade.file.service;
|
||||||
|
|
||||||
|
import org.springblade.file.pojo.vo.PartEtagVO;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件接口
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/21
|
||||||
|
*/
|
||||||
|
public interface IFileService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* @param objectKey 文件key
|
||||||
|
* @param is 输入流
|
||||||
|
*/
|
||||||
|
void uploadFile(String objectKey, InputStream is);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传临时文件
|
||||||
|
* @param objectKey 文件key
|
||||||
|
* @param is 输入流
|
||||||
|
* @param expires 过期时间,单位天,过期后自动删除
|
||||||
|
*/
|
||||||
|
String uploadTempFile(String objectKey, InputStream is, Integer expires);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* @param objectKey 文件key
|
||||||
|
* @param file 文件
|
||||||
|
*/
|
||||||
|
void uploadFile(String objectKey, File file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化分片上传
|
||||||
|
*
|
||||||
|
* @param objectKey 文件key
|
||||||
|
* @return 上传任务id
|
||||||
|
*/
|
||||||
|
String initiateMultipartUpload(String objectKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分段上传
|
||||||
|
* @param objectKey 文件key
|
||||||
|
* @param uploadId 上传任务id
|
||||||
|
* @param file 文件
|
||||||
|
* @param partNumber 分段编号
|
||||||
|
* @param offset 偏移位
|
||||||
|
* @param partSize 分段大小
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
PartEtagVO uploadPart(String objectKey, String uploadId, File file, int partNumber, Long offset, Long partSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完成分段上传任务
|
||||||
|
* @param objectKey 文件key
|
||||||
|
* @param uploadId 上传任务id
|
||||||
|
* @param partEtagVOS 要合并的分段
|
||||||
|
*/
|
||||||
|
void completeMultipartUpload(String objectKey, String uploadId, List<PartEtagVO> partEtagVOS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消分段上传任务
|
||||||
|
* @param objectKey
|
||||||
|
* @param uploadId
|
||||||
|
*/
|
||||||
|
void cancelMultipartUpload(String objectKey, String uploadId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件链接
|
||||||
|
* @param objectKey 文件key
|
||||||
|
* @param expires 过期时间,单位秒
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getFileUrl(String objectKey, Long expires);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件链接
|
||||||
|
* @param objectKey 文件key
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @param expires 过期时间,单位秒
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getFileUrl(String objectKey, String fileName, Long expires);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件上传链接
|
||||||
|
*
|
||||||
|
* @param objectKey 文件key
|
||||||
|
* @param uploadId
|
||||||
|
* @param partNumber
|
||||||
|
* @param expires 过期时间,单位秒
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getUploadPartUrl(String objectKey, String uploadId, Integer partNumber, Long expires);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件链接批量
|
||||||
|
* @param objectKeys
|
||||||
|
* @param expires 过期时间
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<String> getFileUrls(List<String> objectKeys, Long expires);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
* @param objectKey
|
||||||
|
* @param downloadFile 下载路径
|
||||||
|
*/
|
||||||
|
void downloadFile(String objectKey, String downloadFile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件md5
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getFileMd5(File file);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.file.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.springblade.file.pojo.entity.FileTaskPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务类
|
||||||
|
*
|
||||||
|
* @author zhaowei
|
||||||
|
*/
|
||||||
|
public interface IFileTaskPartService extends IService<FileTaskPart> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.file.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.springblade.file.pojo.dto.FileTaskCreateDTO;
|
||||||
|
import org.springblade.file.pojo.dto.FileTaskUpdateDTO;
|
||||||
|
import org.springblade.file.pojo.entity.FileTask;
|
||||||
|
import org.springblade.file.pojo.vo.FileTaskUpdateVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务类
|
||||||
|
*
|
||||||
|
* @author zhaowei
|
||||||
|
*/
|
||||||
|
public interface IFileTaskService extends IService<FileTask> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件md5值查询最新一条上传任务记录
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @param md5
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
FileTaskUpdateVO queryFileTask(Long id, String md5);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建文件任务
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Long createFileTask(FileTaskCreateDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新文件任务进度
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
FileTaskUpdateVO updateFileTask(FileTaskUpdateDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件任务id获取上传链接
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @param partNumber
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getUploadUrl(Long id, Integer partNumber);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消文件任务
|
||||||
|
* @param taskIds
|
||||||
|
*/
|
||||||
|
void cancelBatchByIds(List<Long> taskIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新文件任务状态为失败
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
FileTaskUpdateVO updateFailed(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据id列表更新文件任务状态为暂停
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean updatePaused(List<Long> param);
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.springblade.file.service;
|
||||||
|
|
||||||
|
import org.springblade.file.pojo.dto.FileCertificateBatchRecognitionDTO;
|
||||||
|
import org.springblade.thirdparty.ocr.pojo.vo.TransportCertificateVO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ocr转换
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2025/3/13
|
||||||
|
*/
|
||||||
|
public interface IOCRConvertService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 凭证批量识别,不分类
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
TransportCertificateVO recognitionTransportCertificate(FileCertificateBatchRecognitionDTO param);
|
||||||
|
}
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.file.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.springblade.core.log.exception.ServiceException;
|
||||||
|
import org.springblade.core.tool.api.R;
|
||||||
|
import org.springblade.core.tool.utils.CollectionUtil;
|
||||||
|
import org.springblade.core.tool.utils.SpringUtil;
|
||||||
|
import org.springblade.core.tool.utils.StringPool;
|
||||||
|
import org.springblade.core.tool.utils.StringUtil;
|
||||||
|
import org.springblade.file.config.ObsProperties;
|
||||||
|
import org.springblade.file.convert.BusinessAttachmentConvert;
|
||||||
|
import org.springblade.file.exception.UnzipFailException;
|
||||||
|
import org.springblade.file.mapper.AttachmentMapper;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
import org.springblade.file.pojo.vo.AttachmentDetailVO;
|
||||||
|
import org.springblade.file.pojo.vo.FileHandleVO;
|
||||||
|
import org.springblade.file.pojo.vo.FileVO;
|
||||||
|
import org.springblade.file.service.IAttachmentService;
|
||||||
|
import org.springblade.file.service.IFileHandleService;
|
||||||
|
import org.springblade.file.service.IFileService;
|
||||||
|
import org.springblade.file.util.ObjectKeyUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务实现类
|
||||||
|
* @author zhaowei
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AttachmentServiceImpl extends ServiceImpl<AttachmentMapper, Attachment> implements IAttachmentService {
|
||||||
|
|
||||||
|
private final IFileService fileService;
|
||||||
|
private final BusinessAttachmentConvert convert;
|
||||||
|
private final ObsProperties obsProperties;
|
||||||
|
private final IFileHandleService fileHandleService;
|
||||||
|
private IAttachmentService self;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<List<Attachment>> batchOssUpload(MultipartFile[] files, String overWriteFileName){
|
||||||
|
try {
|
||||||
|
List<Attachment> attachmentList = new ArrayList<>();
|
||||||
|
// 文件数量为1个,且重写的文件名不为空,使用重写的文件名,给uniapp上传使用,uniapp上传的文件名不是原始文件名
|
||||||
|
boolean useOverWriteFileName = files.length == 1 && StringUtil.isNotBlank(overWriteFileName);
|
||||||
|
for(MultipartFile file : files){
|
||||||
|
String fileName = useOverWriteFileName ? overWriteFileName : file.getOriginalFilename();
|
||||||
|
String objectkey = ObjectKeyUtils.generateObjectKey(fileName);
|
||||||
|
fileService.uploadFile(objectkey, file.getInputStream());
|
||||||
|
// 插入附件数据
|
||||||
|
Attachment attachment = new Attachment();
|
||||||
|
Long id = IdWorker.getId();
|
||||||
|
attachment.setId(id);
|
||||||
|
attachment.setAttachmentName(fileName);
|
||||||
|
attachment.setSize(file.getSize());
|
||||||
|
attachment.setObjectKey(objectkey);
|
||||||
|
attachmentList.add(attachment);
|
||||||
|
}
|
||||||
|
this.saveBatch(attachmentList);
|
||||||
|
log.info("OBS上传 successfully");
|
||||||
|
return R.data(attachmentList,"OBS上传 successfully");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("OBS上传 failed,Exception", e);
|
||||||
|
}
|
||||||
|
return R.fail("OBS上传 failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Attachment> getAttachment(String id) {
|
||||||
|
return this.list(new LambdaQueryWrapper<Attachment>()
|
||||||
|
.in(Attachment::getId, Arrays.stream(id.split(",")).toList())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Attachment> batchOssUploadUnzipFilesAndDelete(List<File> files, File workDir) {
|
||||||
|
if (CollectionUtil.isEmpty(files)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<Attachment> attachmentList = new ArrayList<>();
|
||||||
|
AtomicInteger index = new AtomicInteger(1);
|
||||||
|
try {
|
||||||
|
log.info("上传文件总数:{}", files.size());
|
||||||
|
for(File file : files){
|
||||||
|
String fileName = file.getName();
|
||||||
|
// 压缩文件所在压缩包父目录相对路径
|
||||||
|
String dir = this.getDir(workDir, file);
|
||||||
|
// 获取上传的目录前缀
|
||||||
|
String prefixDir = getUploadPrefix();
|
||||||
|
String objectkey = prefixDir + ObjectKeyUtils.generateObjectKey(fileName);
|
||||||
|
fileService.uploadFile(objectkey, file);
|
||||||
|
int completeFiles = index.getAndIncrement();
|
||||||
|
if (completeFiles % 10 == 0) {
|
||||||
|
log.info("上传文件总进度:{}/{}", completeFiles, files.size());
|
||||||
|
}
|
||||||
|
// 插入附件数据
|
||||||
|
Attachment attachment = new Attachment();
|
||||||
|
Long id = IdWorker.getId();
|
||||||
|
attachment.setId(id);
|
||||||
|
attachment.setDir(dir);
|
||||||
|
attachment.setAttachmentName(fileName);
|
||||||
|
attachment.setSize(file.length());
|
||||||
|
attachment.setObjectKey(objectkey);
|
||||||
|
attachmentList.add(attachment);
|
||||||
|
}
|
||||||
|
log.info("上传文件完成:{}", files.size());
|
||||||
|
// 新事务批量保存
|
||||||
|
this.getSelf().batchSaveWithNewTransaction(attachmentList);
|
||||||
|
log.info("OBS上传 successfully");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("OBS上传失败", e);
|
||||||
|
throw new ServiceException("OBS上传失败");
|
||||||
|
}
|
||||||
|
// 返回新增的附件列表
|
||||||
|
return attachmentList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取上传文件目录前缀
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getUploadPrefix() {
|
||||||
|
// 上传路径前缀 = 配置的解压上传路径 + /
|
||||||
|
return obsProperties.getUnzipUploadDir() + StringPool.SLASH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取压缩文件所在压缩包父目录的相对路径,结尾不带/
|
||||||
|
* @param workDir 工作目录,解压的根目录
|
||||||
|
* @param file 解压后的文件
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getDir(File workDir, File file) {
|
||||||
|
if (workDir == null) {
|
||||||
|
return StringPool.EMPTY;
|
||||||
|
}
|
||||||
|
Path workDirPath = workDir.toPath();
|
||||||
|
Path filePath = file.toPath();
|
||||||
|
return workDirPath.relativize(filePath).toString()
|
||||||
|
// 去掉文件名以及文件所在父目录的后缀/或\
|
||||||
|
.replace(File.separator + file.getName(), "")
|
||||||
|
// 将文件分隔符替换为/,windows下是\,需要处理
|
||||||
|
.replace(File.separator, StringPool.SLASH);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||||
|
@Override
|
||||||
|
public void batchSaveWithNewTransaction(List<Attachment> list) {
|
||||||
|
this.saveBatch(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AttachmentDetailVO getDetail(Long id) {
|
||||||
|
if (id == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Attachment attachment = this.getById(id);
|
||||||
|
if (attachment == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
AttachmentDetailVO detailVO = convert.entity2vo(attachment);
|
||||||
|
// 查询下载链接
|
||||||
|
String fileUrl = fileService.getFileUrl(attachment.getObjectKey(), null);
|
||||||
|
detailVO.setUrl(fileUrl);
|
||||||
|
return detailVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Attachment> unzipAndUpload(FileVO file) {
|
||||||
|
// 1. 下载并解压文件
|
||||||
|
try {
|
||||||
|
FileHandleVO fileHandleVO = fileHandleService.downloadAndUnzip(file);
|
||||||
|
List<File> unzippedFiles = fileHandleVO.getUnzippedFiles();
|
||||||
|
if (CollectionUtil.isEmpty(unzippedFiles)) {
|
||||||
|
log.warn("下载解压文件为空 objectKey:{}", file.getObjectKey());
|
||||||
|
throw new UnzipFailException("解压文件为空", fileHandleVO.getUnzippedDir());
|
||||||
|
}
|
||||||
|
File unzippedDir = fileHandleVO.getUnzippedDir();
|
||||||
|
// 2. 上传文件
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
List<Attachment> attachments = getSelf().batchOssUploadUnzipFilesAndDelete(unzippedFiles, unzippedDir);
|
||||||
|
if (CollectionUtil.isEmpty(attachments)) {
|
||||||
|
log.warn("上传解压文件为空 objectKey:{}", file.getObjectKey());
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
// 删除下载的压缩文件
|
||||||
|
fileHandleVO.getDownloadFile().delete();
|
||||||
|
// 删除解压后的目录
|
||||||
|
FileUtils.deleteQuietly(unzippedDir);
|
||||||
|
return attachments;
|
||||||
|
} finally {
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
log.info("文件:{} 解压后上传完成 耗时:{}", file.getObjectKey(), end - start);
|
||||||
|
}
|
||||||
|
} catch (UnzipFailException e) {
|
||||||
|
// 文件解压失败,删除解压后的文件
|
||||||
|
File unzipDir = e.getUnzipDir();
|
||||||
|
// 删除解压后的目录
|
||||||
|
FileUtils.deleteQuietly(unzipDir);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自己
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private IAttachmentService getSelf() {
|
||||||
|
if (self == null) {
|
||||||
|
self = SpringUtil.getBean(IAttachmentService.class);
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
package org.springblade.file.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springblade.core.secure.utils.AuthUtil;
|
||||||
|
import org.springblade.core.tool.constant.BladeConstant;
|
||||||
|
import org.springblade.core.tool.utils.StringUtil;
|
||||||
|
import org.springblade.file.convert.BusinessAttachmentConvert;
|
||||||
|
import org.springblade.file.mapper.BusinessAttachmentMapper;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentAddDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentBatchAddDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentDeleteDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessAttachmentQueryDTO;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessAttachment;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessAttachmentVO;
|
||||||
|
import org.springblade.file.service.IBusinessAttachmentService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务附件信息表 服务实现类
|
||||||
|
*
|
||||||
|
* @author BladeX
|
||||||
|
* @since 2024-09-04
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class BusinessAttachmentServiceImpl extends ServiceImpl<BusinessAttachmentMapper, BusinessAttachment> implements IBusinessAttachmentService {
|
||||||
|
|
||||||
|
private final BusinessAttachmentConvert convert;
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public boolean saveAndRemove(BusinessAttachmentBatchAddDTO param) {
|
||||||
|
if (param == null) {
|
||||||
|
log.warn("批量保存业务附件,参数为空");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (param.isRemove() && param.getBizId() != null) {
|
||||||
|
// 先删除
|
||||||
|
this.removeByBizIds(List.of(param.getBizId()));
|
||||||
|
}
|
||||||
|
List<BusinessAttachment> addList = convert.dto2entities(param);
|
||||||
|
if (CollectionUtil.isNotEmpty(addList)) {
|
||||||
|
return this.saveBatch(addList);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public boolean saveAndRemove(List<BusinessAttachmentAddDTO> params, BusinessAttachmentDeleteDTO deleteParam) {
|
||||||
|
boolean hasBizIds = deleteParam != null && deleteParam.isDelete() && CollectionUtil.isNotEmpty(deleteParam.getBizIds());
|
||||||
|
if (hasBizIds) {
|
||||||
|
// bizIds不为空,先删除
|
||||||
|
this.removeByBizIdsAndCodes(deleteParam.getBizIds(), deleteParam.getBizCodes());
|
||||||
|
}
|
||||||
|
if (CollectionUtil.isEmpty(params)) {
|
||||||
|
log.warn("保存业务附件,参数为空");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!hasBizIds && (deleteParam == null || deleteParam.isDelete())) {
|
||||||
|
// bizIds为空,从参数提取bizIds,再删除
|
||||||
|
// 删除参数为空,默认删除,删除参数中delete为true默认删除,false不删除
|
||||||
|
List<Long> bizIds = params.stream()
|
||||||
|
.map(BusinessAttachmentAddDTO::getBizId)
|
||||||
|
.distinct()
|
||||||
|
.toList();
|
||||||
|
this.removeByBizIds(bizIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BusinessAttachment> businessAttachments = convert.dtos2entities(params);
|
||||||
|
|
||||||
|
// 按照业务id分组排序
|
||||||
|
Map<Long, List<BusinessAttachment>> bizIdAttachmentsMap = businessAttachments.stream()
|
||||||
|
.collect(Collectors.groupingBy(BusinessAttachment::getBizId));
|
||||||
|
String tenantId = AuthUtil.getTenantId();
|
||||||
|
for (Map.Entry<Long, List<BusinessAttachment>> entry : bizIdAttachmentsMap.entrySet()) {
|
||||||
|
int i = 1;
|
||||||
|
for (BusinessAttachment businessAttachment : entry.getValue()) {
|
||||||
|
businessAttachment.setId(IdWorker.getId());
|
||||||
|
// 处理排序
|
||||||
|
businessAttachment.setSort(i++);
|
||||||
|
if (StringUtil.isBlank(tenantId)) {
|
||||||
|
businessAttachment.setTenantId(BladeConstant.ADMIN_TENANT_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.saveBatch(businessAttachments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public boolean removeByBizIds(List<Long> bizIds) {
|
||||||
|
return this.removeByBizIdsAndCodes(bizIds, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BusinessAttachmentVO> queryList(BusinessAttachmentQueryDTO param) {
|
||||||
|
return baseMapper.queryList(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除
|
||||||
|
* @param bizIds 业务id列表,为空,不删除
|
||||||
|
* @param bizCodes 业务编码列表,为空,删除所有
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean removeByBizIdsAndCodes(List<Long> bizIds, List<String> bizCodes) {
|
||||||
|
if (CollectionUtil.isEmpty(bizIds)) {
|
||||||
|
log.warn("删除附件,参数为空");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
List<Long> ids = this.list(Wrappers.<BusinessAttachment>lambdaQuery()
|
||||||
|
.in(BusinessAttachment::getBizId, bizIds)
|
||||||
|
// 业务编码列表不为空,添加业务编码查询条件
|
||||||
|
.in(CollectionUtil.isNotEmpty(bizCodes), BusinessAttachment::getBizCode, bizCodes)
|
||||||
|
).stream()
|
||||||
|
.map(BusinessAttachment::getId)
|
||||||
|
.toList();
|
||||||
|
if (CollectionUtil.isNotEmpty(ids)) {
|
||||||
|
return this.removeBatchByIds(ids);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package org.springblade.file.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springblade.core.tool.utils.CollectionUtil;
|
||||||
|
import org.springblade.file.exception.UnzipFailException;
|
||||||
|
import org.springblade.file.listener.UnzipCompletedEvent;
|
||||||
|
import org.springblade.file.listener.UnzipFailEvent;
|
||||||
|
import org.springblade.file.mapper.BusinessUnzipDetailMapper;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessUnzipDetail;
|
||||||
|
import org.springblade.file.pojo.vo.FileVO;
|
||||||
|
import org.springblade.file.service.IAttachmentService;
|
||||||
|
import org.springblade.file.service.IBusinessUnzipDetailService;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/30
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class BusinessUnzipDetailServiceImpl extends ServiceImpl<BusinessUnzipDetailMapper, BusinessUnzipDetail> implements IBusinessUnzipDetailService {
|
||||||
|
|
||||||
|
private final IAttachmentService attachmentService;
|
||||||
|
private final ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Async
|
||||||
|
@Override
|
||||||
|
public void unzipAndSaveAsync(Long unzipTaskId, FileVO file) {
|
||||||
|
log.info("解压文件并上传开始 unzipTaskId: {} file: {}", unzipTaskId, JSON.toJSONString(file));
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
// 1. 上传文件并解压
|
||||||
|
List<Attachment> attachments = attachmentService.unzipAndUpload(file);
|
||||||
|
if (CollectionUtil.isEmpty(attachments)) {
|
||||||
|
log.warn("上传解压文件为空 unzipTaskId:{} objectKey:{}", unzipTaskId, file.getObjectKey());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 2. 保存压缩文件和解压文件关系
|
||||||
|
List<BusinessUnzipDetail> addParams = attachments.stream()
|
||||||
|
.map(attachment -> {
|
||||||
|
BusinessUnzipDetail addParam = new BusinessUnzipDetail();
|
||||||
|
addParam.setBusinessUnzipTaskId(unzipTaskId);
|
||||||
|
addParam.setAttachmentId(attachment.getId());
|
||||||
|
return addParam;
|
||||||
|
}).toList();
|
||||||
|
if (CollectionUtil.isNotEmpty(addParams)) {
|
||||||
|
this.saveBatch(addParams);
|
||||||
|
}
|
||||||
|
// 3. 发布解压完成事件
|
||||||
|
applicationContext.publishEvent(new UnzipCompletedEvent(unzipTaskId));
|
||||||
|
} catch (UnzipFailException e) {
|
||||||
|
log.error("解压文件异常", e);
|
||||||
|
// 发布解压失败事件
|
||||||
|
applicationContext.publishEvent(new UnzipFailEvent(unzipTaskId));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解压文件并上传异常", e);
|
||||||
|
} finally {
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
log.info("解压文件并上传 完成 unzipTaskId: {} objectKey: {} 耗时:{}", unzipTaskId, file.getObjectKey(), end - start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
package org.springblade.file.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springblade.common.constant.DictTypeEnum;
|
||||||
|
import org.springblade.core.log.exception.ServiceException;
|
||||||
|
import org.springblade.core.log.utils.AssertUtils;
|
||||||
|
import org.springblade.core.tool.utils.CollectionUtil;
|
||||||
|
import org.springblade.core.tool.utils.StringUtil;
|
||||||
|
import org.springblade.file.convert.FileTaskConvert;
|
||||||
|
import org.springblade.file.listener.UnzipStartEvent;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessUnzipTaskAddDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessUnzipTaskQueryDTO;
|
||||||
|
import org.springblade.file.pojo.dto.BusinessUnzipTaskUpdateDTO;
|
||||||
|
import org.springblade.file.pojo.entity.Attachment;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessUnzipTask;
|
||||||
|
import org.springblade.file.mapper.BusinessUnzipTaskMapper;
|
||||||
|
import org.springblade.file.pojo.entity.FileTask;
|
||||||
|
import org.springblade.file.pojo.enums.FileTaskStatus;
|
||||||
|
import org.springblade.file.pojo.enums.UnzipTask;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessUnzipDetailListVO;
|
||||||
|
import org.springblade.file.pojo.vo.BusinessUnzipTaskListVO;
|
||||||
|
import org.springblade.file.pojo.vo.FileVO;
|
||||||
|
import org.springblade.file.service.IAttachmentService;
|
||||||
|
import org.springblade.file.service.IBusinessUnzipDetailService;
|
||||||
|
import org.springblade.file.service.IBusinessUnzipTaskService;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.springblade.file.service.IFileTaskService;
|
||||||
|
import org.springblade.system.cache.DictCache;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 业务解压任务表 服务实现类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2024-10-28
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class BusinessUnzipTaskServiceImpl extends ServiceImpl<BusinessUnzipTaskMapper, BusinessUnzipTask> implements IBusinessUnzipTaskService {
|
||||||
|
|
||||||
|
private final FileTaskConvert convert;
|
||||||
|
private final IFileTaskService fileTaskService;
|
||||||
|
private final IBusinessUnzipDetailService detailService;
|
||||||
|
private final IAttachmentService attachmentService;
|
||||||
|
private final ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public boolean save(BusinessUnzipTaskAddDTO param) {
|
||||||
|
BusinessUnzipTask addParam = convert.dto2entity(param);
|
||||||
|
String status = getStatus(param.getRelateType(), param.getRelateId());
|
||||||
|
addParam.setStatus(status);
|
||||||
|
boolean result = this.save(addParam);
|
||||||
|
if (result && UnzipTask.Status.UPLOADED.getCode().equals(status)) {
|
||||||
|
// 解压任务状态是上传完成,发布解压开始事件
|
||||||
|
applicationContext.publishEvent(new UnzipStartEvent(addParam));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjectKey(BusinessUnzipTask task) {
|
||||||
|
return this.getFile(task).getObjectKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVO getFile(BusinessUnzipTask task) {
|
||||||
|
AssertUtils.notNull(task, "文件任务不存在");
|
||||||
|
String relateType = task.getRelateType();
|
||||||
|
AssertUtils.notBlank(relateType, "文件任务关联类型不能为空");
|
||||||
|
Long relateId = task.getRelateId();
|
||||||
|
AssertUtils.notNull(relateId, "文件任务关联id不能为空");
|
||||||
|
if (UnzipTask.RelateType.FILE_TASK.getCode().equals(relateType)) {
|
||||||
|
// 文件任务关联类型
|
||||||
|
FileTask fileTask = fileTaskService.getById(relateId);
|
||||||
|
AssertUtils.notNull(fileTask, "文件任务不存在");
|
||||||
|
return new FileVO(fileTask.getObjectKey(), fileTask.getMd5());
|
||||||
|
}
|
||||||
|
if (UnzipTask.RelateType.ATTACHMENT.getCode().equals(relateType)) {
|
||||||
|
// 附件关联类型
|
||||||
|
Attachment attachment = attachmentService.getById(relateId);
|
||||||
|
AssertUtils.notNull(attachment, "附件不存在");
|
||||||
|
// 附件暂时没有md5
|
||||||
|
return new FileVO(attachment.getObjectKey(), null);
|
||||||
|
}
|
||||||
|
throw new ServiceException("文件任务关联类型错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPage<BusinessUnzipTaskListVO> selectPage(IPage<BusinessUnzipTask> page, BusinessUnzipTaskQueryDTO param) {
|
||||||
|
List<BusinessUnzipTaskListVO> list = baseMapper.selectTaskList(page, param);
|
||||||
|
if (CollectionUtil.isNotEmpty(list)) {
|
||||||
|
// 处理状态枚举值名称
|
||||||
|
list.forEach(vo -> {
|
||||||
|
String status = vo.getStatus();
|
||||||
|
if (StringUtil.isNotBlank(status)) {
|
||||||
|
vo.setStatusStr(DictCache.getValue(DictTypeEnum.FILE_TASK_STATUS.getType(), vo.getStatus()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
IPage<BusinessUnzipTaskListVO> newPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
|
||||||
|
return newPage.setRecords(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public boolean updateReupload(BusinessUnzipTaskUpdateDTO param) {
|
||||||
|
log.info("修改业务解压任务重新上传参数:{}", JSON.toJSONString(param));
|
||||||
|
if (param == null || (param.getId() == null && param.getBizId() == null)) {
|
||||||
|
throw new ServiceException("参数不能为空");
|
||||||
|
}
|
||||||
|
// 校验业务解压任务
|
||||||
|
BusinessUnzipTask unzipTask = param.getId() != null ? this.getById(param.getId()) : this.getOne(Wrappers.<BusinessUnzipTask>lambdaQuery()
|
||||||
|
.eq(BusinessUnzipTask::getBizId, param.getBizId())
|
||||||
|
.last("limit 1")
|
||||||
|
);
|
||||||
|
AssertUtils.notNull(unzipTask, "业务任务不存在");
|
||||||
|
// 上传中或解压失败才可以重新上传
|
||||||
|
AssertUtils.isTrue(UnzipTask.Status.UPLOADING.getCode().equals(unzipTask.getStatus())
|
||||||
|
|| UnzipTask.Status.UNZIP_FAIL.getCode().equals(unzipTask.getStatus()), "只有上传中或解压失败的任务才可以重新上传");
|
||||||
|
|
||||||
|
if (UnzipTask.Status.UPLOADING.getCode().equals(unzipTask.getStatus())) {
|
||||||
|
// 上传中的才需要取消上传任务,解压失败的无需取消
|
||||||
|
try {
|
||||||
|
// 取消文件任务
|
||||||
|
fileTaskService.cancelBatchByIds(Lists.newArrayList(unzipTask.getRelateId()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("取消上传异常", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新业务解压任务
|
||||||
|
BusinessUnzipTask updateParam = new BusinessUnzipTask();
|
||||||
|
updateParam.setId(unzipTask.getId());
|
||||||
|
updateParam.setRelateId(param.getRelateId());
|
||||||
|
String status = getStatus(param.getRelateType(), param.getRelateId());
|
||||||
|
updateParam.setStatus(status);
|
||||||
|
boolean result = this.updateById(updateParam);
|
||||||
|
if (result && UnzipTask.Status.UPLOADED.getCode().equals(status)) {
|
||||||
|
// 重新查询,防止解压开始事件中查询时事务未提交查询不到最新的数据
|
||||||
|
unzipTask = this.getById(unzipTask.getId());
|
||||||
|
// 解压任务状态是上传完成,发布解压开始事件
|
||||||
|
applicationContext.publishEvent(new UnzipStartEvent(unzipTask));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public boolean cancelBusinessUnzipTask(Long bizId, boolean cancelFile) {
|
||||||
|
List<BusinessUnzipTask> list = this.list(Wrappers.<BusinessUnzipTask>lambdaQuery()
|
||||||
|
.eq(BusinessUnzipTask::getBizId, bizId)
|
||||||
|
);
|
||||||
|
if (CollectionUtil.isEmpty(list)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (cancelFile) {
|
||||||
|
boolean hasUpload = list.stream()
|
||||||
|
.anyMatch(task -> !UnzipTask.Status.UPLOADING.getCode().equals(task.getStatus()));
|
||||||
|
AssertUtils.isFalse(hasUpload, "当前任务已上传完成,不能取消");
|
||||||
|
// 取消文件任务
|
||||||
|
List<Long> taskIds = list.stream()
|
||||||
|
.filter(task -> UnzipTask.RelateType.FILE_TASK.getCode().equals(task.getRelateType()))
|
||||||
|
.map(BusinessUnzipTask::getRelateId)
|
||||||
|
.toList();
|
||||||
|
fileTaskService.cancelBatchByIds(taskIds);
|
||||||
|
}
|
||||||
|
// 删除业务文件解压任务
|
||||||
|
List<Long> unzipTaskIds = list.stream()
|
||||||
|
.map(BusinessUnzipTask::getId)
|
||||||
|
.toList();
|
||||||
|
this.removeBatchByIds(unzipTaskIds);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BusinessUnzipDetailListVO> queryBusinessUnzipDetail(Long bizId) {
|
||||||
|
return baseMapper.queryBusinessUnzipDetail(bizId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BusinessUnzipTaskListVO> getBusinessUnzipTasksByBizIds(List<Long> bizIds) {
|
||||||
|
if (CollectionUtil.isEmpty(bizIds)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
BusinessUnzipTaskQueryDTO param = new BusinessUnzipTaskQueryDTO();
|
||||||
|
param.setBizIds(bizIds);
|
||||||
|
return baseMapper.selectTaskList(null, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取解压任务状态
|
||||||
|
* @param relateType 关联类型
|
||||||
|
* @param relateId 关联id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getStatus(String relateType, Long relateId) {
|
||||||
|
if (UnzipTask.RelateType.ATTACHMENT.getCode().equals(relateType)) {
|
||||||
|
// 关联类型是附件,状态直接就是上传完成
|
||||||
|
return UnzipTask.Status.UPLOADED.getCode();
|
||||||
|
}
|
||||||
|
if (UnzipTask.RelateType.FILE_TASK.getCode().equals(relateType)) {
|
||||||
|
// 关联类型是文件任务,查询文件任务状态
|
||||||
|
FileTask fileTask = fileTaskService.getById(relateId);
|
||||||
|
AssertUtils.notNull(fileTask, "文件任务不存在");
|
||||||
|
if (FileTaskStatus.COMPLETED.getCode().equals(fileTask.getStatus())) {
|
||||||
|
// 文件任务上传完成,解压任务设置为上传完成
|
||||||
|
return UnzipTask.Status.UPLOADED.getCode();
|
||||||
|
}
|
||||||
|
// 否则解压任务设置为上传中状态
|
||||||
|
return UnzipTask.Status.UPLOADING.getCode();
|
||||||
|
}
|
||||||
|
throw new ServiceException("关联类型错误");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package org.springblade.file.service.impl;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springblade.core.tool.utils.StringUtil;
|
||||||
|
import org.springblade.file.config.ObsProperties;
|
||||||
|
import org.springblade.file.exception.UnzipFailException;
|
||||||
|
import org.springblade.file.pojo.vo.FileHandleVO;
|
||||||
|
import org.springblade.file.pojo.vo.FileVO;
|
||||||
|
import org.springblade.file.service.IFileHandleService;
|
||||||
|
import org.springblade.file.service.IFileService;
|
||||||
|
import org.springblade.file.util.UnzipUtil;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/22
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class FileHandleServiceImpl implements IFileHandleService {
|
||||||
|
|
||||||
|
private final IFileService fileService;
|
||||||
|
private final ObsProperties obsProperties;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileHandleVO downloadAndUnzip(FileVO file) {
|
||||||
|
File downloadDir = new File(obsProperties.getTmpDownloadDir());
|
||||||
|
if (!downloadDir.exists()) {
|
||||||
|
downloadDir.mkdirs();
|
||||||
|
}
|
||||||
|
File downloadFile = new File(downloadDir, file.getObjectKey());
|
||||||
|
String downloadFilePath = downloadFile.getAbsolutePath();
|
||||||
|
File unzipDir = null;
|
||||||
|
long unzipStart = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
// 下载文件
|
||||||
|
downloadFile(file, downloadFile, downloadFilePath);
|
||||||
|
// 2. 解压文件目录
|
||||||
|
unzipDir = new File(obsProperties.getTmpUnzipDir(), file.getObjectKey());
|
||||||
|
if (!unzipDir.exists()) {
|
||||||
|
unzipDir.mkdirs();
|
||||||
|
}
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
List<File> files = UnzipUtil.unzipOrUnrar(downloadFilePath, unzipDir);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
log.info("文件:{} 解压完成 共{}个 耗时:{}", file.getObjectKey(), files.size(), end - start);
|
||||||
|
FileHandleVO fileHandleVO = new FileHandleVO();
|
||||||
|
fileHandleVO.setDownloadFile(downloadFile);
|
||||||
|
fileHandleVO.setUnzippedDir(unzipDir);
|
||||||
|
fileHandleVO.setUnzippedFiles(files);
|
||||||
|
return fileHandleVO;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文件解压失败异常", e);
|
||||||
|
throw new UnzipFailException(e, unzipDir);
|
||||||
|
} finally {
|
||||||
|
long unzipEnd = System.currentTimeMillis();
|
||||||
|
log.info("文件:{} 下载并解压完成 耗时:{}", file.getObjectKey(), unzipEnd - unzipStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @param downloadFile
|
||||||
|
* @param downloadFilePath
|
||||||
|
*/
|
||||||
|
private void downloadFile(FileVO file, File downloadFile, String downloadFilePath) {
|
||||||
|
if (downloadFile.exists() && file.getMd5() != null) {
|
||||||
|
// 下载文件存在且md5不为空,可能是重新解压
|
||||||
|
String fileMd5 = fileService.getFileMd5(downloadFile);
|
||||||
|
if (StringUtil.equals(fileMd5, file.getMd5())) {
|
||||||
|
log.info("文件存在且md5一致,无需重新下载 文件路径:{}", downloadFile.getAbsolutePath());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long downloadStart = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
// 1. 下载文件
|
||||||
|
fileService.downloadFile(file.getObjectKey(), downloadFilePath);
|
||||||
|
} finally {
|
||||||
|
long downloadEnd = System.currentTimeMillis();
|
||||||
|
log.info("文件:{} 下载完成 耗时:{}", file.getObjectKey(), downloadEnd - downloadStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.file.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springblade.file.mapper.FileTaskPartMapper;
|
||||||
|
import org.springblade.file.pojo.entity.FileTaskPart;
|
||||||
|
import org.springblade.file.service.IFileTaskPartService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务实现类
|
||||||
|
*
|
||||||
|
* @author zhaowei
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class FileTaskPartServiceImpl extends ServiceImpl<FileTaskPartMapper, FileTaskPart> implements IFileTaskPartService {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,360 @@
|
|||||||
|
/**
|
||||||
|
* BladeX Commercial License Agreement
|
||||||
|
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||||
|
* <p>
|
||||||
|
* Use of this software is governed by the Commercial License Agreement
|
||||||
|
* obtained after purchasing a license from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 1. This software is for development use only under a valid license
|
||||||
|
* from BladeX.
|
||||||
|
* <p>
|
||||||
|
* 2. Redistribution of this software's source code to any third party
|
||||||
|
* without a commercial license is strictly prohibited.
|
||||||
|
* <p>
|
||||||
|
* 3. Licensees may copyright their own code but cannot use segments
|
||||||
|
* from this software for such purposes. Copyright of this software
|
||||||
|
* remains with BladeX.
|
||||||
|
* <p>
|
||||||
|
* Using this software signifies agreement to this License, and the software
|
||||||
|
* must not be used for illegal purposes.
|
||||||
|
* <p>
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||||
|
* not liable for any claims arising from secondary or illegal development.
|
||||||
|
* <p>
|
||||||
|
* Author: Chill Zhuang (bladejava@qq.com)
|
||||||
|
*/
|
||||||
|
package org.springblade.file.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springblade.core.log.exception.ServiceException;
|
||||||
|
import org.springblade.core.log.utils.AssertUtils;
|
||||||
|
import org.springblade.core.tool.utils.CollectionUtil;
|
||||||
|
import org.springblade.core.tool.utils.StringUtil;
|
||||||
|
import org.springblade.file.config.ObsProperties;
|
||||||
|
import org.springblade.file.convert.FileTaskConvert;
|
||||||
|
import org.springblade.file.listener.FileUploadedEvent;
|
||||||
|
import org.springblade.file.mapper.BusinessUnzipTaskMapper;
|
||||||
|
import org.springblade.file.mapper.FileTaskMapper;
|
||||||
|
import org.springblade.file.pojo.dto.FileTaskCreateDTO;
|
||||||
|
import org.springblade.file.pojo.dto.FileTaskUpdateDTO;
|
||||||
|
import org.springblade.file.pojo.entity.BusinessUnzipTask;
|
||||||
|
import org.springblade.file.pojo.entity.FileTask;
|
||||||
|
import org.springblade.file.pojo.entity.FileTaskPart;
|
||||||
|
import org.springblade.file.pojo.enums.FileTaskStatus;
|
||||||
|
import org.springblade.file.pojo.vo.FileTaskUpdateVO;
|
||||||
|
import org.springblade.file.pojo.vo.PartEtagVO;
|
||||||
|
import org.springblade.file.service.IFileService;
|
||||||
|
import org.springblade.file.service.IFileTaskPartService;
|
||||||
|
import org.springblade.file.service.IFileTaskService;
|
||||||
|
import org.springblade.file.util.ObjectKeyUtils;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务实现类
|
||||||
|
*
|
||||||
|
* @author zhaowei
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class FileTaskServiceImpl extends ServiceImpl<FileTaskMapper, FileTask> implements IFileTaskService {
|
||||||
|
|
||||||
|
private final FileTaskConvert convert;
|
||||||
|
private final IFileTaskPartService partService;
|
||||||
|
private final IFileService fileService;
|
||||||
|
private final BusinessUnzipTaskMapper unzipTaskMapper;
|
||||||
|
private final ObsProperties obsProperties;
|
||||||
|
private final ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileTaskUpdateVO queryFileTask(Long id, String md5) {
|
||||||
|
if (id == null && StringUtil.isBlank(md5)) {
|
||||||
|
throw new ServiceException("id和md5不能都为空");
|
||||||
|
}
|
||||||
|
// 根据md5按创建时间倒序取一条
|
||||||
|
FileTask fileTask = this.getOne(Wrappers.<FileTask>lambdaQuery()
|
||||||
|
.eq(id != null, FileTask::getId, id)
|
||||||
|
.eq(StringUtil.isNotBlank(md5), FileTask::getMd5, md5)
|
||||||
|
.orderByDesc(FileTask::getCreateTime)
|
||||||
|
.last("limit 1")
|
||||||
|
);
|
||||||
|
if (fileTask == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getFileTaskUpdateVO(fileTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public Long createFileTask(FileTaskCreateDTO param) {
|
||||||
|
if (!param.isForce()) {
|
||||||
|
// 不是强制创建新任务,文件任务存在就报错
|
||||||
|
FileTask fileTask = this.getOne(Wrappers.<FileTask>lambdaQuery()
|
||||||
|
.eq(FileTask::getMd5, param.getMd5())
|
||||||
|
.last("limit 1")
|
||||||
|
);
|
||||||
|
AssertUtils.isNull(fileTask, "文件任务已存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 初始化上传任务
|
||||||
|
String fileName = param.getAttachmentName();
|
||||||
|
String fileSuffix = fileName.substring(fileName.lastIndexOf("."));
|
||||||
|
String objectKey = ObjectKeyUtils.generateObjectKey(obsProperties.getZipUploadDir(), fileName);
|
||||||
|
String uploadId = fileService.initiateMultipartUpload(objectKey);
|
||||||
|
|
||||||
|
// 2. 保存文件任务
|
||||||
|
FileTask addParam = convert.dto2entity(param);
|
||||||
|
addParam.setId(IdWorker.getId());
|
||||||
|
addParam.setObjectKey(objectKey);
|
||||||
|
addParam.setSuffix(fileSuffix);
|
||||||
|
// 当前位置
|
||||||
|
addParam.setCurrentIndex(0);
|
||||||
|
addParam.setUploadId(uploadId);
|
||||||
|
// 正在上传
|
||||||
|
addParam.setStatus(FileTaskStatus.UPLOADING.getCode());
|
||||||
|
this.save(addParam);
|
||||||
|
|
||||||
|
return addParam.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public FileTaskUpdateVO updateFileTask(FileTaskUpdateDTO param) {
|
||||||
|
// 校验文件任务
|
||||||
|
FileTask fileTask = this.getById(param.getId());
|
||||||
|
AssertUtils.notNull(fileTask, "文件任务不存在");
|
||||||
|
AssertUtils.isTrue(!FileTaskStatus.COMPLETED.getCode().equals(fileTask.getStatus()), "文件任务已完成");
|
||||||
|
|
||||||
|
// 1. 新增分段
|
||||||
|
addPart(param, fileTask);
|
||||||
|
|
||||||
|
// 是否最后一段
|
||||||
|
boolean isLast = fileTask.getChunkTotal().equals(param.getPartNumber());
|
||||||
|
// 2. 更新文件任务
|
||||||
|
boolean update = updateTask(param, isLast);
|
||||||
|
// 3. 处理上传结束
|
||||||
|
handleFinished(isLast, update, fileTask);
|
||||||
|
return this.getUpdateVO(param.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理结束
|
||||||
|
* @param isLast
|
||||||
|
* @param update
|
||||||
|
* @param fileTask
|
||||||
|
*/
|
||||||
|
private void handleFinished(boolean isLast, boolean update, FileTask fileTask) {
|
||||||
|
if (isLast && update) {
|
||||||
|
// 最后一段并且更新成功,合并文件
|
||||||
|
List<FileTaskPart> parts = partService.list(Wrappers.<FileTaskPart>lambdaQuery()
|
||||||
|
.eq(FileTaskPart::getFileTaskId, fileTask.getId())
|
||||||
|
.orderByAsc(FileTaskPart::getPartNumber)
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 按分段号去重,相同分段号取第一个,如果分段号相同,etag不同,报错
|
||||||
|
Map<Integer, FileTaskPart> numberTag = parts.stream()
|
||||||
|
.collect(Collectors.toMap(FileTaskPart::getPartNumber, Function.identity(), (a, b) -> {
|
||||||
|
if (StringUtil.equals(a.getEtag(), b.getEtag())) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
log.error("etag不一致 id1:{} id2:{} etag1:{} etag2:{}", a.getId(), b.getId(), a.getEtag(), b.getEtag());
|
||||||
|
throw new ServiceException("etag不一致");
|
||||||
|
}));
|
||||||
|
// 获取要保留的分段id
|
||||||
|
List<Long> partId = numberTag.values().stream()
|
||||||
|
.map(FileTaskPart::getId)
|
||||||
|
.toList();
|
||||||
|
// 去重
|
||||||
|
parts = parts.stream()
|
||||||
|
.filter(e -> partId.contains(e.getId()))
|
||||||
|
.toList();
|
||||||
|
List<PartEtagVO> partEtags = parts.stream()
|
||||||
|
.map(convert::entity2vo)
|
||||||
|
.toList();
|
||||||
|
// 3. 合并文件
|
||||||
|
fileService.completeMultipartUpload(fileTask.getObjectKey(), fileTask.getUploadId(), partEtags);
|
||||||
|
// 4. 删除文件任务分段
|
||||||
|
List<Long> partIds = parts.stream()
|
||||||
|
.map(FileTaskPart::getId)
|
||||||
|
.toList();
|
||||||
|
partService.removeByIds(partIds);
|
||||||
|
// 5. 发布上传完成事件
|
||||||
|
applicationContext.publishEvent(new FileUploadedEvent(fileTask.getId()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文件分段上传合并文件异常", e);
|
||||||
|
log.error("文件任务id:{} objectKey:{}", fileTask.getId(), fileTask.getObjectKey());
|
||||||
|
// 更新文件任务状态为失败
|
||||||
|
FileTask updateParam = new FileTask();
|
||||||
|
updateParam.setId(fileTask.getId());
|
||||||
|
updateParam.setStatus(FileTaskStatus.FAILED.getCode());
|
||||||
|
this.updateById(updateParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增分段
|
||||||
|
* @param param
|
||||||
|
* @param fileTask
|
||||||
|
*/
|
||||||
|
private void addPart(FileTaskUpdateDTO param, FileTask fileTask) {
|
||||||
|
// 校验分段
|
||||||
|
FileTaskPart part = partService.getOne(Wrappers.<FileTaskPart>lambdaQuery()
|
||||||
|
.eq(FileTaskPart::getFileTaskId, fileTask.getId())
|
||||||
|
.eq(FileTaskPart::getPartNumber, param.getPartNumber())
|
||||||
|
.last("limit 1")
|
||||||
|
);
|
||||||
|
if (part != null) {
|
||||||
|
// 分段存在
|
||||||
|
if (StringUtil.equals(part.getEtag(), param.getEtag())) {
|
||||||
|
// 且etag和当前的etag相同,不做任何处理
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// etag和当前的etag不同,报错
|
||||||
|
throw new ServiceException("当前分段已存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增分段
|
||||||
|
FileTaskPart addParam = new FileTaskPart();
|
||||||
|
addParam.setId(IdWorker.getId());
|
||||||
|
addParam.setFileTaskId(fileTask.getId());
|
||||||
|
addParam.setPartNumber(param.getPartNumber());
|
||||||
|
addParam.setEtag(param.getEtag());
|
||||||
|
partService.save(addParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUploadUrl(Long id, Integer partNumber) {
|
||||||
|
FileTask fileTask = this.getById(id);
|
||||||
|
AssertUtils.notNull(fileTask, "文件任务不存在");
|
||||||
|
AssertUtils.isTrue(!FileTaskStatus.COMPLETED.getCode().equals(fileTask.getStatus()), "文件任务已完成");
|
||||||
|
return fileService.getUploadPartUrl(fileTask.getObjectKey(), fileTask.getUploadId(), partNumber, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public void cancelBatchByIds(List<Long> taskIds) {
|
||||||
|
// 查询任务
|
||||||
|
List<FileTask> fileTasks = this.listByIds(taskIds);
|
||||||
|
if (CollectionUtil.isEmpty(fileTasks)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 校验状态
|
||||||
|
fileTasks.forEach(task -> AssertUtils.isFalse(FileTaskStatus.COMPLETED.getCode().equals(task.getStatus()), "文件任务已上传完成"));
|
||||||
|
// 调用obs取消上传任务
|
||||||
|
try {
|
||||||
|
for (FileTask fileTask : fileTasks) {
|
||||||
|
fileService.cancelMultipartUpload(fileTask.getObjectKey(), fileTask.getUploadId());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("调用obs取消文件上传任务异常", e);
|
||||||
|
throw new ServiceException("调用obs取消文件上传任务异常");
|
||||||
|
}
|
||||||
|
// 删除上传任务
|
||||||
|
this.removeBatchByIds(taskIds);
|
||||||
|
// 删除文件任务分片
|
||||||
|
List<FileTaskPart> list = partService.list(Wrappers.<FileTaskPart>lambdaQuery()
|
||||||
|
.in(FileTaskPart::getFileTaskId, taskIds)
|
||||||
|
);
|
||||||
|
if (CollectionUtil.isNotEmpty(list)) {
|
||||||
|
List<Long> partIds = list.stream()
|
||||||
|
.map(FileTaskPart::getId)
|
||||||
|
.toList();
|
||||||
|
partService.removeByIds(partIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileTaskUpdateVO updateFailed(Long id) {
|
||||||
|
// 校验文件任务
|
||||||
|
FileTask fileTask = this.getById(id);
|
||||||
|
AssertUtils.notNull(fileTask, "文件任务不存在");
|
||||||
|
AssertUtils.isTrue(!FileTaskStatus.COMPLETED.getCode().equals(fileTask.getStatus()), "文件任务已完成");
|
||||||
|
// 更新文件任务状态为失败
|
||||||
|
FileTask updateParam = new FileTask();
|
||||||
|
updateParam.setId(id);
|
||||||
|
updateParam.setStatus(FileTaskStatus.FAILED.getCode());
|
||||||
|
this.updateById(updateParam);
|
||||||
|
return this.getUpdateVO(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updatePaused(List<Long> ids) {
|
||||||
|
if (CollectionUtil.isEmpty(ids)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FileTask updateParam = new FileTask();
|
||||||
|
// 修改状态为已暂停
|
||||||
|
updateParam.setStatus(FileTaskStatus.PAUSED.getCode());
|
||||||
|
return this.update(updateParam, Wrappers.<FileTask>lambdaUpdate()
|
||||||
|
.in(FileTask::getId, ids)
|
||||||
|
// 只更新正在上传状态的
|
||||||
|
.eq(FileTask::getStatus, FileTaskStatus.UPLOADING.getCode())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询文件任务
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private FileTaskUpdateVO getUpdateVO(Long id) {
|
||||||
|
FileTask fileTask = this.getById(id);
|
||||||
|
return getFileTaskUpdateVO(fileTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询文件任务
|
||||||
|
* @param fileTask
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private FileTaskUpdateVO getFileTaskUpdateVO(FileTask fileTask) {
|
||||||
|
if (fileTask == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
FileTaskUpdateVO updateVO = convert.entity2updateVo(fileTask);
|
||||||
|
BusinessUnzipTask businessUnzipTask = unzipTaskMapper.selectOne(Wrappers.<BusinessUnzipTask>lambdaQuery()
|
||||||
|
.eq(BusinessUnzipTask::getRelateId, fileTask.getId())
|
||||||
|
.last("limit 1")
|
||||||
|
);
|
||||||
|
if (businessUnzipTask != null && businessUnzipTask.getDocCode() != null) {
|
||||||
|
updateVO.setDocCode(businessUnzipTask.getDocCode());
|
||||||
|
}
|
||||||
|
return updateVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新任务
|
||||||
|
*
|
||||||
|
* @param param
|
||||||
|
* @param isLast 是否最后一段
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean updateTask(FileTaskUpdateDTO param, boolean isLast) {
|
||||||
|
FileTask updateParam = new FileTask();
|
||||||
|
updateParam.setCurrentIndex(param.getPartNumber());
|
||||||
|
if (isLast) {
|
||||||
|
// 最后一段,修改任务状态为完成
|
||||||
|
updateParam.setStatus(FileTaskStatus.COMPLETED.getCode());
|
||||||
|
} else {
|
||||||
|
// 非最后一段,修改任务状态为上传中
|
||||||
|
updateParam.setStatus(FileTaskStatus.UPLOADING.getCode());
|
||||||
|
}
|
||||||
|
return this.update(updateParam, Wrappers.<FileTask>lambdaUpdate()
|
||||||
|
.eq(FileTask::getId, param.getId())
|
||||||
|
.lt(FileTask::getCurrentIndex, param.getPartNumber())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.springblade.file.service.impl;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springblade.core.log.utils.AssertUtils;
|
||||||
|
import org.springblade.file.convert.OCRConverter;
|
||||||
|
import org.springblade.file.pojo.dto.FileCertificateBatchRecognitionDTO;
|
||||||
|
import org.springblade.file.service.IFileService;
|
||||||
|
import org.springblade.file.service.IOCRConvertService;
|
||||||
|
import org.springblade.thirdparty.ocr.pojo.dto.CertificateBatchRecognitionDTO;
|
||||||
|
import org.springblade.thirdparty.ocr.pojo.vo.TransportCertificateVO;
|
||||||
|
import org.springblade.thirdparty.ocr.service.IOCRService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author bfhuange
|
||||||
|
* @since 2025/3/13
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class OCRConvertServiceImpl implements IOCRConvertService {
|
||||||
|
|
||||||
|
private final IFileService fileService;
|
||||||
|
private final IOCRService ocrService;
|
||||||
|
private final OCRConverter converter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransportCertificateVO recognitionTransportCertificate(FileCertificateBatchRecognitionDTO param) {
|
||||||
|
AssertUtils.notNull(param, "参数不能为空");
|
||||||
|
AssertUtils.notNull(param.getObjectKeys(), "图像obs key不能为空");
|
||||||
|
CertificateBatchRecognitionDTO ocrParam = converter.dto2ocr(param);
|
||||||
|
// 转换文件链接
|
||||||
|
List<String> fileUrls = fileService.getFileUrls(param.getObjectKeys(), null);
|
||||||
|
ocrParam.setUrls(fileUrls);
|
||||||
|
return ocrService.recognitionTransportCertificate(ocrParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,293 @@
|
|||||||
|
package org.springblade.file.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.net.URLEncodeUtil;
|
||||||
|
import com.obs.services.ObsClient;
|
||||||
|
import com.obs.services.exception.ObsException;
|
||||||
|
import com.obs.services.internal.Constants;
|
||||||
|
import com.obs.services.internal.utils.ServiceUtils;
|
||||||
|
import com.obs.services.model.*;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springblade.core.log.exception.ServiceException;
|
||||||
|
import org.springblade.core.tool.utils.CollectionUtil;
|
||||||
|
import org.springblade.core.tool.utils.StringUtil;
|
||||||
|
import org.springblade.file.config.ObsProperties;
|
||||||
|
import org.springblade.file.pojo.vo.PartEtagVO;
|
||||||
|
import org.springblade.file.service.IFileService;
|
||||||
|
import org.springblade.file.service.support.DownloadProgressListener;
|
||||||
|
import org.springblade.file.service.support.UploadProgressListener;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 华为obs对象存储
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/21
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ObsFileServiceImpl implements IFileService {
|
||||||
|
private final ObsProperties properties;
|
||||||
|
private final ObsClient obsClient;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uploadFile(String objectKey, InputStream is) {
|
||||||
|
this.uploadFile(objectKey, null, is, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String uploadTempFile(String objectKey, InputStream is, Integer expires) {
|
||||||
|
// 上传文件
|
||||||
|
this.uploadFile(objectKey, null, is, expires);
|
||||||
|
// 生成下载链接
|
||||||
|
return this.getFileUrl(objectKey, properties.getExpires());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uploadFile(String objectKey, File file) {
|
||||||
|
this.uploadFile(objectKey, file, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String initiateMultipartUpload(String objectKey) {
|
||||||
|
InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest(properties.getBucketName(), objectKey);
|
||||||
|
try {
|
||||||
|
InitiateMultipartUploadResult initiateResult = obsClient.initiateMultipartUpload(initiateRequest);
|
||||||
|
return initiateResult.getUploadId();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("初始化分段上传异常", e);
|
||||||
|
throw new ServiceException("初始化分段上传异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PartEtagVO uploadPart(String objectKey, String uploadId, File file, int partNumber, Long offset, Long partSize) {
|
||||||
|
UploadPartRequest uploadPartRequest = new UploadPartRequest();
|
||||||
|
uploadPartRequest.setBucketName(properties.getBucketName());
|
||||||
|
uploadPartRequest.setObjectKey(objectKey);
|
||||||
|
uploadPartRequest.setUploadId(uploadId);
|
||||||
|
uploadPartRequest.setPartNumber(partNumber);
|
||||||
|
uploadPartRequest.setFile(file);
|
||||||
|
if (offset != null) {
|
||||||
|
uploadPartRequest.setOffset(offset);
|
||||||
|
}
|
||||||
|
if (partSize != null) {
|
||||||
|
uploadPartRequest.setPartSize(partSize);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
UploadPartResult uploadPartResult = obsClient.uploadPart(uploadPartRequest);
|
||||||
|
return new PartEtagVO(uploadPartResult.getEtag(), uploadPartResult.getPartNumber());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("分段上传异常", e);
|
||||||
|
throw new ServiceException("分段上传异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void completeMultipartUpload(String objectKey, String uploadId, List<PartEtagVO> partEtagVOS) {
|
||||||
|
if (CollectionUtil.isEmpty(partEtagVOS)) {
|
||||||
|
log.warn("完成分段上传,要合并的分段列表为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 参数转换
|
||||||
|
List<PartEtag> list = partEtagVOS.stream()
|
||||||
|
.map(partEtagVO -> new PartEtag(partEtagVO.getEtag(), partEtagVO.getPartNumber()))
|
||||||
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
|
CompleteMultipartUploadRequest request =
|
||||||
|
new CompleteMultipartUploadRequest(properties.getBucketName(), objectKey, uploadId, list);
|
||||||
|
try {
|
||||||
|
obsClient.completeMultipartUpload(request);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("完成分段上传异常", e);
|
||||||
|
throw new ServiceException("完成分段上传异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelMultipartUpload(String objectKey, String uploadId) {
|
||||||
|
AbortMultipartUploadRequest request = new AbortMultipartUploadRequest(properties.getBucketName(), objectKey, uploadId);
|
||||||
|
try {
|
||||||
|
obsClient.abortMultipartUpload(request);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("取消分段上传任务异常", e);
|
||||||
|
throw new ServiceException("取消分段上传任务异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFileUrl(String objectKey, Long expires) {
|
||||||
|
return this.getFileUrl(objectKey, null, expires);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFileUrl(String objectKey, String fileName, Long expires) {
|
||||||
|
if (StringUtil.isBlank(objectKey)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 链接失效时间
|
||||||
|
expires = Optional.ofNullable(expires)
|
||||||
|
// 参数为空取配置
|
||||||
|
.orElse(Optional.ofNullable(properties.getExpires())
|
||||||
|
// 配置为空,默认1小时
|
||||||
|
.orElse(Duration.ofHours(1).getSeconds()));
|
||||||
|
TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expires);
|
||||||
|
request.setBucketName(properties.getBucketName());
|
||||||
|
request.setObjectKey(objectKey);
|
||||||
|
request.setRequestDate(new Date());
|
||||||
|
if (StringUtil.isNotBlank(fileName)) {
|
||||||
|
// 文件名不为空,修改响应的文件名
|
||||||
|
Map<String, Object> queryParam = new HashMap<>();
|
||||||
|
String encodeFileName = encode(fileName);
|
||||||
|
queryParam.put(Constants.ObsRequestParams.RESPONSE_CONTENT_DISPOSITION, "attachment;filename*=UTF-8''" + encodeFileName);
|
||||||
|
request.setQueryParams(queryParam);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
TemporarySignatureResponse temporarySignature = obsClient.createTemporarySignature(request);
|
||||||
|
return temporarySignature.getSignedUrl();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取文件链接异常", e);
|
||||||
|
throw new ServiceException("获取文件链接异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编码文件名
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String encode(String fileName) {
|
||||||
|
int index = fileName.lastIndexOf(".");
|
||||||
|
if (index < 0) {
|
||||||
|
return URLEncodeUtil.encode(fileName);
|
||||||
|
}
|
||||||
|
// 文件名
|
||||||
|
String prefix = fileName.substring(0, index);
|
||||||
|
// 后缀
|
||||||
|
String ext = fileName.substring(index);
|
||||||
|
return URLEncodeUtil.encode(prefix) + ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUploadPartUrl(String objectKey, String uploadId, Integer partNumber, Long expires) {
|
||||||
|
TemporarySignatureRequest request = new TemporarySignatureRequest();
|
||||||
|
request.setBucketName(properties.getBucketName());
|
||||||
|
request.setObjectKey(objectKey);
|
||||||
|
request.setRequestDate(new Date());
|
||||||
|
// 链接失效时间
|
||||||
|
expires = Optional.ofNullable(expires)
|
||||||
|
.orElse(properties.getExpires());
|
||||||
|
if (expires != null) {
|
||||||
|
request.setExpires(expires);
|
||||||
|
}
|
||||||
|
request.setMethod(HttpMethodEnum.PUT);
|
||||||
|
request.setHeaders(Map.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE));
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put(Constants.ObsRequestParams.PART_NUMBER, String.valueOf(partNumber));
|
||||||
|
params.put(Constants.ObsRequestParams.UPLOAD_ID, uploadId);
|
||||||
|
request.setQueryParams(params);
|
||||||
|
try {
|
||||||
|
TemporarySignatureResponse temporarySignature = obsClient.createTemporarySignature(request);
|
||||||
|
return temporarySignature.getSignedUrl();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取文件链接异常", e);
|
||||||
|
throw new ServiceException("获取文件链接异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getFileUrls(List<String> objectKeys, Long expires) {
|
||||||
|
if (CollectionUtil.isEmpty(objectKeys)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return objectKeys.stream()
|
||||||
|
.map(objectKey -> this.getFileUrl(objectKey, expires))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void downloadFile(String objectKey, String downloadFile) {
|
||||||
|
DownloadFileRequest request = new DownloadFileRequest(properties.getBucketName(), objectKey);
|
||||||
|
request.setDownloadFile(downloadFile);
|
||||||
|
// 开启断点续传模式
|
||||||
|
request.setEnableCheckpoint(true);
|
||||||
|
Long progressInterval = properties.getDownloadProgressInterval();
|
||||||
|
// 设置下载进度日志
|
||||||
|
request.setProgressListener(new DownloadProgressListener(objectKey, progressInterval));
|
||||||
|
request.setProgressInterval(progressInterval);
|
||||||
|
DownloadFileResult result = null;
|
||||||
|
try {
|
||||||
|
result = obsClient.downloadFile(request);
|
||||||
|
} catch (ObsException e) {
|
||||||
|
log.error("下载文件异常", e);
|
||||||
|
log.error("下载文件异常 objectKey:{} responseCode:{} errorCode:{} errorMessage:{} errorRequestId:{} errorHostId:{}", objectKey, e.getResponseCode(), e.getErrorCode(), e.getErrorMessage(), e.getErrorRequestId(), e.getErrorHostId());
|
||||||
|
throw new ServiceException("下载文件异常");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("下载文件异常", e);
|
||||||
|
throw new ServiceException("下载文件异常");
|
||||||
|
} finally {
|
||||||
|
String etag = Optional.ofNullable(result)
|
||||||
|
.map(DownloadFileResult::getObjectMetadata)
|
||||||
|
.map(ObjectMetadata::getEtag)
|
||||||
|
.orElse(null);
|
||||||
|
log.info("下载文件结束 objectKey:{} etag:{}", objectKey, etag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* @param objectKey
|
||||||
|
* @param file
|
||||||
|
* @param is
|
||||||
|
* @param expires 过期时间,单位天,过期后自动删除
|
||||||
|
*/
|
||||||
|
private void uploadFile(String objectKey, File file, InputStream is, Integer expires) {
|
||||||
|
if (file == null && is == null ) {
|
||||||
|
throw new ServiceException("文件不存在");
|
||||||
|
}
|
||||||
|
PutObjectRequest request = new PutObjectRequest();
|
||||||
|
request.setBucketName(properties.getBucketName());
|
||||||
|
request.setObjectKey(objectKey);
|
||||||
|
if (expires != null) {
|
||||||
|
request.setExpires(expires);
|
||||||
|
}
|
||||||
|
if (is != null) {
|
||||||
|
request.setInput(is);
|
||||||
|
} else {
|
||||||
|
request.setFile(file);
|
||||||
|
// 文件不为空,设置md5
|
||||||
|
String md5 = getFileMd5(file);
|
||||||
|
ObjectMetadata metadata = new ObjectMetadata();
|
||||||
|
metadata.setContentMd5(md5);
|
||||||
|
request.setMetadata(metadata);
|
||||||
|
}
|
||||||
|
Long progressInterval = properties.getUploadProgressInterval();
|
||||||
|
// 设置上传进度日志
|
||||||
|
request.setProgressListener(new UploadProgressListener(objectKey, progressInterval));
|
||||||
|
request.setProgressInterval(progressInterval);
|
||||||
|
try {
|
||||||
|
obsClient.putObject(request);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("上传文件异常", e);
|
||||||
|
throw new ServiceException("上传文件异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFileMd5(File file) {
|
||||||
|
try {
|
||||||
|
return ServiceUtils.toBase64(ServiceUtils.computeMD5Hash(new FileInputStream(file)));
|
||||||
|
} catch (NoSuchAlgorithmException | IOException e) {
|
||||||
|
log.error("获取文件md5异常", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.springblade.file.service.support;
|
||||||
|
|
||||||
|
import com.obs.services.model.ProgressListener;
|
||||||
|
import com.obs.services.model.ProgressStatus;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件下载进度监听器
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/28
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class DownloadProgressListener implements ProgressListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* obs对象名称
|
||||||
|
*/
|
||||||
|
private final String objectKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度间隔,如果新传输的大小不等于进度间隔,说明是结束了
|
||||||
|
*/
|
||||||
|
private final long progressInterval;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void progressChanged(ProgressStatus status) {
|
||||||
|
log.info("文件下载进度 文件名:{} 是否结束:{} 总大小:{} 已下载大小:{} 百分比:{} 下载速度:{}", objectKey, progressInterval != status.getNewlyTransferredBytes(), status.getTotalBytes(), status.getTransferredBytes(), status.getTransferPercentage(), String.format("%.2f", status.getAverageSpeed()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.springblade.file.service.support;
|
||||||
|
|
||||||
|
import com.obs.services.model.ProgressListener;
|
||||||
|
import com.obs.services.model.ProgressStatus;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传进度监听器
|
||||||
|
* @author bfhuange
|
||||||
|
* @date 2024/10/28
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class UploadProgressListener implements ProgressListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* obs对象名称
|
||||||
|
*/
|
||||||
|
private final String objectKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度间隔,如果新传输的大小不等于进度间隔,说明是结束了
|
||||||
|
*/
|
||||||
|
private final long progressInterval;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void progressChanged(ProgressStatus status) {
|
||||||
|
log.info("文件上传进度 文件名:{} 是否结束:{} 已上传大小:{} 上传速度:{}", objectKey, progressInterval != status.getNewlyTransferredBytes(), status.getTransferredBytes(), String.format("%.2f", status.getAverageSpeed()));
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user