refactor travel

This commit is contained in:
Timi
2025-12-13 18:45:50 +08:00
parent d12c76fe03
commit 658765df6f
17 changed files with 179 additions and 155 deletions
@@ -3,12 +3,15 @@ package com.imyeyu.api.modules.common.entity;
import com.google.gson.JsonObject;
import com.imyeyu.api.bean.MultilingualHandler;
import com.imyeyu.java.ref.Ref;
import com.imyeyu.spring.annotation.table.Transient;
import com.imyeyu.spring.entity.Entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import java.io.InputStream;
/**
* @author 夜雨
* @since 2023-08-15 10:17
@@ -80,6 +83,9 @@ public class Attachment extends Entity implements MultilingualHandler {
protected Long destroyAt;
@Transient
protected InputStream inputStream;
public void setAttachTypeValue(Enum<?> attachType) {
this.attachType = attachType.toString();
}
@@ -4,11 +4,7 @@ import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentView;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.spring.service.DeletableService;
import com.imyeyu.spring.service.DestroyableService;
import com.imyeyu.spring.service.GettableService;
import com.imyeyu.spring.service.PageableService;
import com.imyeyu.spring.service.UpdatableService;
import com.imyeyu.spring.service.BaseService;
import com.mongodb.client.gridfs.model.GridFSFile;
import java.io.InputStream;
@@ -22,14 +18,19 @@ import java.util.List;
* @author 夜雨
* @since 2023-08-15 10:21
*/
public interface AttachmentService extends GettableService<Attachment, Long>, PageableService<Attachment>, UpdatableService<Attachment>, DeletableService<Long>, DestroyableService<Long> {
public interface AttachmentService extends BaseService<Attachment, Long> {
Attachment createMedia(Attachment attachment);
/**
*
*
* @param request
*/
void create(AttachmentRequest request);
@Deprecated
default void create(AttachmentRequest request) {
create((Attachment) request);
}
/**
* 创建媒体附件,同步创建缩略图
@@ -37,7 +38,10 @@ public interface AttachmentService extends GettableService<Attachment, Long>, Pa
* @param request 附件请求
* @return 缩略图附件
*/
Attachment createMedia(AttachmentRequest request) throws TimiException;
@Deprecated
default Attachment createMedia(AttachmentRequest request) throws TimiException {
return createMedia((Attachment) request);
}
void deleteMedia(Long thumbId) throws TimiException;
@@ -6,6 +6,7 @@ import com.imyeyu.java.bean.timi.TimiException;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
import java.util.List;
/**
@@ -18,5 +19,7 @@ public interface TempFileService {
File get(String id) throws TimiException;
InputStream getInputStream(String id) throws TimiException;
TempFileMetaData metadata(String id) throws TimiException;
}
@@ -8,7 +8,6 @@ import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.mapper.AttachmentMapper;
import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.service.SettingService;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentView;
import com.imyeyu.api.util.JavaCV;
import com.imyeyu.io.IO;
@@ -65,6 +64,47 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
return mapper;
}
@Transactional(TimiServerDBConfig.ROLLBACKER)
@Override
public void create(Attachment attachment) {
TimiException.required(attachment.getBizType(), "not found attachment.bizType");
TimiException.required(attachment.getBizId(), "not found attachment.bizId");
TimiException.required(attachment.getName(), "not found attachment.name");
String mongoId = null;
try {
InputStream is = attachment.getInputStream();
TimiException.required(is, "not found attachment.inputStream");
TimiException.requiredTrue(is.available() != 0, "empty attachment.inputStream");
StringBuilder mongoName = new StringBuilder(attachment.getBizType().toString());
if (TimiJava.isNotEmpty(attachment.getAttachType())) {
mongoName.append("_").append(attachment.getAttachType().toUpperCase()).append("_");
}
mongoName.append(attachment.getName());
mongoId = gridFsTemplate.store(attachment.getInputStream(), mongoName.toString()).toString();
GridFSFile gridFSFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(mongoId)));
attachment.setMongoId(mongoId);
attachment.setSize(gridFSFile.getLength());
attachment.setMd5(IO.md5(gridFSBucket.openDownloadStream(gridFSFile.getObjectId())));
attachment.setMimeType(new Tika().detect(gridFSBucket.openDownloadStream(gridFSFile.getObjectId())));
if (attachment.getMimeType().startsWith("image")) {
BufferedImage image = ImageIO.read(gridFSBucket.openDownloadStream(gridFSFile.getObjectId()));
Metadata.Image metadata = new Metadata.Image();
metadata.setWidth(image.getWidth());
metadata.setHeight(image.getHeight());
attachment.setMetadata(gson.toJsonTree(metadata).getAsJsonObject());
}
mapper.insert(attachment);
} catch (Exception e) {
if (mongoId != null) {
gridFsTemplate.delete(Query.query(Criteria.where("_id").is(mongoId)));
}
log.error("create attachment error", e);
throw new TimiException(TimiCode.ARG_BAD).msgKey("TODO read attachment input stream error");
}
}
@Transactional(TimiServerDBConfig.ROLLBACKER)
@Override
public void destroy(Long id) {
@@ -83,62 +123,18 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
@Transactional(TimiServerDBConfig.ROLLBACKER)
@Override
public void create(AttachmentRequest request) {
TimiException.required(request.getBizType(), "not found request.bizType");
TimiException.required(request.getBizId(), "not found request.bizId");
TimiException.required(request.getName(), "not found request.name");
String mongoId = null;
try {
InputStream is = request.getInputStream();
TimiException.required(is, "not found request.inputStream");
TimiException.requiredTrue(is.available() != 0, "empty request.inputStream");
StringBuilder mongoName = new StringBuilder(request.getBizType().toString());
if (TimiJava.isNotEmpty(request.getAttachType())) {
mongoName.append("_").append(request.getAttachType().toUpperCase()).append("_");
}
mongoName.append(request.getName());
mongoId = gridFsTemplate.store(request.getInputStream(), mongoName.toString()).toString();
GridFSFile gridFSFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(mongoId)));
request.setMongoId(mongoId);
request.setSize(gridFSFile.getLength());
request.setMd5(IO.md5(gridFSBucket.openDownloadStream(gridFSFile.getObjectId())));
request.setMimeType(new Tika().detect(gridFSBucket.openDownloadStream(gridFSFile.getObjectId())));
if (request.getMimeType().startsWith("image")) {
BufferedImage image = ImageIO.read(gridFSBucket.openDownloadStream(gridFSFile.getObjectId()));
Metadata.Image metadata = new Metadata.Image();
metadata.setWidth(image.getWidth());
metadata.setHeight(image.getHeight());
request.setMetadata(gson.toJsonTree(metadata).getAsJsonObject());
}
mapper.insert(request);
} catch (Exception e) {
if (mongoId != null) {
gridFsTemplate.delete(Query.query(Criteria.where("_id").is(mongoId)));
}
log.error("create attachment error", e);
throw new TimiException(TimiCode.ARG_BAD).msgKey("TODO read attachment input stream error");
}
}
@Transactional(TimiServerDBConfig.ROLLBACKER)
@Override
public Attachment createMedia(AttachmentRequest request) throws TimiException {
TimiException.required(request.getName(), "not found name");
TimiException.required(request.getBizType(), "not found bizType");
TimiException.required(request.getInputStream(), "not found inputStream");
public Attachment createMedia(Attachment attachment) throws TimiException {
try {
// 储存源文件
request.setAttachTypeValue(MediaAttach.Type.SOURCE);
create(request);
attachment.setAttachTypeValue(MediaAttach.Type.SOURCE);
create(attachment);
// 生成缩略图
InputStream mimeStream = getInputStreamByMongoId(request.getMongoId());
InputStream mimeStream = getInputStreamByMongoId(attachment.getMongoId());
String mimeType = new Tika().detect(mimeStream);
boolean isImage = false;
InputStream sourceStream = getInputStreamByMongoId(request.getMongoId());
InputStream sourceStream = getInputStreamByMongoId(attachment.getMongoId());
ByteArrayOutputStream thumbStream = new ByteArrayOutputStream();
switch (mimeType) {
case "image/png", "image/bmp", "image/jpeg" -> {
@@ -146,14 +142,14 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
Thumbnails.of(sourceStream).width(256).keepAspectRatio(true).toOutputStream(thumbStream);
}
case "video/mp4", "video/quicktime" -> {
log.info("capturing thumbnail: {}", request.getName());
log.info("capturing thumbnail: {}", attachment.getName());
long start = Time.now();
File tempFile = IO.file("temp/%s_%s".formatted(UUID.randomUUID().toString(), request.getName()));
File tempFile = IO.file("temp/%s_%s".formatted(UUID.randomUUID().toString(), attachment.getName()));
try {
IO.toFile(tempFile, sourceStream);
ByteArrayOutputStream baos = JavaCV.captureThumbnail(IO.getInputStream(tempFile), 2);
Thumbnails.of(IO.toInputStream(baos)).width(256).keepAspectRatio(true).toOutputStream(thumbStream);
log.info("captured thumbnail: {} at {} ms", request.getName(), Time.now() - start);
log.info("captured thumbnail: {} at {} ms", attachment.getName(), Time.now() - start);
} finally {
IO.destroy(tempFile);
}
@@ -162,13 +158,13 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
MediaAttach.ExtData extData = new MediaAttach.ExtData();
extData.setImage(isImage);
extData.setVideo(!isImage);
extData.setSourceId(request.getId());
extData.setSourceMongoId(request.getMongoId());
extData.setSourceId(attachment.getId());
extData.setSourceMongoId(attachment.getMongoId());
AttachmentRequest thumbAttach = new AttachmentRequest();
thumbAttach.setName(Network.simpleURIFileName(request.getName()) + ".png");
thumbAttach.setBizType(request.getBizType());
thumbAttach.setBizId(request.getBizId());
Attachment thumbAttach = new Attachment();
thumbAttach.setName(Network.simpleURIFileName(attachment.getName()) + ".png");
thumbAttach.setBizType(attachment.getBizType());
thumbAttach.setBizId(attachment.getBizId());
thumbAttach.setAttachTypeValue(MediaAttach.Type.THUMB);
thumbAttach.setExt(gson.toJson(extData));
thumbAttach.setInputStream(new ByteArrayInputStream(thumbStream.toByteArray()));
@@ -22,7 +22,9 @@ import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -108,6 +110,15 @@ public class TempFileServiceImplement implements TempFileService {
return metaData.getPath().toFile();
}
@Override
public InputStream getInputStream(String id) throws TimiException {
try {
return IO.getInputStream(get(id));
} catch (FileNotFoundException e) {
throw new TimiException(TimiCode.RESULT_NULL, "not found temp file");
}
}
@Override
public TempFileMetaData metadata(String id) throws TimiException {
return metadataMap.get(id);
@@ -5,8 +5,6 @@ import com.imyeyu.spring.annotation.table.Transient;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.InputStream;
/**
* @author 夜雨
@@ -14,8 +12,7 @@ import java.io.InputStream;
*/
@Data
@Transient
@Deprecated
@EqualsAndHashCode(callSuper = true)
public class AttachmentRequest extends Attachment {
private InputStream inputStream;
}