add export task
This commit is contained in:
parent
f580d3b962
commit
7d322ffe56
@ -1,9 +1,9 @@
|
|||||||
package com.pudonghot.ambition.crm.service.support;
|
package com.pudonghot.ambition.crm.service.support;
|
||||||
|
|
||||||
|
import lombok.val;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.chyxion.tigon.model.M2;
|
import me.chyxion.tigon.model.M2;
|
||||||
@ -11,14 +11,13 @@ import java.util.function.Consumer;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import me.chyxion.tigon.mybatis.Search;
|
import me.chyxion.tigon.mybatis.Search;
|
||||||
import me.chyxion.tigon.sequence.IdSequence;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import me.chyxion.tigon.mybatis.BaseMapper;
|
import me.chyxion.tigon.mybatis.BaseMapper;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import me.chyxion.tigon.sequence.IdSequence;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.pudonghot.ambition.file.DiskFileApi;
|
import com.pudonghot.ambition.file.DiskFileApi;
|
||||||
import com.pudonghot.ambition.crm.model.FileInfo;
|
|
||||||
import com.pudonghot.ambition.crm.model.Attachment;
|
import com.pudonghot.ambition.crm.model.Attachment;
|
||||||
import com.pudonghot.ambition.crm.model.AttachedImage;
|
import com.pudonghot.ambition.crm.model.AttachedImage;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@ -27,6 +26,7 @@ import com.pudonghot.ambition.crm.mapper.AttachedFileMapper;
|
|||||||
import com.pudonghot.ambition.crm.mapper.AttachedImageMapper;
|
import com.pudonghot.ambition.crm.mapper.AttachedImageMapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import com.pudonghot.ambition.file.request.AmInputStreamUploadReq;
|
||||||
import com.pudonghot.ambition.crm.form.update.AttachmentFormForUpdate;
|
import com.pudonghot.ambition.crm.form.update.AttachmentFormForUpdate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,19 +64,24 @@ public class AttachmentServiceSupport
|
|||||||
final Date now = new Date();
|
final Date now = new Date();
|
||||||
final String fileFolder = fileFolder(ownerId);
|
final String fileFolder = fileFolder(ownerId);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (final MultipartFile file : files) {
|
|
||||||
|
for (val file : files) {
|
||||||
if (!file.isEmpty()) {
|
if (!file.isEmpty()) {
|
||||||
final String originalFilename = file.getOriginalFilename();
|
val originalFilename = file.getOriginalFilename();
|
||||||
try (final InputStream ins = file.getInputStream()) {
|
try (val ins = file.getInputStream()) {
|
||||||
final String fileId = idSeq.get();
|
val fileId = idSeq.get();
|
||||||
final T appFile = constructor.get();
|
val appFile = constructor.get();
|
||||||
final FileInfo fileInfo = fileApi.upload(ins,
|
val req = new AmInputStreamUploadReq();
|
||||||
file.getSize(),
|
req.setInputStream(ins);
|
||||||
fileFolder,
|
req.setContentLength(file.getSize());
|
||||||
fileId,
|
req.setFolder(fileFolder);
|
||||||
file.getContentType(),
|
req.setName(fileId);
|
||||||
FilenameUtils.getExtension(originalFilename),
|
req.setContentType(file.getContentType());
|
||||||
originalFilename);
|
req.setFormat(FilenameUtils.getExtension(originalFilename));
|
||||||
|
req.setDownloadName(originalFilename);
|
||||||
|
|
||||||
|
val fileInfo = fileApi.upload(req);
|
||||||
|
|
||||||
appFile.setId(fileId);
|
appFile.setId(fileId);
|
||||||
appFile.setOwnerId(ownerId);
|
appFile.setOwnerId(ownerId);
|
||||||
appFile.setFileId(fileInfo.getId());
|
appFile.setFileId(fileInfo.getId());
|
||||||
@ -112,15 +117,15 @@ public class AttachmentServiceSupport
|
|||||||
final Function<String, List<T>> listSort,
|
final Function<String, List<T>> listSort,
|
||||||
final Consumer<T> updater) {
|
final Consumer<T> updater) {
|
||||||
|
|
||||||
final String id = form.getId();
|
val id = form.getId();
|
||||||
final T appImage = finder.apply(id);
|
val appImage = finder.apply(id);
|
||||||
Assert.state(appImage != null, "No local product file [" + id + "] found");
|
Assert.state(appImage != null, "No local product file [" + id + "] found");
|
||||||
final String ownerId = appImage.getOwnerId();
|
val ownerId = appImage.getOwnerId();
|
||||||
final String updatedBy = form.getUpdatedBy();
|
val updatedBy = form.getUpdatedBy();
|
||||||
|
|
||||||
boolean sortUpdated = false;
|
boolean sortUpdated = false;
|
||||||
final float sort = form.getSort();
|
val sort = form.getSort();
|
||||||
final float sortOld = appImage.getSort();
|
val sortOld = appImage.getSort();
|
||||||
if (sort < sortOld) {
|
if (sort < sortOld) {
|
||||||
sortUpdated = true;
|
sortUpdated = true;
|
||||||
appImage.setSort(sortOld - 1.5f);
|
appImage.setSort(sortOld - 1.5f);
|
||||||
@ -150,12 +155,13 @@ public class AttachmentServiceSupport
|
|||||||
final Function<String, Integer> deleter,
|
final Function<String, Integer> deleter,
|
||||||
final Function<String, Integer> sortUpdater,
|
final Function<String, Integer> sortUpdater,
|
||||||
final Consumer<T> validator) {
|
final Consumer<T> validator) {
|
||||||
final T attachment = finder.apply(id);
|
|
||||||
|
val attachment = finder.apply(id);
|
||||||
Assert.state(attachment != null, "No file [" + id + "] found");
|
Assert.state(attachment != null, "No file [" + id + "] found");
|
||||||
if (validator != null) {
|
if (validator != null) {
|
||||||
validator.accept(attachment);
|
validator.accept(attachment);
|
||||||
}
|
}
|
||||||
final String ownerId = attachment.getOwnerId();
|
val ownerId = attachment.getOwnerId();
|
||||||
fileApi.delete(fileFolder(ownerId) + "/" + id);
|
fileApi.delete(fileFolder(ownerId) + "/" + id);
|
||||||
deleter.apply(id);
|
deleter.apply(id);
|
||||||
sortUpdater.apply(ownerId);
|
sortUpdater.apply(ownerId);
|
||||||
@ -170,7 +176,7 @@ public class AttachmentServiceSupport
|
|||||||
final Consumer<M> validator) {
|
final Consumer<M> validator) {
|
||||||
|
|
||||||
log.info("Delete attachment owner [{}].", ownerId);
|
log.info("Delete attachment owner [{}].", ownerId);
|
||||||
final M owner = mapper.find(ownerId);
|
val owner = mapper.find(ownerId);
|
||||||
Assert.state(owner != null, "No attachment owner [" + ownerId + "] found");
|
Assert.state(owner != null, "No attachment owner [" + ownerId + "] found");
|
||||||
Assert.state(!owner.isEnabled(), "Attachment owner [" + ownerId + "] is enabled");
|
Assert.state(!owner.isEnabled(), "Attachment owner [" + ownerId + "] is enabled");
|
||||||
|
|
||||||
@ -178,7 +184,7 @@ public class AttachmentServiceSupport
|
|||||||
validator.accept(owner);
|
validator.accept(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Search search = new Search(AttachedImage.OWNER_ID, ownerId);
|
val search = new Search(AttachedImage.OWNER_ID, ownerId);
|
||||||
imageMapper.list(search).forEach(
|
imageMapper.list(search).forEach(
|
||||||
image -> fileApi.deleteById(image.getFileId()));
|
image -> fileApi.deleteById(image.getFileId()));
|
||||||
imageMapper.delete(search);
|
imageMapper.delete(search);
|
||||||
|
@ -3,10 +3,12 @@ package com.pudonghot.ambition.file;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import javax.validation.constraints.Min;
|
import javax.validation.Valid;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import com.pudonghot.ambition.file.request.AmFileUploadReq;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import com.pudonghot.ambition.file.request.AmInputStreamUploadReq;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version 0.0.4
|
* @version 0.0.4
|
||||||
@ -42,67 +44,18 @@ public interface AmbitionFileApi<UploadReturn> {
|
|||||||
@NotBlank String getUrl(@NotBlank String name);
|
@NotBlank String getUrl(@NotBlank String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload File To OSS
|
* upload file
|
||||||
* @param file File
|
* @param req req
|
||||||
* @param name File Name [optional], Such As "foobar.doc",
|
* @return result
|
||||||
* A UUID Will Be The Name, If Name Not Specified,
|
|
||||||
* @return File Link [http://umsapp.oss-cn-hangzhou.aliyuncs.com/echat-dev/foobar.png]
|
|
||||||
*/
|
*/
|
||||||
UploadReturn upload(@NotNull File file, String name);
|
UploadReturn upload(@NotNull @Valid AmFileUploadReq req);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload File
|
* upload file
|
||||||
* @param file File
|
* @param req req
|
||||||
* @param folder Custom Folder
|
* @return result
|
||||||
* @param name File Name
|
|
||||||
* @param contentType Content Type [Optional]
|
|
||||||
* @param format File Format [Optional]
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
UploadReturn upload(@NotNull File file, String folder, String name, String contentType, String format);
|
UploadReturn upload(@NotNull @Valid AmInputStreamUploadReq req);
|
||||||
|
|
||||||
/**
|
|
||||||
* Upload Stream
|
|
||||||
* @param ins Input Stream
|
|
||||||
* @param name File Name
|
|
||||||
* @return File Link [http://umsapp.oss-cn-hangzhou.aliyuncs.com/echat-dev/foobar.png]
|
|
||||||
*/
|
|
||||||
UploadReturn upload(@NotNull InputStream ins, @Min(1) long contentLength, String name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Upload Stream
|
|
||||||
* @param ins Input Stream
|
|
||||||
* @param folder Custom Folder
|
|
||||||
* @param name name
|
|
||||||
* @param contentType Content Type [Optional]
|
|
||||||
* @param format File Format [Optional]
|
|
||||||
*/
|
|
||||||
UploadReturn upload(@NotNull InputStream ins,
|
|
||||||
@Min(1) long contentLength,
|
|
||||||
String folder,
|
|
||||||
String name,
|
|
||||||
String contentType,
|
|
||||||
String format);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Upload Stream To OSS
|
|
||||||
* @param ins Input Stream
|
|
||||||
* @param contentLength
|
|
||||||
* @param folder Custom Folder
|
|
||||||
* @param name File Name [optional], Such As "foobar.doc",
|
|
||||||
* A UUID Will Be The Name, If Name Not Specified,
|
|
||||||
* @param contentType Content Type [Optional]
|
|
||||||
* @param format File Format [Optional]
|
|
||||||
* @param downloadName File Download Name [Optional]
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
UploadReturn upload(@NotNull InputStream ins,
|
|
||||||
@Min(1) long contentLength,
|
|
||||||
String folder,
|
|
||||||
String name,
|
|
||||||
String contentType,
|
|
||||||
String format,
|
|
||||||
String downloadName);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get File From OSS
|
* Get File From OSS
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.pudonghot.ambition.file.request;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date May 29, 2022 12:14:35
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class AmFileUploadReq implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload file
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
private File file;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* custom folder
|
||||||
|
*/
|
||||||
|
private String folder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional file name, such as "some-file.doc"
|
||||||
|
* A UUID will be the name, if name not specified
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file content type [optional]
|
||||||
|
*/
|
||||||
|
private String contentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file format
|
||||||
|
*/
|
||||||
|
private String format;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file download name
|
||||||
|
*/
|
||||||
|
private String downloadName;
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.pudonghot.ambition.file.request;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date May 29, 2022 12:14:35
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class AmInputStreamUploadReq implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input stream
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
private InputStream inputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file content length
|
||||||
|
*/
|
||||||
|
@Min(1)
|
||||||
|
@NotNull
|
||||||
|
private Number contentLength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* custom folder
|
||||||
|
*/
|
||||||
|
private String folder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional file name, such as "some-file.doc"
|
||||||
|
* A UUID will be the name, if name not specified
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file content type [optional]
|
||||||
|
*/
|
||||||
|
private String contentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file format
|
||||||
|
*/
|
||||||
|
private String format;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file download name
|
||||||
|
*/
|
||||||
|
private String downloadName;
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.pudonghot.ambition.file.support;
|
package com.pudonghot.ambition.file.support;
|
||||||
|
|
||||||
|
import lombok.val;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -20,7 +21,9 @@ import me.chyxion.tigon.sequence.IdSequence;
|
|||||||
import com.pudonghot.ambition.file.ImageTool;
|
import com.pudonghot.ambition.file.ImageTool;
|
||||||
import org.springframework.util.MimeTypeUtils;
|
import org.springframework.util.MimeTypeUtils;
|
||||||
import com.pudonghot.ambition.file.AmbitionFileApi;
|
import com.pudonghot.ambition.file.AmbitionFileApi;
|
||||||
|
import com.pudonghot.ambition.file.request.AmFileUploadReq;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import com.pudonghot.ambition.file.request.AmInputStreamUploadReq;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version 0.0.1
|
* @version 0.0.1
|
||||||
@ -40,55 +43,41 @@ public abstract class AbstractAmbitionFileApi<UploadReturn> implements AmbitionF
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public UploadReturn upload(final File file, final String folder, String name, final String contentType, String format) {
|
public UploadReturn upload(final AmFileUploadReq fileReq) {
|
||||||
|
val file = fileReq.getFile();
|
||||||
|
val folder = fileReq.getFolder();
|
||||||
|
String name = fileReq.getName();
|
||||||
|
val contentType = fileReq.getContentType();
|
||||||
|
String format = fileReq.getFormat();
|
||||||
|
|
||||||
log.info("Upload input stream file [{}].", name);
|
log.info("Upload input stream file [{}].", name);
|
||||||
if (StringUtils.isBlank(name)) {
|
if (StringUtils.isBlank(name)) {
|
||||||
name = idSeq.get();
|
name = idSeq.get();
|
||||||
String fileExt = FilenameUtils.getExtension(file.getName());
|
val fileExt = FilenameUtils.getExtension(file.getName());
|
||||||
if (StringUtils.isNotBlank(fileExt)
|
if (StringUtils.isNotBlank(fileExt)
|
||||||
&& StringUtils.isBlank(format)) {
|
&& StringUtils.isBlank(format)) {
|
||||||
format = fileExt;
|
format = fileExt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val req = new AmInputStreamUploadReq();
|
||||||
try {
|
try {
|
||||||
return upload(new FileInputStream(file),
|
req.setInputStream(new FileInputStream(file));
|
||||||
file.length(),
|
|
||||||
folder,
|
|
||||||
name,
|
|
||||||
contentType,
|
|
||||||
format);
|
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException e) {
|
catch (FileNotFoundException e) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Upload File Error Caused, File Not Found", e);
|
"Upload file error caused, file not found", e);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
req.setContentLength(file.length());
|
||||||
* {@inheritDoc}
|
req.setFolder(folder);
|
||||||
*/
|
req.setName(name);
|
||||||
@Override
|
req.setContentType(contentType);
|
||||||
public UploadReturn upload(File file, String name) {
|
req.setFormat(format);
|
||||||
return upload(file, null, name, null, null);
|
req.setDownloadName(fileReq.getDownloadName());
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
return upload(req);
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public UploadReturn upload(InputStream in, long contentLength, String name) {
|
|
||||||
return upload(in, contentLength, null, name, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public UploadReturn upload(InputStream in,
|
|
||||||
long contentLength,
|
|
||||||
String folder, String name,
|
|
||||||
String contentType, String fileFormat) {
|
|
||||||
return upload(in, contentLength, folder, name, contentType, fileFormat, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,25 +85,19 @@ public abstract class AbstractAmbitionFileApi<UploadReturn> implements AmbitionF
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public byte[] combineAvatars(List<String> members) {
|
public byte[] combineAvatars(List<String> members) {
|
||||||
List<BufferedImage> images = new LinkedList<BufferedImage>();
|
val images = new LinkedList<BufferedImage>();
|
||||||
for (String memberId : members) {
|
|
||||||
InputStream imageInput = null;
|
for (val memberId : members) {
|
||||||
try {
|
try (val imageInput = getInputStream("avatar/" + memberId)) {
|
||||||
imageInput = getInputStream("avatar/" + memberId);
|
|
||||||
images.add(ImageIO.read(imageInput));
|
images.add(ImageIO.read(imageInput));
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
uploadAvatar(memberId, "U", "");
|
uploadAvatar(memberId, "U", "");
|
||||||
log.error("Read Member [{}] Avatar Error Caused", memberId, e);
|
log.error("Read Member [{}] Avatar Error Caused", memberId, e);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
IOUtils.closeQuietly(imageInput);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!images.isEmpty()) {
|
if (!images.isEmpty()) {
|
||||||
ByteArrayOutputStream baos = null;
|
try (val baos = new ByteArrayOutputStream()) {
|
||||||
try {
|
|
||||||
baos = new ByteArrayOutputStream();
|
|
||||||
ImageIO.write(imageTool.combine(images), "png", baos);
|
ImageIO.write(imageTool.combine(images), "png", baos);
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
@ -122,12 +105,9 @@ public abstract class AbstractAmbitionFileApi<UploadReturn> implements AmbitionF
|
|||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Write Image File Error Caused", e);
|
"Write Image File Error Caused", e);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
IOUtils.closeQuietly(baos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"No Image Found In Members " + members);
|
"No image found in members " + members);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,11 +132,14 @@ public abstract class AbstractAmbitionFileApi<UploadReturn> implements AmbitionF
|
|||||||
@Override
|
@Override
|
||||||
public UploadReturn uploadAvatar(String folder, String memberId, String name, String gender) {
|
public UploadReturn uploadAvatar(String folder, String memberId, String name, String gender) {
|
||||||
byte[] bytesAvatar = imageTool.genAvatar(name, gender);
|
byte[] bytesAvatar = imageTool.genAvatar(name, gender);
|
||||||
return upload(new ByteArrayInputStream(bytesAvatar),
|
val req = new AmInputStreamUploadReq();
|
||||||
bytesAvatar.length,
|
req.setInputStream(new ByteArrayInputStream(bytesAvatar));
|
||||||
folder,
|
req.setContentLength(bytesAvatar.length);
|
||||||
memberId,
|
req.setFolder(folder);
|
||||||
MimeTypeUtils.IMAGE_PNG_VALUE, "png");
|
req.setName(memberId);
|
||||||
|
req.setContentType(MimeTypeUtils.IMAGE_PNG_VALUE);
|
||||||
|
req.setFormat("png");
|
||||||
|
return upload(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -202,15 +185,21 @@ public abstract class AbstractAmbitionFileApi<UploadReturn> implements AmbitionF
|
|||||||
String format = imageTool.imageType(new ByteArrayInputStream(bytesFile));
|
String format = imageTool.imageType(new ByteArrayInputStream(bytesFile));
|
||||||
if (StringUtils.isNotBlank(format)) {
|
if (StringUtils.isNotBlank(format)) {
|
||||||
if (!ArrayUtils.contains(new String[] {"png", "jpg", "jpeg"}, format)) {
|
if (!ArrayUtils.contains(new String[] {"png", "jpg", "jpeg"}, format)) {
|
||||||
log.info("Image File Type Is Not JPG Or PNG, Convert To JPG.");
|
log.info("Image file type is not `JPG` Or `PNG`, convert to JPG.");
|
||||||
bytesFile = imageTool.toJpegBytes(bytesFile);
|
bytesFile = imageTool.toJpegBytes(bytesFile);
|
||||||
format = "jpg";
|
format = "jpg";
|
||||||
}
|
}
|
||||||
log.info("Upload Image With Folder [{}], Name [{}], Format [{}].", folder, name, format);
|
log.info("Upload Image With Folder [{}], Name [{}], Format [{}].", folder, name, format);
|
||||||
return upload(
|
|
||||||
new ByteArrayInputStream(bytesFile),
|
val req = new AmInputStreamUploadReq();
|
||||||
bytesFile.length,
|
req.setInputStream(new ByteArrayInputStream(bytesFile));
|
||||||
folder, name, "image/" + format, format);
|
req.setContentLength(bytesFile.length);
|
||||||
|
req.setFolder(folder);
|
||||||
|
req.setName(name);
|
||||||
|
req.setContentType("image/" + format);
|
||||||
|
req.setFormat(format);
|
||||||
|
|
||||||
|
return upload(req);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.pudonghot.ambition.file.disk;
|
package com.pudonghot.ambition.file.disk;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import lombok.val;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
@ -15,6 +16,7 @@ import com.pudonghot.ambition.crm.mapper.FileInfoMapper;
|
|||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import com.pudonghot.ambition.file.request.AmInputStreamUploadReq;
|
||||||
import com.pudonghot.ambition.file.support.AbstractAmbitionFileApi;
|
import com.pudonghot.ambition.file.support.AbstractAmbitionFileApi;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,11 +43,11 @@ public class DiskFileSupport
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public InputStream getInputStream(String name) {
|
public InputStream getInputStream(final String name) {
|
||||||
try {
|
try {
|
||||||
return new FileInputStream(getFile(name));
|
return new FileInputStream(getFile(name));
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException e) {
|
catch (final FileNotFoundException e) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Get file [" + name + "] input stream error caused");
|
"Get file [" + name + "] input stream error caused");
|
||||||
}
|
}
|
||||||
@ -65,7 +67,7 @@ public class DiskFileSupport
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Throwable.class)
|
@Transactional(rollbackFor = Throwable.class)
|
||||||
public void delete(final String name) {
|
public void delete(final String name) {
|
||||||
final FileInfo fileInfo = findFileInfo(name);
|
val fileInfo = findFileInfo(name);
|
||||||
if (fileInfo != null) {
|
if (fileInfo != null) {
|
||||||
fileInfoMapper.delete(fileInfo.getId());
|
fileInfoMapper.delete(fileInfo.getId());
|
||||||
FileUtils.deleteQuietly(getFile(fileInfo));
|
FileUtils.deleteQuietly(getFile(fileInfo));
|
||||||
@ -85,23 +87,24 @@ public class DiskFileSupport
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public FileInfo upload(final InputStream in,
|
public FileInfo upload(final AmInputStreamUploadReq req) {
|
||||||
final long contentLength,
|
|
||||||
String folder,
|
val folder = req.getFolder();
|
||||||
final String name,
|
val name = req.getName();
|
||||||
String contentType,
|
|
||||||
String fileFormat,
|
val fileId = idSeq.get();
|
||||||
String downloadName) {
|
val fullName = getFileFullName(fileId, folder, name);
|
||||||
final String fileId = idSeq.get();
|
|
||||||
final String fullName = getFileFullName(fileId, folder, name);
|
|
||||||
boolean update = false;
|
boolean update = false;
|
||||||
Date now = new Date();
|
|
||||||
|
val now = new Date();
|
||||||
FileInfo fileInfo = findFileInfo(fullName);
|
FileInfo fileInfo = findFileInfo(fullName);
|
||||||
|
|
||||||
if (fileInfo != null) {
|
if (fileInfo != null) {
|
||||||
fileInfo.setDateUpdated(now);
|
fileInfo.setDateUpdated(now);
|
||||||
update = true;
|
update = true;
|
||||||
// delete previous file
|
// delete previous file
|
||||||
final File prevFile = getFile(fileInfo);
|
val prevFile = getFile(fileInfo);
|
||||||
log.info("Will delete previous file [{}].", prevFile);
|
log.info("Will delete previous file [{}].", prevFile);
|
||||||
// delete previous files
|
// delete previous files
|
||||||
if (prevFile != null) {
|
if (prevFile != null) {
|
||||||
@ -116,12 +119,15 @@ public class DiskFileSupport
|
|||||||
fileInfo.setDateCreated(now);
|
fileInfo.setDateCreated(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String filePath = getFilePath(fileId, folder, name, fileFormat);
|
val fileFormat = req.getFormat();
|
||||||
|
val filePath = getFilePath(fileId, folder, name, fileFormat);
|
||||||
fileInfo.setFilePath(filePath);
|
fileInfo.setFilePath(filePath);
|
||||||
fileInfo.setEnabled(true);
|
fileInfo.setEnabled(true);
|
||||||
fileInfo.setContentLength(contentLength);
|
|
||||||
fileInfo.setDownloadName(downloadName);
|
fileInfo.setContentLength(req.getContentLength().longValue());
|
||||||
fileInfo.setContentType(StringUtils.defaultIfBlank(contentType,
|
fileInfo.setDownloadName(req.getDownloadName());
|
||||||
|
|
||||||
|
fileInfo.setContentType(StringUtils.defaultIfBlank(req.getContentType(),
|
||||||
MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE));
|
MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE));
|
||||||
fileInfo.setFormat(fileFormat);
|
fileInfo.setFormat(fileFormat);
|
||||||
|
|
||||||
@ -134,29 +140,24 @@ public class DiskFileSupport
|
|||||||
|
|
||||||
// File
|
// File
|
||||||
log.info("Upload input stream with name [{}].", fullName);
|
log.info("Upload input stream with name [{}].", fullName);
|
||||||
OutputStream fout = null;
|
|
||||||
try {
|
|
||||||
|
|
||||||
final File storeFile = new File(getFileDir(), filePath);
|
val storeFile = new File(getFileDir(), filePath);
|
||||||
final File fileParent = storeFile.getParentFile();
|
val fileParent = storeFile.getParentFile();
|
||||||
if (!fileParent.isDirectory()) {
|
if (!fileParent.isDirectory()) {
|
||||||
fileParent.mkdirs();
|
fileParent.mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
fout = new FileOutputStream(storeFile);
|
try (val in = req.getInputStream();
|
||||||
|
val fout = new FileOutputStream(storeFile)) {
|
||||||
IOUtils.copy(in, fout);
|
IOUtils.copy(in, fout);
|
||||||
// return basePath + fullName;
|
|
||||||
fileInfo.setUrl(basePath + filePath);
|
|
||||||
return fileInfo;
|
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Upload file [" + fullName + "] error caused", e);
|
"Upload file [" + fullName + "] error caused", e);
|
||||||
}
|
}
|
||||||
finally {
|
// return basePath + fullName;
|
||||||
IOUtils.closeQuietly(fout);
|
fileInfo.setUrl(basePath + filePath);
|
||||||
IOUtils.closeQuietly(in);
|
return fileInfo;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,7 +165,7 @@ public class DiskFileSupport
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public File getFile(final String name) {
|
public File getFile(final String name) {
|
||||||
final FileInfo fileInfo = findFileInfo(name);
|
val fileInfo = findFileInfo(name);
|
||||||
return fileInfo != null ? getFile(fileInfo): null;
|
return fileInfo != null ? getFile(fileInfo): null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +173,7 @@ public class DiskFileSupport
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public long getContentLength(String name) {
|
public long getContentLength(final String name) {
|
||||||
return getFile(name).length();
|
return getFile(name).length();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,24 +181,17 @@ public class DiskFileSupport
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(String folder, String name) {
|
public String getUrl(final String folder, String name) {
|
||||||
String fileFullName = null;
|
val fileFullName = prependFolder(folder, name);
|
||||||
if (StringUtils.isNotBlank(folder)) {
|
|
||||||
if (!folder.endsWith("/")) {
|
val fileInfo = findFileInfo(fileFullName);
|
||||||
folder += "/";
|
if (fileInfo != null) {
|
||||||
|
return basePath + fileInfo.getFilePath();
|
||||||
}
|
}
|
||||||
fileFullName = folder + name;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fileFullName = name;
|
|
||||||
}
|
|
||||||
final FileInfo fileInfo = findFileInfo(fileFullName);
|
|
||||||
if (fileInfo == null) {
|
|
||||||
log.error("No File [{}] Found.", fileFullName);
|
log.error("No File [{}] Found.", fileFullName);
|
||||||
return basePath + fileFullName;
|
return basePath + fileFullName;
|
||||||
}
|
}
|
||||||
return basePath + fileInfo.getFilePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
@ -227,8 +221,8 @@ public class DiskFileSupport
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(String id) {
|
public void deleteById(final String id) {
|
||||||
final FileInfo fileInfo = fileInfoMapper.find(id);
|
val fileInfo = fileInfoMapper.find(id);
|
||||||
if (fileInfo != null) {
|
if (fileInfo != null) {
|
||||||
log.info("Delete file [{}].", fileInfo);
|
log.info("Delete file [{}].", fileInfo);
|
||||||
fileInfoMapper.delete(id);
|
fileInfoMapper.delete(id);
|
||||||
@ -240,55 +234,36 @@ public class DiskFileSupport
|
|||||||
// private methods
|
// private methods
|
||||||
|
|
||||||
File getFileDir() {
|
File getFileDir() {
|
||||||
File baseFileDir = new File(baseDir);
|
val baseFileDir = new File(baseDir);
|
||||||
if (!baseFileDir.exists()) {
|
if (!baseFileDir.exists()) {
|
||||||
baseFileDir.mkdirs();
|
baseFileDir.mkdirs();
|
||||||
}
|
}
|
||||||
return baseFileDir;
|
return baseFileDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getFileFullName(String fileId, String folder, String name) {
|
String getFileFullName(final String fileId,
|
||||||
if (StringUtils.isNotBlank(folder)) {
|
final String folder,
|
||||||
if (!folder.endsWith("/")) {
|
final String name) {
|
||||||
folder += "/";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String fullName = null;
|
|
||||||
if (StringUtils.isNotBlank(name)) {
|
if (StringUtils.isNotBlank(name)) {
|
||||||
log.debug("Name [{}] is not blank.", name);
|
log.debug("Name [{}] is not blank.", name);
|
||||||
if (name.startsWith(basePath)) {
|
if (name.startsWith(basePath)) {
|
||||||
log.debug("Name starts with base path [{}], trim.", basePath);
|
log.debug("Name starts with base path [{}], trim.", basePath);
|
||||||
fullName = name.replaceFirst(basePath, "");
|
return name.replaceFirst(basePath, "");
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotBlank(folder)) {
|
|
||||||
fullName = folder + name;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fullName = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// name is blank, folder is not blank
|
|
||||||
else if (StringUtils.isNotBlank(folder)) {
|
|
||||||
fullName = folder + fileId;
|
|
||||||
}
|
|
||||||
// name and folder are blank
|
|
||||||
else {
|
|
||||||
fullName = fileId;
|
|
||||||
}
|
|
||||||
return fullName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getFilePath(final String fileId, final String folder, final String name, String fileFormat) {
|
return prependFolder(folder, fileId);
|
||||||
String distFolder = DateFormatUtils.format(new Date(), "yyyyMMdd") + "/";
|
|
||||||
if (StringUtils.isNotBlank(folder)) {
|
|
||||||
if (folder.endsWith("/")) {
|
|
||||||
distFolder = folder + distFolder;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
distFolder = folder + "/" + distFolder;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getFilePath(final String fileId,
|
||||||
|
final String folder,
|
||||||
|
final String name,
|
||||||
|
final String fileFormat) {
|
||||||
|
|
||||||
|
val distFolder = prependFolder(folder,
|
||||||
|
DateFormatUtils.format(new Date(), "yyyyMMdd") + "/");
|
||||||
|
|
||||||
String filePath = null;
|
String filePath = null;
|
||||||
if (StringUtils.isNotBlank(name)) {
|
if (StringUtils.isNotBlank(name)) {
|
||||||
log.debug("Name [{}] is not blank.", name);
|
log.debug("Name [{}] is not blank.", name);
|
||||||
@ -307,4 +282,14 @@ public class DiskFileSupport
|
|||||||
return StringUtils.isNotBlank(fileFormat) ?
|
return StringUtils.isNotBlank(fileFormat) ?
|
||||||
filePath + "." + fileFormat : filePath;
|
filePath + "." + fileFormat : filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String prependFolder(final String folder, final String file) {
|
||||||
|
if (StringUtils.isNotBlank(folder)) {
|
||||||
|
if (folder.endsWith("/")) {
|
||||||
|
return folder + file;
|
||||||
|
}
|
||||||
|
return folder + "/" + file;
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.pudonghot.ambition.crm.enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date May 29, 2022 11:58:01
|
||||||
|
*/
|
||||||
|
public enum EnumExportTaskStatus {
|
||||||
|
RUNNING,
|
||||||
|
DONE,
|
||||||
|
FAILED
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.pudonghot.ambition.crm.enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date May 29, 2022 11:58:01
|
||||||
|
*/
|
||||||
|
public enum EnumGender {
|
||||||
|
M,
|
||||||
|
F
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.pudonghot.ambition.crm.model;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import me.chyxion.tigon.mybatis.NotUpdate;
|
||||||
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Shaun Chyxion <br>
|
||||||
|
* chyxion@163.com <br>
|
||||||
|
* Aug 09, 2017 22:24:40
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@FieldNameConstants(prefix = "")
|
||||||
|
public class BaseDbModel implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
@NotUpdate
|
||||||
|
private String createdBy;
|
||||||
|
@NotUpdate
|
||||||
|
private Date dateCreated;
|
||||||
|
private String updatedBy;
|
||||||
|
private Date dateUpdated;
|
||||||
|
private boolean enabled;
|
||||||
|
private String note;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.pudonghot.ambition.crm.model;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import me.chyxion.tigon.mybatis.Table;
|
||||||
|
import me.chyxion.tigon.mybatis.NotUpdate;
|
||||||
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
import com.pudonghot.ambition.crm.enumeration.EnumExportTaskStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date May 29, 2022 11:55:30
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Table("crm_export_task")
|
||||||
|
@FieldNameConstants(prefix = "")
|
||||||
|
public class ExportTask extends BaseDbModel {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
private EnumExportTaskStatus status;
|
||||||
|
@NotUpdate
|
||||||
|
private String location;
|
||||||
|
}
|
@ -26,7 +26,7 @@ public class FileInfo extends M3<String, String> {
|
|||||||
private String filePath;
|
private String filePath;
|
||||||
private String format;
|
private String format;
|
||||||
private String downloadName;
|
private String downloadName;
|
||||||
private long contentLength;
|
private Long contentLength;
|
||||||
private String contentType;
|
private String contentType;
|
||||||
@Transient
|
@Transient
|
||||||
private String url;
|
private String url;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user