Compare commits

...

5 Commits

Author SHA1 Message Date
fa11b388db refactor TempFileService, use Attachment and mongodb 2026-01-05 14:35:38 +08:00
b6eb7980e4 remove AttachmentRequest and AttachmentView 2026-01-04 19:17:42 +08:00
3410c540ab remove Attachment.ext 2026-01-04 19:13:02 +08:00
040a46934d update BaseMapper list rename to select 2026-01-04 19:12:47 +08:00
7eb409f6d0 add MALL travel location type 2025-12-23 14:46:21 +08:00
33 changed files with 293 additions and 462 deletions

View File

@ -19,7 +19,7 @@ public interface ArticleMapper extends BaseMapper<Article, Long> {
long countByPage(Page page); long countByPage(Page page);
@Override @Override
List<Article> listByPage(Page page); List<Article> selectByPage(Page page);
long countByKeyword(String keyword); long countByKeyword(String keyword);

View File

@ -58,7 +58,7 @@ public class ArticleServiceImplement extends AbstractEntityService<Article, Long
@Override @Override
public PageResult<Article> page(Page page) { public PageResult<Article> page(Page page) {
PageResult<Article> result = new PageResult<>(); PageResult<Article> result = new PageResult<>();
result.setList(mapper.listByPage(page)); result.setList(mapper.selectByPage(page));
result.setTotal(mapper.countByPage(page)); result.setTotal(mapper.countByPage(page));
return result; return result;
} }

View File

@ -1,7 +1,5 @@
package com.imyeyu.api.modules.common.bean; package com.imyeyu.api.modules.common.bean;
import lombok.Data;
/** /**
* @author 夜雨 * @author 夜雨
* @since 2025-10-20 15:04 * @since 2025-10-20 15:04
@ -18,22 +16,4 @@ public class MediaAttach {
THUMB THUMB
} }
/**
*
*
* @author 夜雨
* @since 2025-10-20 15:04
*/
@Data
public static class ExtData {
private Long sourceId;
private String sourceMongoId;
private boolean isImage;
private boolean isVideo;
}
} }

View File

@ -1,6 +1,7 @@
package com.imyeyu.api.modules.common.bean; package com.imyeyu.api.modules.common.bean;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
/** /**
* @author 夜雨 * @author 夜雨
@ -9,7 +10,7 @@ import lombok.Data;
public class Metadata { public class Metadata {
/** /**
* * 图片
* *
* @author 夜雨 * @author 夜雨
* @since 2025-12-11 18:15 * @since 2025-12-11 18:15
@ -21,4 +22,21 @@ public class Metadata {
private int height; private int height;
} }
/**
* 缩略图
*
* @author 夜雨
* @since 2026-01-04 18:10
*/
@Data
@EqualsAndHashCode(callSuper = true)
public static class ThumbImage extends Image {
private long sourceId;
private String sourceMongoId;
private String sourceMimeType;
}
} }

View File

@ -131,7 +131,7 @@ public enum SettingKey {
MUSIC_CONTROLLER_URI, MUSIC_CONTROLLER_URI,
// ---------- ---------- // ---------- 日记 ----------
JOURNAL_KEY, JOURNAL_KEY,
@ -139,7 +139,22 @@ public enum SettingKey {
JOURNAL_APP_SECRET, JOURNAL_APP_SECRET,
JOURNAL_TRAVEL, // ---------- 临时文件 ----------
/** 临时文件最小缓存时间 */
TEMP_FILE_TTL_MIN,
/** 临时文件最长缓存时间 */
TEMP_FILE_TTL_MAX,
/** 临时文件默认缓存时间 */
TEMP_FILE_TTL_DEFAULT,
/** 已过期的临时文件保留时间 */
TEMP_FILE_RESIDUE_TIME,
/** 每个 IP 限制有效临时文件容量 */
TEMP_FILE_LIMIT,
// ---------- 系统 ---------- // ---------- 系统 ----------

View File

@ -1,26 +0,0 @@
package com.imyeyu.api.modules.common.bean;
import lombok.Data;
import java.nio.file.Path;
/**
* @author 夜雨
* @since 2025-09-27 01:47
*/
@Data
public class TempFileMetaData {
private String id;
private String name;
private String originalName;
private Path path;
private Long lastAccessAt;
/** 缓存时长(毫秒) */
private Long ttl;
}

View File

@ -5,7 +5,6 @@ import com.google.gson.reflect.TypeToken;
import com.imyeyu.api.bean.CaptchaFrom; import com.imyeyu.api.bean.CaptchaFrom;
import com.imyeyu.api.modules.common.bean.ImageType; import com.imyeyu.api.modules.common.bean.ImageType;
import com.imyeyu.api.modules.common.bean.SettingKey; import com.imyeyu.api.modules.common.bean.SettingKey;
import com.imyeyu.api.modules.common.bean.TempFileMetaData;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.entity.Setting; import com.imyeyu.api.modules.common.entity.Setting;
import com.imyeyu.api.modules.common.entity.Task; import com.imyeyu.api.modules.common.entity.Task;
@ -20,7 +19,6 @@ import com.imyeyu.api.modules.common.service.TemplateService;
import com.imyeyu.api.modules.common.service.VersionService; import com.imyeyu.api.modules.common.service.VersionService;
import com.imyeyu.api.modules.common.vo.FeedbackRequest; import com.imyeyu.api.modules.common.vo.FeedbackRequest;
import com.imyeyu.api.modules.common.vo.TempFileResponse; import com.imyeyu.api.modules.common.vo.TempFileResponse;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentView;
import com.imyeyu.api.modules.system.util.ResourceHandler; import com.imyeyu.api.modules.system.util.ResourceHandler;
import com.imyeyu.api.util.CaptchaManager; import com.imyeyu.api.util.CaptchaManager;
import com.imyeyu.io.IO; import com.imyeyu.io.IO;
@ -64,12 +62,8 @@ import java.awt.Graphics2D;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -264,8 +258,8 @@ public class CommonController {
@AOPLog @AOPLog
@RequestRateLimit @RequestRateLimit
@GetMapping("/attachment/{mongoId}") @GetMapping("/attachment/{mongoId}")
public AttachmentView getAttachment(@PathVariable String mongoId) { public Attachment getAttachment(@PathVariable String mongoId) {
return attachmentService.viewByMongoId(mongoId); return attachmentService.getByMongoId(mongoId);
} }
@AOPLog @AOPLog
@ -393,29 +387,28 @@ public class CommonController {
/** /**
* 读取临时文件 * 读取临时文件
* *
* @param fileId * @param mongoId mongoId
* @param req * @param req 请求
* @param resp * @param resp 返回
*/ */
@AOPLog @AOPLog
@RequestRateLimit @RequestRateLimit
@IgnoreGlobalReturn @IgnoreGlobalReturn
@GetMapping("/temp/file/read/{fileId}") @GetMapping("/temp/file/read/{mongoId}")
public void tempFileRead(@PathVariable String fileId, HttpServletRequest req, HttpServletResponse resp) { public void tempFileRead(@PathVariable String mongoId, HttpServletRequest req, HttpServletResponse resp) {
try { try {
File file = tempFileService.get(fileId); Attachment attach = attachmentService.getByMongoId(mongoId);
if (TimiJava.isEmpty(file) && file.exists()) { if (TimiJava.isEmpty(attach)) {
resp.setStatus(HttpServletResponse.SC_NOT_FOUND); resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
return; return;
} }
Path filePath = file.toPath(); GridFSFile file = attachmentService.readByMongoId(attach.getMongoId());
resp.setContentLengthLong(Files.size(filePath)); GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(file.getObjectId());
String mimeType = new Tika().detect(filePath); GridFsResource gridFsResource = new GridFsResource(file, downloadStream);
if (TimiJava.isNotEmpty(mimeType)) { req.setAttribute(ResourceHandler.ATTR_TYPE, ResourceHandler.Type.MONGO);
resp.setContentType(mimeType); req.setAttribute(ResourceHandler.ATTR_VALUE, gridFsResource);
}
req.setAttribute(ResourceHandler.ATTR_TYPE, ResourceHandler.Type.FILE); resp.setContentType(attach.getMimeType());
req.setAttribute(ResourceHandler.ATTR_VALUE, filePath);
resourceHandler.handleRequest(req, resp); resourceHandler.handleRequest(req, resp);
} catch (Exception e) { } catch (Exception e) {
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
@ -425,41 +418,40 @@ public class CommonController {
/** /**
* 下载临时文件 * 下载临时文件
* *
* @param fileId * @param mongoId
* @param resp * @param resp
*/ */
@AOPLog @AOPLog
@RequestRateLimit @RequestRateLimit
@IgnoreGlobalReturn @IgnoreGlobalReturn
@RequestMapping("/temp/file/download/{fileId}") @RequestMapping("/temp/file/download/{mongoId}")
public void tempFileDownload(@PathVariable String fileId, HttpServletResponse resp) { public void tempFileDownload(@PathVariable String mongoId, HttpServletResponse resp) {
try { try {
TempFileMetaData metadata = tempFileService.metadata(fileId); Attachment attach = attachmentService.getByMongoId(mongoId);
File file = tempFileService.get(fileId); if (TimiJava.isEmpty(attach)) {
if (TimiJava.isEmpty(file) && file.exists()) {
resp.setStatus(HttpServletResponse.SC_NOT_FOUND); resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
return; return;
} }
String mimeType = new Tika().detect(file); resp.setContentType(attach.getMimeType());
resp.setContentType(mimeType); resp.setHeader("Content-Disposition", Network.getFileDownloadHeader(attach.getName()));
resp.setHeader("Content-Disposition", Network.getFileDownloadHeader(metadata.getOriginalName()));
resp.setHeader("Accept-Ranges", "bytes"); resp.setHeader("Accept-Ranges", "bytes");
RequestRange range = TimiSpring.requestRange(file.length()); GridFSFile file = attachmentService.readByMongoId(mongoId);
@Cleanup
GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(file.getObjectId());
RequestRange range = TimiSpring.requestRange(attach.getSize());
if (range == null) { if (range == null) {
// 完整文件 // 完整文件
resp.setContentLengthLong(file.length()); resp.setContentLengthLong(attach.getSize());
resp.setStatus(HttpServletResponse.SC_OK); resp.setStatus(HttpServletResponse.SC_OK);
IO.toOutputStream(resp.getOutputStream(), file); IO.toOutputStream(downloadStream, resp.getOutputStream());
} else { } else {
// 分片文件 // 分片文件
resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
resp.setHeader("Content-Range", "bytes %s-%s/%s".formatted(range.getStart(), range.getEnd(), file.length())); resp.setHeader("Content-Range", "bytes %s-%s/%s".formatted(range.getStart(), range.getEnd(), attach.getSize()));
resp.setContentLengthLong(range.getLength()); resp.setContentLengthLong(range.getLength());
IO.toOutputStream(downloadStream, resp.getOutputStream(), range.getStart(), range.getEnd());
@Cleanup RandomAccessFile raf = new RandomAccessFile(file, "r"); resp.flushBuffer();
raf.seek(range.getStart());
IO.toOutputStream(resp.getOutputStream(), raf, range.getStart(), range.getLength());
} }
} catch (Exception e) { } catch (Exception e) {
log.error("download error", e); log.error("download error", e);

View File

@ -1,7 +1,9 @@
package com.imyeyu.api.modules.common.entity; package com.imyeyu.api.modules.common.entity;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.imyeyu.api.TimiServerAPI;
import com.imyeyu.api.bean.MultilingualHandler; import com.imyeyu.api.bean.MultilingualHandler;
import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.java.ref.Ref; import com.imyeyu.java.ref.Ref;
import com.imyeyu.spring.annotation.table.Transient; import com.imyeyu.spring.annotation.table.Transient;
import com.imyeyu.spring.entity.Entity; import com.imyeyu.spring.entity.Entity;
@ -48,14 +50,20 @@ public class Attachment extends Entity implements MultilingualHandler {
/** 镜像 */ /** 镜像 */
MIRROR, MIRROR,
/** 日记 */
JOURNAL, JOURNAL,
/** 日记出行 */
JOURNAL_TRAVEL, JOURNAL_TRAVEL,
/** 日记瞬间 */
JOURNAL_MOMENT, JOURNAL_MOMENT,
/** 系统 */ /** 系统 */
SYSTEM SYSTEM,
/** 临时文件 */
TEMP_FILE
} }
protected BizType bizType; protected BizType bizType;
@ -79,13 +87,20 @@ public class Attachment extends Entity implements MultilingualHandler {
protected String md5; protected String md5;
protected String ext; protected String uploaderIp;
protected Boolean isDestroyed;
protected Long destroyAt; protected Long destroyAt;
@Transient @Transient
protected InputStream inputStream; protected InputStream inputStream;
public InputStream openInputStream() {
AttachmentService service = TimiServerAPI.applicationContext.getBean(AttachmentService.class);
return service.getInputStreamByMongoId(mongoId);
}
public void setAttachTypeValue(Enum<?> attachType) { public void setAttachTypeValue(Enum<?> attachType) {
this.attachType = attachType.toString(); this.attachType = attachType.toString();
} }

View File

@ -3,6 +3,7 @@ package com.imyeyu.api.modules.common.mapper;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.spring.bean.Page; import com.imyeyu.spring.bean.Page;
import com.imyeyu.spring.mapper.BaseMapper; import com.imyeyu.spring.mapper.BaseMapper;
import com.imyeyu.spring.mapper.RawMapper;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import java.util.List; import java.util.List;
@ -11,10 +12,10 @@ import java.util.List;
* @author 夜雨 * @author 夜雨
* @since 2023-08-15 10:22 * @since 2023-08-15 10:22
*/ */
public interface AttachmentMapper extends BaseMapper<Attachment, Long> { public interface AttachmentMapper extends BaseMapper<Attachment, Long>, RawMapper<Attachment, Long> {
/** 有效条件,非删除和销毁 */ /** 有效条件,非删除和销毁 */
String VALID = NOT_DELETE + " AND destroy_at IS NULL"; String VALID = NOT_DELETE + " AND (`destroy_at` IS NULL OR " + UNIX_TIME + " < `destroy_at`)";
@Select("SELECT * FROM attachment WHERE biz_type = #{bizType} AND biz_id = #{bizId} " + VALID + LIMIT_1) @Select("SELECT * FROM attachment WHERE biz_type = #{bizType} AND biz_id = #{bizId} " + VALID + LIMIT_1)
Attachment selectByBizId(Attachment.BizType bizType, long bizId); Attachment selectByBizId(Attachment.BizType bizType, long bizId);
@ -25,9 +26,12 @@ public interface AttachmentMapper extends BaseMapper<Attachment, Long> {
@Select("SELECT * FROM attachment WHERE biz_type = #{bizType} AND biz_id = #{bizId} AND attach_type = #{attachType} " + VALID + LIMIT_1) @Select("SELECT * FROM attachment WHERE biz_type = #{bizType} AND biz_id = #{bizId} AND attach_type = #{attachType} " + VALID + LIMIT_1)
Attachment selectByAttachType(Attachment.BizType bizType, long bizId, Enum<?> attachType); Attachment selectByAttachType(Attachment.BizType bizType, long bizId, Enum<?> attachType);
List<Attachment> listByBizId(Attachment.BizType bizType, Long bizId, List<Enum<?>> attachTypes, Page page); List<Attachment> listByBizId(Attachment.BizType bizType, Long bizId, List<Enum<?>> attachTypes, Page<Attachment> page);
long countByBizId(Attachment.BizType bizType, Long bizId, List<Enum<?>> attachTypes); long countByBizId(Attachment.BizType bizType, Long bizId, List<Enum<?>> attachTypes);
List<Attachment> listByMd5s(Attachment.BizType bizType, Long bizId, List<Enum<?>> attachTypes, List<String> md5s); List<Attachment> listByMd5s(Attachment.BizType bizType, Long bizId, List<Enum<?>> attachTypes, List<String> md5s);
@Select("SELECT * FROM attachment WHERE `is_destroyed` = FALSE AND `destroy_at` < " + UNIX_TIME)
List<Attachment> selectNeedDestroy();
} }

View File

@ -22,7 +22,7 @@ public interface CommentMapper extends BaseMapper<Comment, Long> {
long countByPage(Page page); long countByPage(Page page);
@Override @Override
List<Comment> listByPage(Page page); List<Comment> selectByPage(Page page);
@Select("SELECT * FROM comment WHERE id = #{id}" + NOT_DELETE) @Select("SELECT * FROM comment WHERE id = #{id}" + NOT_DELETE)
Comment select(Long id); Comment select(Long id);

View File

@ -1,8 +1,6 @@
package com.imyeyu.api.modules.common.service; package com.imyeyu.api.modules.common.service;
import com.imyeyu.api.modules.common.entity.Attachment; 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.java.bean.timi.TimiException;
import com.imyeyu.spring.service.BaseService; import com.imyeyu.spring.service.BaseService;
import com.mongodb.client.gridfs.model.GridFSFile; import com.mongodb.client.gridfs.model.GridFSFile;
@ -22,27 +20,6 @@ public interface AttachmentService extends BaseService<Attachment, Long> {
Attachment createMedia(Attachment attachment); Attachment createMedia(Attachment attachment);
/**
*
*
* @param request
*/
@Deprecated
default void create(AttachmentRequest request) {
create((Attachment) request);
}
/**
* 创建媒体附件,同步创建缩略图
*
* @param request 附件请求
* @return 缩略图附件
*/
@Deprecated
default Attachment createMedia(AttachmentRequest request) throws TimiException {
return createMedia((Attachment) request);
}
void deleteMedia(Long thumbId) throws TimiException; void deleteMedia(Long thumbId) throws TimiException;
Attachment getByBizId(Attachment.BizType bizType, long bizId); Attachment getByBizId(Attachment.BizType bizType, long bizId);
@ -51,8 +28,6 @@ public interface AttachmentService extends BaseService<Attachment, Long> {
Attachment getByMongoId(String mongoId); Attachment getByMongoId(String mongoId);
AttachmentView viewByMongoId(String mongoId);
GridFSFile readByMongoId(String mongoId); GridFSFile readByMongoId(String mongoId);
InputStream getInputStreamByMongoId(String mongoId); InputStream getInputStreamByMongoId(String mongoId);
@ -81,7 +56,9 @@ public interface AttachmentService extends BaseService<Attachment, Long> {
*/ */
long countByBizId(Attachment.BizType bizType, Long bizId, Enum<?> ...attachTypes); long countByBizId(Attachment.BizType bizType, Long bizId, Enum<?> ...attachTypes);
List<Attachment> listByMd5s(Attachment.BizType bizType, Long bizId, List<Enum<?>> attachTypeList, List<String> md5s) throws TimiException; List<Attachment> listByMd5s(Attachment.BizType bizType, Long bizId, List<Enum<?>> attachTypeList, List<String> md5s);
void deleteByBizId(Attachment.BizType bizType, long bizId, Enum<?> ...attachTypes); void deleteByBizId(Attachment.BizType bizType, long bizId, Enum<?> ...attachTypes);
List<Attachment> listNeedDestroy();
} }

View File

@ -1,12 +1,8 @@
package com.imyeyu.api.modules.common.service; package com.imyeyu.api.modules.common.service;
import com.imyeyu.api.modules.common.bean.TempFileMetaData;
import com.imyeyu.api.modules.common.vo.TempFileResponse; import com.imyeyu.api.modules.common.vo.TempFileResponse;
import com.imyeyu.java.bean.timi.TimiException;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
import java.util.List; import java.util.List;
/** /**
@ -15,11 +11,5 @@ import java.util.List;
*/ */
public interface TempFileService { public interface TempFileService {
List<TempFileResponse> store(List<MultipartFile> files, Long ttl) throws TimiException; List<TempFileResponse> store(List<MultipartFile> files, Long ttl);
File get(String id) throws TimiException;
InputStream getInputStream(String id) throws TimiException;
TempFileMetaData metadata(String id) throws TimiException;
} }

View File

@ -1,6 +1,7 @@
package com.imyeyu.api.modules.common.service.implement; package com.imyeyu.api.modules.common.service.implement;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.imyeyu.api.config.dbsource.TimiServerDBConfig; import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
import com.imyeyu.api.modules.common.bean.MediaAttach; import com.imyeyu.api.modules.common.bean.MediaAttach;
import com.imyeyu.api.modules.common.bean.Metadata; import com.imyeyu.api.modules.common.bean.Metadata;
@ -8,13 +9,13 @@ import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.mapper.AttachmentMapper; import com.imyeyu.api.modules.common.mapper.AttachmentMapper;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.service.SettingService; import com.imyeyu.api.modules.common.service.SettingService;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentView;
import com.imyeyu.api.util.JavaCV; import com.imyeyu.api.util.JavaCV;
import com.imyeyu.io.IO; import com.imyeyu.io.IO;
import com.imyeyu.java.TimiJava; import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.network.Network; import com.imyeyu.network.Network;
import com.imyeyu.spring.TimiSpring;
import com.imyeyu.spring.mapper.BaseMapper; import com.imyeyu.spring.mapper.BaseMapper;
import com.imyeyu.spring.service.AbstractEntityService; import com.imyeyu.spring.service.AbstractEntityService;
import com.imyeyu.utils.Time; import com.imyeyu.utils.Time;
@ -24,7 +25,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails; import net.coobird.thumbnailator.Thumbnails;
import org.apache.tika.Tika; import org.apache.tika.Tika;
import org.springframework.beans.BeanUtils;
import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.data.mongodb.gridfs.GridFsTemplate;
@ -68,13 +68,11 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
@Override @Override
public void create(Attachment attachment) { public void create(Attachment attachment) {
TimiException.required(attachment.getBizType(), "not found attachment.bizType"); TimiException.required(attachment.getBizType(), "not found attachment.bizType");
TimiException.required(attachment.getBizId(), "not found attachment.bizId");
TimiException.required(attachment.getName(), "not found attachment.name"); TimiException.required(attachment.getName(), "not found attachment.name");
String mongoId = null; String mongoId = null;
try { try {
InputStream is = attachment.getInputStream(); InputStream is = attachment.getInputStream();
TimiException.required(is, "not found attachment.inputStream"); TimiException.required(is, "not found attachment.inputStream");
TimiException.requiredTrue(is.available() != 0, "empty attachment.inputStream");
StringBuilder mongoName = new StringBuilder(attachment.getBizType().toString()); StringBuilder mongoName = new StringBuilder(attachment.getBizType().toString());
if (TimiJava.isNotEmpty(attachment.getAttachType())) { if (TimiJava.isNotEmpty(attachment.getAttachType())) {
@ -88,12 +86,14 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
attachment.setSize(gridFSFile.getLength()); attachment.setSize(gridFSFile.getLength());
attachment.setMd5(IO.md5(gridFSBucket.openDownloadStream(gridFSFile.getObjectId()))); attachment.setMd5(IO.md5(gridFSBucket.openDownloadStream(gridFSFile.getObjectId())));
attachment.setMimeType(new Tika().detect(gridFSBucket.openDownloadStream(gridFSFile.getObjectId()))); attachment.setMimeType(new Tika().detect(gridFSBucket.openDownloadStream(gridFSFile.getObjectId())));
attachment.setUploaderIp(TimiSpring.getRequestIP());
attachment.setIsDestroyed(false);
if (attachment.getMimeType().startsWith("image")) { if (attachment.getMimeType().startsWith("image")) {
BufferedImage image = ImageIO.read(gridFSBucket.openDownloadStream(gridFSFile.getObjectId())); BufferedImage image = ImageIO.read(gridFSBucket.openDownloadStream(gridFSFile.getObjectId()));
Metadata.Image metadata = new Metadata.Image(); attachment.setMetadata(TimiJava.defaultIfNull(attachment.getMetadata(), new JsonObject()));
metadata.setWidth(image.getWidth()); JsonObject metadata = attachment.getMetadata();
metadata.setHeight(image.getHeight()); metadata.addProperty("width", image.getWidth());
attachment.setMetadata(gson.toJsonTree(metadata).getAsJsonObject()); metadata.addProperty("height", image.getHeight());
} }
mapper.insert(attachment); mapper.insert(attachment);
} catch (Exception e) { } catch (Exception e) {
@ -109,12 +109,17 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
@Override @Override
public void destroy(Long id) { public void destroy(Long id) {
try { try {
Attachment attachment = get(id); Attachment attach = mapper.selectRaw(id);
gridFsTemplate.delete(Query.query(Criteria.where("_id").is(attachment.getMongoId()))); GridFSFile file = readByMongoId(attach.getMongoId());
if (file != null) {
attachment.setDeletedAt(Time.now()); gridFsTemplate.delete(Query.query(Criteria.where("_id").is(attach.getMongoId())));
attachment.setDestroyAt(Time.now()); }
mapper.update(attachment); if (!attach.isDeleted()) {
attach.setDeletedAt(Time.now());
}
attach.setIsDestroyed(true);
attach.setDestroyAt(Time.now());
mapper.update(attach);
} catch (Exception e) { } catch (Exception e) {
log.error("delete mongo file error", e); log.error("delete mongo file error", e);
throw new TimiException(TimiCode.ERROR).msgKey("TODO delete mongo file error"); throw new TimiException(TimiCode.ERROR).msgKey("TODO delete mongo file error");
@ -130,17 +135,13 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
create(attachment); create(attachment);
// 生成缩略图 // 生成缩略图
InputStream mimeStream = getInputStreamByMongoId(attachment.getMongoId()); InputStream mimeStream = attachment.openInputStream();
String mimeType = new Tika().detect(mimeStream); String mimeType = new Tika().detect(mimeStream);
boolean isImage = false;
InputStream sourceStream = getInputStreamByMongoId(attachment.getMongoId()); InputStream sourceStream = attachment.openInputStream();
ByteArrayOutputStream thumbStream = new ByteArrayOutputStream(); ByteArrayOutputStream thumbStream = new ByteArrayOutputStream();
switch (mimeType) { switch (mimeType) {
case "image/png", "image/bmp", "image/jpeg" -> { case "image/png", "image/bmp", "image/jpeg" -> Thumbnails.of(sourceStream).width(256).keepAspectRatio(true).toOutputStream(thumbStream);
isImage = true;
Thumbnails.of(sourceStream).width(256).keepAspectRatio(true).toOutputStream(thumbStream);
}
case "video/mp4", "video/quicktime" -> { case "video/mp4", "video/quicktime" -> {
log.info("capturing thumbnail: {}", attachment.getName()); log.info("capturing thumbnail: {}", attachment.getName());
long start = Time.now(); long start = Time.now();
@ -155,18 +156,17 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
} }
} }
} }
MediaAttach.ExtData extData = new MediaAttach.ExtData(); Metadata.ThumbImage thumbMetadata = new Metadata.ThumbImage();
extData.setImage(isImage); thumbMetadata.setSourceId(attachment.getId());
extData.setVideo(!isImage); thumbMetadata.setSourceMongoId(attachment.getMongoId());
extData.setSourceId(attachment.getId()); thumbMetadata.setSourceMimeType(mimeType);
extData.setSourceMongoId(attachment.getMongoId());
Attachment thumbAttach = new Attachment(); Attachment thumbAttach = new Attachment();
thumbAttach.setName(Network.simpleURIFileName(attachment.getName()) + ".png"); thumbAttach.setName(Network.simpleURIFileName(attachment.getName()) + ".png");
thumbAttach.setBizType(attachment.getBizType()); thumbAttach.setBizType(attachment.getBizType());
thumbAttach.setBizId(attachment.getBizId()); thumbAttach.setBizId(attachment.getBizId());
thumbAttach.setAttachTypeValue(MediaAttach.Type.THUMB); thumbAttach.setAttachTypeValue(MediaAttach.Type.THUMB);
thumbAttach.setExt(gson.toJson(extData)); thumbAttach.setMetadata(gson.toJsonTree(thumbMetadata).getAsJsonObject());
thumbAttach.setInputStream(new ByteArrayInputStream(thumbStream.toByteArray())); thumbAttach.setInputStream(new ByteArrayInputStream(thumbStream.toByteArray()));
create(thumbAttach); create(thumbAttach);
@ -182,8 +182,8 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
public void deleteMedia(Long thumbId) throws TimiException { public void deleteMedia(Long thumbId) throws TimiException {
Attachment attachment = get(thumbId); Attachment attachment = get(thumbId);
delete(attachment.getId()); delete(attachment.getId());
MediaAttach.ExtData data = gson.fromJson(attachment.getExt(), MediaAttach.ExtData.class); Metadata.ThumbImage thumbMetadata = gson.fromJson(attachment.getMetadata(), Metadata.ThumbImage.class);
delete(data.getSourceId()); delete(thumbMetadata.getSourceId());
} }
@Override @Override
@ -201,22 +201,11 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
return mapper.selectByMongoId(mongoId); return mapper.selectByMongoId(mongoId);
} }
@Override
public AttachmentView viewByMongoId(String mongoId) {
Attachment attachment = getByMongoId(mongoId);
if (attachment == null) {
throw new TimiException(TimiCode.RESULT_NULL).msgKey("TODO not found attachment");
}
AttachmentView view = new AttachmentView();
BeanUtils.copyProperties(attachment, view);
return view;
}
@Override @Override
public GridFSFile readByMongoId(String mongoId) { public GridFSFile readByMongoId(String mongoId) {
Attachment view = mapper.selectByMongoId(mongoId); Attachment attach = mapper.selectByMongoId(mongoId);
TimiException.required(view, "not found attachment: %s".formatted(mongoId)); TimiException.required(attach, "not found attachment: %s".formatted(mongoId));
return gridFsTemplate.findOne(new Query(Criteria.where("_id").is(view.getMongoId()))); return gridFsTemplate.findOne(new Query(Criteria.where("_id").is(attach.getMongoId())));
} }
@Override @Override
@ -227,7 +216,7 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
@Override @Override
public byte[] readAllByMongoId(String mongoId) { public byte[] readAllByMongoId(String mongoId) {
try { try {
return IO.toBytes(getInputStreamByMongoId(mongoId)); return IO.toBytes(getByMongoId(mongoId).openInputStream());
} catch (IOException e) { } catch (IOException e) {
throw new TimiException(TimiCode.ERROR, "TODO 读取失败"); throw new TimiException(TimiCode.ERROR, "TODO 读取失败");
} }
@ -262,4 +251,9 @@ public class AttachmentServiceImplement extends AbstractEntityService<Attachment
} }
} }
} }
@Override
public List<Attachment> listNeedDestroy() {
return mapper.selectNeedDestroy();
}
} }

View File

@ -1,38 +1,27 @@
package com.imyeyu.api.modules.common.service.implement; package com.imyeyu.api.modules.common.service.implement;
import com.google.gson.Gson;
import com.imyeyu.api.modules.common.bean.SettingKey; import com.imyeyu.api.modules.common.bean.SettingKey;
import com.imyeyu.api.modules.common.bean.TempFileMetaData; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.service.SettingService; import com.imyeyu.api.modules.common.service.SettingService;
import com.imyeyu.api.modules.common.service.TempFileService; import com.imyeyu.api.modules.common.service.TempFileService;
import com.imyeyu.api.modules.common.vo.TempFileResponse; import com.imyeyu.api.modules.common.vo.TempFileResponse;
import com.imyeyu.io.IO;
import com.imyeyu.io.IOSize; import com.imyeyu.io.IOSize;
import com.imyeyu.java.TimiJava; import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.network.Network;
import com.imyeyu.spring.TimiSpring; import com.imyeyu.spring.TimiSpring;
import com.imyeyu.spring.bean.Page;
import com.imyeyu.utils.Time; import com.imyeyu.utils.Time;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; 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;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* @author 夜雨 * @author 夜雨
@ -43,61 +32,58 @@ import java.util.concurrent.ConcurrentHashMap;
@RequiredArgsConstructor @RequiredArgsConstructor
public class TempFileServiceImplement implements TempFileService { public class TempFileServiceImplement implements TempFileService {
private static final Long DEFAULT_TTL = Time.H * 6; private final Gson gson;
private static final Long MAX_TTL = Time.D * 3;
private static final Long LIMIT = IOSize.GB * 10;
private final SettingService settingService; private final SettingService settingService;
private final AttachmentService attachmentService; private final AttachmentService attachmentService;
private Path storagePath;
private final Map<String, TempFileMetaData> metadataMap = new ConcurrentHashMap<>();
private final Map<String, Long> usageMap = new ConcurrentHashMap<>();
@PostConstruct
public void init() throws IOException {
storagePath = Paths.get(settingService.getAsString(SettingKey.TEMP_FILE_PATH));
IO.destroy(storagePath.toFile());
Files.createDirectories(storagePath);
}
public List<TempFileResponse> store(List<MultipartFile> files, Long ttl) throws TimiException { public List<TempFileResponse> store(List<MultipartFile> files, Long ttl) throws TimiException {
ttl = TimiJava.defaultIfNull(ttl, DEFAULT_TTL); String ttlMinStr = settingService.getAsString(SettingKey.TEMP_FILE_TTL_MIN);
TimiException.requiredTrue(0 < ttl && ttl <= MAX_TTL, "ttl must be between 1ms and 3 days(259200000ms)"); String ttlMaxStr = settingService.getAsString(SettingKey.TEMP_FILE_TTL_MAX);
String limitStr = settingService.getAsString(SettingKey.TEMP_FILE_LIMIT);
long minTTL = Time.parseToMS(ttlMinStr);
long maxTTL = Time.parseToMS(ttlMaxStr);
long defaultTTL = Time.parseToMS(settingService.getAsString(SettingKey.TEMP_FILE_TTL_DEFAULT));
long limit = IOSize.parse(limitStr);
long residueTime = Time.parseToMS(settingService.getAsString(SettingKey.TEMP_FILE_RESIDUE_TIME));
ttl = TimiJava.defaultIfNull(ttl, defaultTTL);
TimiException.requiredTrue(minTTL < ttl && ttl <= maxTTL, String.format("ttl must be between %s and %s", ttlMinStr, ttlMaxStr));
long newFileSize = files.stream().mapToLong(MultipartFile::getSize).sum(); long newFileSize = files.stream().mapToLong(MultipartFile::getSize).sum();
long currentUsage = usageMap.getOrDefault(TimiSpring.getRequestIP(), 0L); {
TimiException.requiredTrue(currentUsage + newFileSize < LIMIT, "out of storage limit(10 GB)"); // 缓存池大小限制
Page<Attachment> page = new Page<>();
page.setIndex(0);
page.setSize(Long.MAX_VALUE);
{
Attachment example = new Attachment();
example.setUploaderIp(TimiSpring.getRequestIP());
page.setEqualsExample(example);
}
long currentUsage = attachmentService.page(page).getList().stream().mapToLong(Attachment::getSize).sum();
TimiException.requiredTrue(currentUsage + newFileSize < limit, "out of storage limit(%s)".formatted(limitStr));
}
try { try {
List<TempFileResponse> result = new ArrayList<>(); List<TempFileResponse> result = new ArrayList<>();
long deletedAt = Time.now() + ttl;
long destroyAt = deletedAt + residueTime;
for (int i = 0; i < files.size(); i++) { for (int i = 0; i < files.size(); i++) {
MultipartFile file = files.get(i); MultipartFile file = files.get(i);
String fileId = UUID.randomUUID().toString(); Attachment attach = new Attachment();
String fileName = fileId; attach.setBizType(Attachment.BizType.TEMP_FILE);
if (TimiJava.isNotEmpty(file.getOriginalFilename())) { attach.setName(file.getOriginalFilename());
fileName = fileId + "." + Network.uriFileExtension(file.getOriginalFilename()); attach.setDeletedAt(deletedAt);
} attach.setDestroyAt(destroyAt);
Path filePath = storagePath.resolve(fileName); attach.setInputStream(file.getInputStream());
Files.copy(file.getInputStream(), filePath); attachmentService.create(attach);
// 创建元数据
TempFileMetaData metadata = new TempFileMetaData();
metadata.setId(fileId);
metadata.setPath(filePath);
metadata.setName(fileName);
metadata.setOriginalName(file.getOriginalFilename());
metadata.setLastAccessAt(Time.now());
metadata.setTtl(ttl);
metadataMap.put(metadata.getId(), metadata);
TempFileResponse resp = new TempFileResponse(); TempFileResponse resp = new TempFileResponse();
resp.setId(metadata.getId()); resp.setId(attach.getMongoId());
resp.setExpireAt(metadata.getLastAccessAt() + ttl); resp.setExpireAt(deletedAt);
usageMap.put(TimiSpring.getRequestIP(), currentUsage + newFileSize);
result.add(resp); result.add(resp);
} }
return result; return result;
@ -107,42 +93,20 @@ public class TempFileServiceImplement implements TempFileService {
} }
} }
@Override
public File get(String id) throws TimiException {
TempFileMetaData metaData = metadataMap.get(id);
TimiException.required(metaData, "not found temp file");
metaData.setLastAccessAt(Time.now());
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);
}
@Scheduled(fixedRate = 3600000) @Scheduled(fixedRate = 3600000)
public void cleanup() { public void cleanup() {
List<String> expiredIds = metadataMap.values() // List<String> expiredIds = metadataMap.values()
.stream() // .stream()
.filter(metadata -> metadata.getLastAccessAt() + metadata.getTtl() < Time.now()) // .filter(metadata -> metadata.getLastAccessAt() + metadata.getTtl() < Time.now())
.map(TempFileMetaData::getId) // .map(TempFileMetaData::getId)
.toList(); // .toList();
for (int i = 0; i < expiredIds.size(); i++) { // for (int i = 0; i < expiredIds.size(); i++) {
TempFileMetaData removed = metadataMap.remove(expiredIds.get(i)); // TempFileMetaData removed = metadataMap.remove(expiredIds.get(i));
if (TimiJava.isNotEmpty(removed)) { // if (TimiJava.isNotEmpty(removed)) {
File file = removed.getPath().toFile(); // File file = removed.getPath().toFile();
IO.destroy(file); // IO.destroy(file);
usageMap.computeIfPresent(TimiSpring.getRequestIP(), (ip, usage) -> usage - file.length()); // usageMap.computeIfPresent(TimiSpring.getRequestIP(), (ip, usage) -> usage - file.length());
} // }
} // }
} }
} }

View File

@ -1,9 +1,5 @@
package com.imyeyu.api.modules.common.service.implement; package com.imyeyu.api.modules.common.service.implement;
import com.imyeyu.io.IOSize;
import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.api.config.dbsource.TimiServerDBConfig; import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.entity.User; import com.imyeyu.api.modules.common.entity.User;
@ -12,8 +8,11 @@ import com.imyeyu.api.modules.common.mapper.UserProfileMapper;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.service.UserProfileService; import com.imyeyu.api.modules.common.service.UserProfileService;
import com.imyeyu.api.modules.common.service.UserService; import com.imyeyu.api.modules.common.service.UserService;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest;
import com.imyeyu.api.modules.common.vo.user.UserRequest; import com.imyeyu.api.modules.common.vo.user.UserRequest;
import com.imyeyu.io.IOSize;
import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.spring.mapper.BaseMapper; import com.imyeyu.spring.mapper.BaseMapper;
import com.imyeyu.spring.service.AbstractEntityService; import com.imyeyu.spring.service.AbstractEntityService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -73,7 +72,7 @@ public class UserProfileServiceImplement extends AbstractEntityService<UserProfi
if (IOSize.MB < bytes.length) { if (IOSize.MB < bytes.length) {
throw new TimiException(TimiCode.ARG_BAD).msgKey("限制上传文件大小 1 MB"); throw new TimiException(TimiCode.ARG_BAD).msgKey("限制上传文件大小 1 MB");
} }
AttachmentRequest wrapperAttach = new AttachmentRequest(); Attachment wrapperAttach = new Attachment();
wrapperAttach.setName(request.getId() + ".png"); wrapperAttach.setName(request.getId() + ".png");
wrapperAttach.setBizType(Attachment.BizType.USER); wrapperAttach.setBizType(Attachment.BizType.USER);
wrapperAttach.setBizId(request.getId()); wrapperAttach.setBizId(request.getId());
@ -88,7 +87,7 @@ public class UserProfileServiceImplement extends AbstractEntityService<UserProfi
attachmentService.delete(dbAvatar.getId()); attachmentService.delete(dbAvatar.getId());
} }
MultipartFile avatar = request.getProfile().getAvatar(); MultipartFile avatar = request.getProfile().getAvatar();
AttachmentRequest avatarAttach = new AttachmentRequest(); Attachment avatarAttach = new Attachment();
avatarAttach.setName(request.getId() + ".png"); avatarAttach.setName(request.getId() + ".png");
avatarAttach.setBizType(Attachment.BizType.USER); avatarAttach.setBizType(Attachment.BizType.USER);
avatarAttach.setBizId(request.getId()); avatarAttach.setBizId(request.getId());

View File

@ -0,0 +1,49 @@
package com.imyeyu.api.modules.common.task;
import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.service.AttachmentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import java.util.List;
/**
* 附件清除定时任务。每天凌晨 1 点执行,清除已过期但未销毁的附件
*
* @author 夜雨
* @since 2026-01-05 12:37
*/
@Slf4j
@Configuration
@EnableScheduling
@RequiredArgsConstructor
public class AttachmentClearTask {
private final AttachmentService attachmentService;
@Scheduled(cron = "0 0 1 * * ?")
public void run() {
log.info("start clear expired attachments");
try {
List<Attachment> needDestroyList = attachmentService.listNeedDestroy();
if (needDestroyList.isEmpty()) {
log.info("nothing attachment need clear");
return;
}
for (Attachment attach : needDestroyList) {
try {
attachmentService.destroy(attach.getId());
log.info("clear attachment success: id[{}]", attach.getId());
} catch (Exception e) {
log.error("clear attachment error: id[{}]", attach.getId(), e);
}
}
log.info("end clear expired attachments");
} catch (Exception e) {
log.error("attachment clear task error", e);
}
}
}

View File

@ -1,18 +0,0 @@
package com.imyeyu.api.modules.common.vo.attachment;
import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.spring.annotation.table.Transient;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author 夜雨
* @since 2024-02-21 10:58
*/
@Data
@Transient
@Deprecated
@EqualsAndHashCode(callSuper = true)
public class AttachmentRequest extends Attachment {
}

View File

@ -1,15 +0,0 @@
package com.imyeyu.api.modules.common.vo.attachment;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.imyeyu.api.bean.MultilingualHandler;
import com.imyeyu.api.modules.common.entity.Attachment;
/**
* @author 夜雨
* @since 2024-02-21 10:55
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class AttachmentView extends Attachment implements MultilingualHandler {
}

View File

@ -1,59 +0,0 @@
package com.imyeyu.api.modules.journal.bean;
import lombok.Data;
import java.util.List;
/**
* @author 夜雨
* @since 2025-09-30 11:51
*/
@Data
public class Travel {
private Luggage luggage;
private List<Guide> guides;
/**
*
*
* @author 夜雨
* @since 2025-09-30 11:52
*/
@Data
public static class Luggage {
private List<Item> gao;
private List<Item> yu;
/**
*
*
* @author 夜雨
* @since 2025-09-30 11:52
*/
@Data
public static class Item {
private String name;
private boolean isTaken;
}
}
/**
*
*
* @author 夜雨
* @since 2025-09-30 11:54
*/
@Data
public static class Guide {
private String title;
private List<String> images;
}
}

View File

@ -7,7 +7,6 @@ import com.imyeyu.api.modules.common.bean.SettingKey;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.service.SettingService; import com.imyeyu.api.modules.common.service.SettingService;
import com.imyeyu.api.modules.journal.bean.Travel;
import com.imyeyu.api.modules.journal.entity.Journal; import com.imyeyu.api.modules.journal.entity.Journal;
import com.imyeyu.api.modules.journal.service.JournalService; import com.imyeyu.api.modules.journal.service.JournalService;
import com.imyeyu.api.modules.journal.vo.journal.ArchiveRequest; import com.imyeyu.api.modules.journal.vo.journal.ArchiveRequest;
@ -206,24 +205,6 @@ public class JournalController {
return journal + journalTravel; return journal + journalTravel;
} }
/**
*
*
* @return
*/
@RequestRateLimit
@GetMapping("/travel")
public Travel getTravel() {
return service.getTravel();
}
@AOPLog
@RequestRateLimit
@PostMapping("/travel/luggage/update")
public void updateTravel(@RequestBody Travel.Luggage luggage) {
service.updateTravelLuggage(luggage);
}
/** /**
* 创建瞬间(上传的临时文件持久化储存,微信限制单次上传数量) * 创建瞬间(上传的临时文件持久化储存,微信限制单次上传数量)
* *

View File

@ -1,6 +1,7 @@
package com.imyeyu.api.modules.journal.controller; package com.imyeyu.api.modules.journal.controller;
import com.imyeyu.api.bean.PreviewPage; import com.imyeyu.api.bean.PreviewPage;
import com.imyeyu.api.modules.common.bean.MediaAttach;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.journal.entity.TravelLocation; import com.imyeyu.api.modules.journal.entity.TravelLocation;
@ -105,6 +106,7 @@ public class TravelLocationController {
Attachment example = new Attachment(); Attachment example = new Attachment();
example.setBizType(Attachment.BizType.JOURNAL_TRAVEL); example.setBizType(Attachment.BizType.JOURNAL_TRAVEL);
example.setBizId(location.getId()); example.setBizId(location.getId());
example.setAttachTypeValue(MediaAttach.Type.THUMB);
attachPage.setEqualsExample(example); attachPage.setEqualsExample(example);
} }
attachPage.setIndex(0); attachPage.setIndex(0);

View File

@ -39,6 +39,9 @@ public class TravelLocation extends Entity {
/** 景点 */ /** 景点 */
ATTRACTION, ATTRACTION,
/** 商场 */
MALL,
/** 购物 */ /** 购物 */
SHOPPING, SHOPPING,

View File

@ -1,7 +1,6 @@
package com.imyeyu.api.modules.journal.service; package com.imyeyu.api.modules.journal.service;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.journal.bean.Travel;
import com.imyeyu.api.modules.journal.entity.Journal; import com.imyeyu.api.modules.journal.entity.Journal;
import com.imyeyu.api.modules.journal.vo.journal.ArchiveRequest; import com.imyeyu.api.modules.journal.vo.journal.ArchiveRequest;
import com.imyeyu.api.modules.journal.vo.journal.JournalRequest; import com.imyeyu.api.modules.journal.vo.journal.JournalRequest;
@ -39,8 +38,4 @@ public interface JournalService extends PageableService<Journal>, GettableServic
void deleteMoment(Long[] thumbIds) throws TimiException; void deleteMoment(Long[] thumbIds) throws TimiException;
void archiveMoment(ArchiveRequest request) throws TimiException; void archiveMoment(ArchiveRequest request) throws TimiException;
Travel getTravel() throws TimiException;
void updateTravelLuggage(Travel.Luggage luggage) throws TimiException;
} }

View File

@ -3,21 +3,17 @@ package com.imyeyu.api.modules.journal.service.implement;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.imyeyu.api.config.dbsource.TimiServerDBConfig; import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
import com.imyeyu.api.modules.common.bean.MediaAttach; import com.imyeyu.api.modules.common.bean.MediaAttach;
import com.imyeyu.api.modules.common.bean.SettingKey; import com.imyeyu.api.modules.common.bean.Metadata;
import com.imyeyu.api.modules.common.bean.TempFileMetaData;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.entity.Setting;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.service.SettingService; import com.imyeyu.api.modules.common.service.SettingService;
import com.imyeyu.api.modules.common.service.TempFileService; import com.imyeyu.api.modules.common.service.TempFileService;
import com.imyeyu.api.modules.journal.bean.Travel;
import com.imyeyu.api.modules.journal.entity.Journal; import com.imyeyu.api.modules.journal.entity.Journal;
import com.imyeyu.api.modules.journal.mapper.JournalMapper; import com.imyeyu.api.modules.journal.mapper.JournalMapper;
import com.imyeyu.api.modules.journal.service.JournalService; import com.imyeyu.api.modules.journal.service.JournalService;
import com.imyeyu.api.modules.journal.vo.journal.ArchiveRequest; import com.imyeyu.api.modules.journal.vo.journal.ArchiveRequest;
import com.imyeyu.api.modules.journal.vo.journal.JournalRequest; import com.imyeyu.api.modules.journal.vo.journal.JournalRequest;
import com.imyeyu.api.modules.journal.vo.journal.UpdateRequest; import com.imyeyu.api.modules.journal.vo.journal.UpdateRequest;
import com.imyeyu.io.IO;
import com.imyeyu.java.TimiJava; import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.java.bean.timi.TimiException;
@ -29,7 +25,6 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -71,14 +66,13 @@ public class JournalServiceImplement extends AbstractEntityService<Journal, Long
return; return;
} }
for (int i = 0; i < tempFileIds.length; i++) { for (int i = 0; i < tempFileIds.length; i++) {
TempFileMetaData metadata = tempFileService.metadata(tempFileIds[i]); Attachment tempFileAttach = attachmentService.getByMongoId(tempFileIds[i]);
File file = tempFileService.get(tempFileIds[i]);
Attachment sourceAttach = new Attachment(); Attachment sourceAttach = new Attachment();
sourceAttach.setName(metadata.getOriginalName()); sourceAttach.setName(tempFileAttach.getName());
sourceAttach.setBizType(Attachment.BizType.JOURNAL); sourceAttach.setBizType(Attachment.BizType.JOURNAL);
sourceAttach.setBizId(journal.getId()); sourceAttach.setBizId(journal.getId());
sourceAttach.setInputStream(IO.getInputStream(file)); sourceAttach.setInputStream(tempFileAttach.openInputStream());
attachmentService.createMedia(sourceAttach); attachmentService.createMedia(sourceAttach);
} }
} catch (Exception e) { } catch (Exception e) {
@ -107,13 +101,13 @@ public class JournalServiceImplement extends AbstractEntityService<Journal, Long
} }
// 新增 // 新增
for (String tempFileId : TimiJava.defaultIfNull(request.getTempFileIds(), new String[0])) { for (String tempFileId : TimiJava.defaultIfNull(request.getTempFileIds(), new String[0])) {
TempFileMetaData metadata = tempFileService.metadata(tempFileId); Attachment tempFileAttach = attachmentService.getByMongoId(tempFileId);
Attachment sourceAttach = new Attachment(); Attachment sourceAttach = new Attachment();
sourceAttach.setName(metadata.getOriginalName()); sourceAttach.setName(tempFileAttach.getName());
sourceAttach.setBizType(Attachment.BizType.JOURNAL); sourceAttach.setBizType(Attachment.BizType.JOURNAL);
sourceAttach.setBizId(journal.getId()); sourceAttach.setBizId(journal.getId());
sourceAttach.setInputStream(tempFileService.getInputStream(tempFileId)); sourceAttach.setInputStream(tempFileAttach.openInputStream());
attachmentService.createMedia(sourceAttach); attachmentService.createMedia(sourceAttach);
} }
} }
@ -150,16 +144,15 @@ public class JournalServiceImplement extends AbstractEntityService<Journal, Long
try { try {
List<Attachment> thumbResult = new ArrayList<>(); List<Attachment> thumbResult = new ArrayList<>();
for (int i = 0; i < tempFileIds.length; i++) { for (int i = 0; i < tempFileIds.length; i++) {
TempFileMetaData metadata = tempFileService.metadata(tempFileIds[i]); Attachment tempFileAttach = attachmentService.getByMongoId(tempFileIds[i]);
File file = tempFileService.get(tempFileIds[i]);
Attachment sourceAttach = new Attachment(); Attachment sourceAttach = new Attachment();
sourceAttach.setName(metadata.getOriginalName()); sourceAttach.setName(tempFileAttach.getName());
sourceAttach.setBizType(Attachment.BizType.JOURNAL_MOMENT); sourceAttach.setBizType(Attachment.BizType.JOURNAL_MOMENT);
sourceAttach.setBizId(0L); sourceAttach.setBizId(0L);
sourceAttach.setAttachTypeValue(MediaAttach.Type.SOURCE); sourceAttach.setAttachTypeValue(MediaAttach.Type.SOURCE);
sourceAttach.setSize(file.length()); sourceAttach.setSize(tempFileAttach.getSize());
sourceAttach.setInputStream(IO.getInputStream(file)); sourceAttach.setInputStream(tempFileAttach.openInputStream());
thumbResult.add(attachmentService.createMedia(sourceAttach)); thumbResult.add(attachmentService.createMedia(sourceAttach));
} }
return thumbResult; return thumbResult;
@ -199,8 +192,8 @@ public class JournalServiceImplement extends AbstractEntityService<Journal, Long
thumbAttach.setBizId(journal.getId()); thumbAttach.setBizId(journal.getId());
attachmentService.update(thumbAttach); attachmentService.update(thumbAttach);
MediaAttach.ExtData extData = gson.fromJson(thumbAttach.getExt(), MediaAttach.ExtData.class); Metadata.ThumbImage thumbMetadata = gson.fromJson(thumbAttach.getMetadata(), Metadata.ThumbImage.class);
Attachment sourceAttach = attachmentService.get(extData.getSourceId()); Attachment sourceAttach = attachmentService.get(thumbMetadata.getSourceId());
sourceAttach.setBizType(Attachment.BizType.JOURNAL); sourceAttach.setBizType(Attachment.BizType.JOURNAL);
sourceAttach.setBizId(journal.getId()); sourceAttach.setBizId(journal.getId());
attachmentService.update(sourceAttach); attachmentService.update(sourceAttach);
@ -210,19 +203,4 @@ public class JournalServiceImplement extends AbstractEntityService<Journal, Long
throw new TimiException(TimiCode.ERROR).msgKey("TODO archive journal error"); throw new TimiException(TimiCode.ERROR).msgKey("TODO archive journal error");
} }
} }
@Override
public Travel getTravel() throws TimiException {
return gson.fromJson(settingService.getAsJsonObject(SettingKey.JOURNAL_TRAVEL), Travel.class);
}
@Override
public void updateTravelLuggage(Travel.Luggage luggage) throws TimiException {
Travel dbTravel = getTravel();
dbTravel.setLuggage(luggage);
Setting setting = settingService.getByKey(SettingKey.JOURNAL_TRAVEL);
setting.setValue(gson.toJson(dbTravel));
settingService.update(setting);
settingService.clearCache(SettingKey.JOURNAL_TRAVEL);
}
} }

View File

@ -2,10 +2,8 @@ package com.imyeyu.api.modules.journal.service.implement;
import com.imyeyu.api.config.dbsource.TimiServerDBConfig; import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
import com.imyeyu.api.modules.common.bean.MediaAttach; import com.imyeyu.api.modules.common.bean.MediaAttach;
import com.imyeyu.api.modules.common.bean.TempFileMetaData;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.service.TempFileService;
import com.imyeyu.api.modules.journal.entity.TravelLocation; import com.imyeyu.api.modules.journal.entity.TravelLocation;
import com.imyeyu.api.modules.journal.mapper.TravelLocationMapper; import com.imyeyu.api.modules.journal.mapper.TravelLocationMapper;
import com.imyeyu.api.modules.journal.service.TravelLocationService; import com.imyeyu.api.modules.journal.service.TravelLocationService;
@ -36,7 +34,6 @@ import java.util.stream.Collectors;
public class TravelLocationServiceImplement extends AbstractEntityService<TravelLocation, Long> implements TravelLocationService { public class TravelLocationServiceImplement extends AbstractEntityService<TravelLocation, Long> implements TravelLocationService {
private final TravelService travelService; private final TravelService travelService;
private final TempFileService tempFileService;
private final AttachmentService attachmentService; private final AttachmentService attachmentService;
private final TravelLocationMapper mapper; private final TravelLocationMapper mapper;
@ -51,13 +48,13 @@ public class TravelLocationServiceImplement extends AbstractEntityService<Travel
public void create(TravelLocation travelLocation) { public void create(TravelLocation travelLocation) {
super.create(travelLocation); super.create(travelLocation);
for (String tempFileId : travelLocation.getTempFileIds()) { for (String tempFileId : travelLocation.getTempFileIds()) {
TempFileMetaData metadata = tempFileService.metadata(tempFileId); Attachment tempFileAttach = attachmentService.getByMongoId(tempFileId);
Attachment attach = new Attachment(); Attachment attach = new Attachment();
attach.setName(metadata.getOriginalName()); attach.setName(tempFileAttach.getName());
attach.setBizType(Attachment.BizType.JOURNAL_TRAVEL); attach.setBizType(Attachment.BizType.JOURNAL_TRAVEL);
attach.setBizId(travelLocation.getId()); attach.setBizId(travelLocation.getId());
attach.setInputStream(tempFileService.getInputStream(tempFileId)); attach.setInputStream(tempFileAttach.openInputStream());
attachmentService.createMedia(attach); attachmentService.createMedia(attach);
} }
// 更新操作时间以保证排序 // 更新操作时间以保证排序
@ -83,13 +80,13 @@ public class TravelLocationServiceImplement extends AbstractEntityService<Travel
} }
// 新增 // 新增
for (String tempFileId : TimiJava.defaultIfNull(travelLocation.getTempFileIds(), new String[0])) { for (String tempFileId : TimiJava.defaultIfNull(travelLocation.getTempFileIds(), new String[0])) {
TempFileMetaData metadata = tempFileService.metadata(tempFileId); Attachment tempFileAttach = attachmentService.getByMongoId(tempFileId);
Attachment attach = new Attachment(); Attachment attach = new Attachment();
attach.setName(metadata.getOriginalName()); attach.setName(tempFileAttach.getName());
attach.setBizType(Attachment.BizType.JOURNAL_TRAVEL); attach.setBizType(Attachment.BizType.JOURNAL_TRAVEL);
attach.setBizId(travelLocation.getId()); attach.setBizId(travelLocation.getId());
attach.setInputStream(tempFileService.getInputStream(tempFileId)); attach.setInputStream(tempFileAttach.openInputStream());
attachmentService.createMedia(attach); attachmentService.createMedia(attach);
} }
// 更新操作时间以保证排序 // 更新操作时间以保证排序

View File

@ -1,18 +1,17 @@
package com.imyeyu.api.modules.lyric.service.implement; package com.imyeyu.api.modules.lyric.service.implement;
import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.api.config.dbsource.TimiServerDBConfig; import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.entity.User; import com.imyeyu.api.modules.common.entity.User;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.service.UserService; import com.imyeyu.api.modules.common.service.UserService;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest;
import com.imyeyu.api.modules.lyric.entity.LyricCorrect; import com.imyeyu.api.modules.lyric.entity.LyricCorrect;
import com.imyeyu.api.modules.lyric.mapper.LyricCorrectMapper; import com.imyeyu.api.modules.lyric.mapper.LyricCorrectMapper;
import com.imyeyu.api.modules.lyric.service.LyricCorrectService; import com.imyeyu.api.modules.lyric.service.LyricCorrectService;
import com.imyeyu.api.modules.lyric.vo.LyricCorrectRequest; import com.imyeyu.api.modules.lyric.vo.LyricCorrectRequest;
import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.spring.TimiSpring; import com.imyeyu.spring.TimiSpring;
import com.imyeyu.spring.bean.Page; import com.imyeyu.spring.bean.Page;
import com.imyeyu.spring.bean.PageResult; import com.imyeyu.spring.bean.PageResult;
@ -76,7 +75,7 @@ public class LyricCorrectServiceImplement extends AbstractEntityService<LyricCor
create(correct); create(correct);
try { try {
MultipartFile file = request.getFile(); MultipartFile file = request.getFile();
AttachmentRequest attachment = new AttachmentRequest(); Attachment attachment = new Attachment();
attachment.setBizType(Attachment.BizType.LYRIC); attachment.setBizType(Attachment.BizType.LYRIC);
attachment.setBizId(correct.getId()); attachment.setBizId(correct.getId());
attachment.setName(correct.getId() + ".lrc"); attachment.setName(correct.getId() + ".lrc");

View File

@ -1,12 +1,11 @@
package com.imyeyu.api.modules.mirror; package com.imyeyu.api.modules.mirror;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import com.imyeyu.api.TimiServerAPI; import com.imyeyu.api.TimiServerAPI;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest;
import com.imyeyu.api.modules.mirror.entity.Mirror; import com.imyeyu.api.modules.mirror.entity.Mirror;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.util.List; import java.util.List;
@ -42,7 +41,7 @@ public abstract class AttachmentMirror extends AbstractMirror {
* @return 新增附件 * @return 新增附件
* @throws Exception 处理异常 * @throws Exception 处理异常
*/ */
protected abstract List<AttachmentRequest> diffAdd(List<Attachment> dbFiles) throws Exception; protected abstract List<Attachment> diffAdd(List<Attachment> dbFiles) throws Exception;
/** /**
* 差分移除附件 * 差分移除附件
@ -70,10 +69,10 @@ public abstract class AttachmentMirror extends AbstractMirror {
attachmentService.destroy(diffRemoveList.get(i).getId()); attachmentService.destroy(diffRemoveList.get(i).getId());
} }
List<AttachmentRequest> diffAddList = diffAdd(dbFiles); List<Attachment> diffAddList = diffAdd(dbFiles);
syncAdded = diffAddList.size(); syncAdded = diffAddList.size();
for (int i = 0; i < diffAddList.size(); i++) { for (int i = 0; i < diffAddList.size(); i++) {
AttachmentRequest request = diffAddList.get(i); Attachment request = diffAddList.get(i);
request.setBizType(Attachment.BizType.MIRROR); request.setBizType(Attachment.BizType.MIRROR);
request.setBizId(mirror.getId()); request.setBizId(mirror.getId());
attachmentService.create(request); attachmentService.create(request);

View File

@ -3,7 +3,6 @@ package com.imyeyu.api.modules.mirror;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest;
import com.imyeyu.api.modules.mirror.bean.AttachType; import com.imyeyu.api.modules.mirror.bean.AttachType;
import com.imyeyu.api.modules.mirror.data.FabricAPI; import com.imyeyu.api.modules.mirror.data.FabricAPI;
import com.imyeyu.api.modules.mirror.entity.Mirror; import com.imyeyu.api.modules.mirror.entity.Mirror;
@ -106,10 +105,10 @@ public class FabricAPIMirror extends AttachmentMirror {
} }
@Override @Override
protected List<AttachmentRequest> diffAdd(List<Attachment> dbFiles) throws Exception { protected List<Attachment> diffAdd(List<Attachment> dbFiles) throws Exception {
Set<String> dbNameSet = dbFiles.stream().map(Attachment::getName).collect(Collectors.toSet()); Set<String> dbNameSet = dbFiles.stream().map(Attachment::getName).collect(Collectors.toSet());
List<AttachmentRequest> result = new ArrayList<>(); List<Attachment> result = new ArrayList<>();
for (Map.Entry<String, String> item : versionMap.entrySet()) { for (Map.Entry<String, String> item : versionMap.entrySet()) {
String version = "%s+%s".formatted(item.getValue(), item.getKey()); String version = "%s+%s".formatted(item.getValue(), item.getKey());
String name = "fabric-api-%s.jar".formatted(version); String name = "fabric-api-%s.jar".formatted(version);
@ -119,7 +118,7 @@ public class FabricAPIMirror extends AttachmentMirror {
byte[] bytes = Request.get(url).viaProxy(proxy).execute().returnContent().asBytes(); byte[] bytes = Request.get(url).viaProxy(proxy).execute().returnContent().asBytes();
AttachmentRequest attachment = new AttachmentRequest(); Attachment attachment = new Attachment();
attachment.setAttachTypeValue(AttachType.FABRIC_API); attachment.setAttachTypeValue(AttachType.FABRIC_API);
attachment.setName(name); attachment.setName(name);
attachment.setSize((long) bytes.length); attachment.setSize((long) bytes.length);

View File

@ -3,7 +3,6 @@ package com.imyeyu.api.modules.mirror;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest;
import com.imyeyu.api.modules.mirror.bean.AttachType; import com.imyeyu.api.modules.mirror.bean.AttachType;
import com.imyeyu.api.modules.mirror.data.OpenJDK; import com.imyeyu.api.modules.mirror.data.OpenJDK;
import com.imyeyu.api.modules.mirror.entity.Mirror; import com.imyeyu.api.modules.mirror.entity.Mirror;
@ -70,11 +69,11 @@ public class OpenJDKMirror extends AttachmentMirror {
} }
@Override @Override
protected List<AttachmentRequest> diffAdd(List<Attachment> dbFiles) throws Exception { protected List<Attachment> diffAdd(List<Attachment> dbFiles) throws Exception {
Map<String, OpenJDK> githubNameMap = githubMirrorResult.stream().collect(Collectors.toMap(OpenJDK::getName, item -> item)); Map<String, OpenJDK> githubNameMap = githubMirrorResult.stream().collect(Collectors.toMap(OpenJDK::getName, item -> item));
Set<String> dbNameSet = dbFiles.stream().map(Attachment::getName).collect(Collectors.toSet()); Set<String> dbNameSet = dbFiles.stream().map(Attachment::getName).collect(Collectors.toSet());
List<AttachmentRequest> result = new ArrayList<>(); List<Attachment> result = new ArrayList<>();
for (Map.Entry<String, OpenJDK> item : githubNameMap.entrySet()) { for (Map.Entry<String, OpenJDK> item : githubNameMap.entrySet()) {
if (!dbNameSet.contains(item.getKey())) { if (!dbNameSet.contains(item.getKey())) {
String url = item.getValue().getData(); String url = item.getValue().getData();
@ -82,7 +81,7 @@ public class OpenJDKMirror extends AttachmentMirror {
byte[] bytes = Request.get(url).viaProxy(proxy).execute().returnContent().asBytes(); byte[] bytes = Request.get(url).viaProxy(proxy).execute().returnContent().asBytes();
AttachmentRequest attachment = new AttachmentRequest(); Attachment attachment = new Attachment();
attachment.setAttachTypeValue(AttachType.OPEN_JDK); attachment.setAttachTypeValue(AttachType.OPEN_JDK);
attachment.setName(item.getKey()); attachment.setName(item.getKey());
attachment.setSize((long) bytes.length); attachment.setSize((long) bytes.length);

View File

@ -1,7 +1,7 @@
package com.imyeyu.api.modules.system.controller; package com.imyeyu.api.modules.system.controller;
import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.common.service.AttachmentService;
import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest;
import com.imyeyu.api.modules.system.bean.ServerStatus; import com.imyeyu.api.modules.system.bean.ServerStatus;
import com.imyeyu.api.modules.system.service.SystemService; import com.imyeyu.api.modules.system.service.SystemService;
import com.imyeyu.api.modules.system.vo.TempAttachRequest; import com.imyeyu.api.modules.system.vo.TempAttachRequest;
@ -119,7 +119,7 @@ public class SystemController {
for (MultipartFile file : request.getFile()) { for (MultipartFile file : request.getFile()) {
byte[] bytes = IO.toBytes(file.getInputStream()); byte[] bytes = IO.toBytes(file.getInputStream());
AttachmentRequest attach = new AttachmentRequest(); Attachment attach = new Attachment();
attach.setName(file.getOriginalFilename()); attach.setName(file.getOriginalFilename());
attach.setBizType(request.getBizType()); attach.setBizType(request.getBizType());
attach.setBizId(request.getBizId()); attach.setBizId(request.getBizId());

View File

@ -24,7 +24,7 @@
<select id="countByPage" resultType="long"> <select id="countByPage" resultType="long">
SELECT COUNT(1) <include refid="normalCondition" /> SELECT COUNT(1) <include refid="normalCondition" />
</select> </select>
<select id="listByPage" resultType="com.imyeyu.api.modules.blog.entity.Article"> <select id="selectByPage" resultType="com.imyeyu.api.modules.blog.entity.Article">
SELECT SELECT
<include refid="listColumn" /> <include refid="listColumn" />
<include refid="normalCondition" /> <include refid="normalCondition" />

View File

@ -3,7 +3,7 @@
<mapper namespace="com.imyeyu.api.modules.common.mapper.CommentMapper"> <mapper namespace="com.imyeyu.api.modules.common.mapper.CommentMapper">
<sql id="table">comment</sql> <sql id="table">comment</sql>
<!-- 主评论 --> <!-- 主评论 -->
<select id="list" resultMap="listResult"> <select id="selectByPage" resultMap="selectResult">
SELECT SELECT
-- 主评论 -- 主评论
comment.id, comment.id,
@ -77,7 +77,7 @@
ON ON
reply_count.id = comment.id reply_count.id = comment.id
</select> </select>
<resultMap id="listResult" type="com.imyeyu.api.modules.common.vo.comment.CommentView"> <resultMap id="selectResult" type="com.imyeyu.api.modules.common.vo.comment.CommentView">
<id property="id" column="id" /> <id property="id" column="id" />
<result property="userId" column="user_id" /> <result property="userId" column="user_id" />
<result property="nick" column="nick" /> <result property="nick" column="nick" />
@ -96,7 +96,7 @@
<result property="createdAt" column="reply_created_at" /> <result property="createdAt" column="reply_created_at" />
</collection> </collection>
</resultMap> </resultMap>
<select id="countAll" resultType="long"> <select id="countByPage" resultType="long">
SELECT SELECT
SUM(result.total_comment + result.total_reply) SUM(result.total_comment + result.total_reply)
FROM ( FROM (

View File

@ -31,7 +31,7 @@
<resultMap id="listByRepositoryIdResult" type="com.imyeyu.api.modules.git.vo.release.ReleaseView" autoMapping="true"> <resultMap id="listByRepositoryIdResult" type="com.imyeyu.api.modules.git.vo.release.ReleaseView" autoMapping="true">
<id property="id" column="id" /> <id property="id" column="id" />
<!-- 关联附件 --> <!-- 关联附件 -->
<collection property="attachmentList" ofType="com.imyeyu.api.modules.common.vo.attachment.AttachmentView"> <collection property="attachmentList" ofType="com.imyeyu.api.modules.common.entity.Attachment">
<id property="id" column="attachmentId" /> <id property="id" column="attachmentId" />
<result property="bizType" column="biz_type" /> <result property="bizType" column="biz_type" />
<result property="bizId" column="biz_id" /> <result property="bizId" column="biz_id" />