From fd71f330d28d4e5b7e4d04863625a6be89f7b64c Mon Sep 17 00:00:00 2001 From: Timi Date: Thu, 6 Nov 2025 14:50:28 +0800 Subject: [PATCH] add Journal module --- .../api/bean/wechat/InitCodeResponse.java | 15 ++ .../java/com/imyeyu/api/config/WebConfig.java | 3 + .../config/dbsource/TimiServerDBConfig.java | 2 + .../api/modules/journal/bean/Travel.java | 59 +++++ .../journal/controller/JournalController.java | 167 +++++++++++++ .../api/modules/journal/entity/Journal.java | 41 ++++ .../modules/journal/mapper/JournalMapper.java | 23 ++ .../journal/service/JournalService.java | 43 ++++ .../implement/JournalServiceImplement.java | 230 ++++++++++++++++++ .../journal/util/JournalAPIInterceptor.java | 47 ++++ .../api/modules/journal/vo/AppendRequest.java | 15 ++ .../modules/journal/vo/ArchiveRequest.java | 16 ++ .../api/modules/journal/vo/JournalPage.java | 17 ++ .../modules/journal/vo/JournalRequest.java | 18 ++ .../modules/journal/vo/JournalResponse.java | 19 ++ 15 files changed, 715 insertions(+) create mode 100644 src/main/java/com/imyeyu/api/bean/wechat/InitCodeResponse.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/bean/Travel.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/controller/JournalController.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/entity/Journal.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/mapper/JournalMapper.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/service/JournalService.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/service/implement/JournalServiceImplement.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/util/JournalAPIInterceptor.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/vo/AppendRequest.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/vo/ArchiveRequest.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/vo/JournalPage.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/vo/JournalRequest.java create mode 100644 src/main/java/com/imyeyu/api/modules/journal/vo/JournalResponse.java diff --git a/src/main/java/com/imyeyu/api/bean/wechat/InitCodeResponse.java b/src/main/java/com/imyeyu/api/bean/wechat/InitCodeResponse.java new file mode 100644 index 0000000..c2fce5e --- /dev/null +++ b/src/main/java/com/imyeyu/api/bean/wechat/InitCodeResponse.java @@ -0,0 +1,15 @@ +package com.imyeyu.api.bean.wechat; + +import lombok.Data; + +/** + * @author 夜雨 + * @since 2025-09-27 11:33 + */ +@Data +public class InitCodeResponse { + + private String session_key; + + private String openid; +} \ No newline at end of file diff --git a/src/main/java/com/imyeyu/api/config/WebConfig.java b/src/main/java/com/imyeyu/api/config/WebConfig.java index c77efee..0fcf267 100644 --- a/src/main/java/com/imyeyu/api/config/WebConfig.java +++ b/src/main/java/com/imyeyu/api/config/WebConfig.java @@ -7,6 +7,7 @@ import com.imyeyu.api.annotation.RequiredTokenInterceptor; import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.vo.user.UserProfileView; import com.imyeyu.api.modules.common.vo.user.UserView; +import com.imyeyu.api.modules.journal.util.JournalAPIInterceptor; import com.imyeyu.api.modules.minecraft.annotation.RequiredFMCServerTokenInterceptor; import com.imyeyu.api.modules.minecraft.entity.MinecraftPlayer; import com.imyeyu.api.modules.mirror.vo.MirrorView; @@ -41,6 +42,7 @@ public class WebConfig implements WebMvcConfigurer { private final SystemAPIInterceptor systemAPIInterceptor; private final GsonSerializerAdapter gsonSerializerAdapter; + private final JournalAPIInterceptor journalAPIInterceptor; private final RequiredTokenInterceptor requiredTokenInterceptor; private final EnableSettingInterceptor enableSettingInterceptor; private final RequestSingleParamResolver requestSingleParamResolver; @@ -55,6 +57,7 @@ public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(systemAPIInterceptor).addPathPatterns(SystemAPIInterceptor.PATH); + registry.addInterceptor(journalAPIInterceptor).addPathPatterns(JournalAPIInterceptor.PATH); registry.addInterceptor(requiredFMCServerTokenInterceptor).addPathPatterns("/fmc/server/**"); registry.addInterceptor(requiredTokenInterceptor).addPathPatterns("/**"); registry.addInterceptor(enableSettingInterceptor).addPathPatterns("/**"); diff --git a/src/main/java/com/imyeyu/api/config/dbsource/TimiServerDBConfig.java b/src/main/java/com/imyeyu/api/config/dbsource/TimiServerDBConfig.java index 89348c1..b451348 100644 --- a/src/main/java/com/imyeyu/api/config/dbsource/TimiServerDBConfig.java +++ b/src/main/java/com/imyeyu/api/config/dbsource/TimiServerDBConfig.java @@ -38,6 +38,7 @@ import java.util.List; "com.imyeyu.api.modules.mirror.mapper", "com.imyeyu.api.modules.system.mapper", "com.imyeyu.api.modules.common.mapper", + "com.imyeyu.api.modules.journal.mapper", "com.imyeyu.api.modules.minecraft.mapper" }, sqlSessionFactoryRef = "timiServerSqlSessionFactory") public class TimiServerDBConfig { @@ -93,6 +94,7 @@ public class TimiServerDBConfig { "com.imyeyu.api.modules.mirror.entity", "com.imyeyu.api.modules.system.entity", "com.imyeyu.api.modules.common.entity", + "com.imyeyu.api.modules.journal.entity", "com.imyeyu.api.modules.minecraft.entity" }; String[] typeHandlers = { diff --git a/src/main/java/com/imyeyu/api/modules/journal/bean/Travel.java b/src/main/java/com/imyeyu/api/modules/journal/bean/Travel.java new file mode 100644 index 0000000..d92ba90 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/bean/Travel.java @@ -0,0 +1,59 @@ +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 guides; + + /** + * + * + * @author 夜雨 + * @since 2025-09-30 11:52 + */ + @Data + public static class Luggage { + + private List gao; + + private List 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 images; + } +} diff --git a/src/main/java/com/imyeyu/api/modules/journal/controller/JournalController.java b/src/main/java/com/imyeyu/api/modules/journal/controller/JournalController.java new file mode 100644 index 0000000..6d9081b --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/controller/JournalController.java @@ -0,0 +1,167 @@ +package com.imyeyu.api.modules.journal.controller; + +import com.google.gson.Gson; +import com.imyeyu.api.bean.wechat.InitCodeResponse; +import com.imyeyu.api.modules.common.bean.MediaAttach; +import com.imyeyu.api.modules.common.bean.SettingKey; +import com.imyeyu.api.modules.common.entity.Attachment; +import com.imyeyu.api.modules.common.service.AttachmentService; +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.service.JournalService; +import com.imyeyu.api.modules.journal.vo.AppendRequest; +import com.imyeyu.api.modules.journal.vo.ArchiveRequest; +import com.imyeyu.api.modules.journal.vo.JournalPage; +import com.imyeyu.api.modules.journal.vo.JournalRequest; +import com.imyeyu.api.modules.journal.vo.JournalResponse; +import com.imyeyu.java.bean.timi.TimiCode; +import com.imyeyu.java.bean.timi.TimiException; +import com.imyeyu.network.ArgMap; +import com.imyeyu.network.GsonRequest; +import com.imyeyu.spring.annotation.AOPLog; +import com.imyeyu.spring.annotation.RequestRateLimit; +import com.imyeyu.spring.annotation.RequestSingleParam; +import com.imyeyu.spring.bean.PageResult; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @author 夜雨 + * @since 2025-09-26 15:55 + */ +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/journal") +public class JournalController { + + private final Gson gson; + private final JournalService service; + private final SettingService settingService; + private final AttachmentService attachmentService; + + @AOPLog + @RequestRateLimit + @PostMapping("/openid") + public String initOpenId(@RequestSingleParam String code) { + try { + ArgMap args = new ArgMap<>(); + args.put("appid", settingService.getAsString(SettingKey.JOURNAL_APP_ID)); + args.put("secret", settingService.getAsString(SettingKey.JOURNAL_APP_SECRET)); + args.put("js_code", code); + args.put("grant_type", "authorization_code"); + InitCodeResponse resp = GsonRequest.get(args.toURL("https://api.weixin.qq.com/sns/jscode2session")).resultAs(InitCodeResponse.class); + return resp.getOpenid(); + } catch (Exception e) { + log.error("init WeChat openId error", e); + throw new TimiException(TimiCode.ERROR, "init openId error", e); + } + } + + @AOPLog + @RequestRateLimit + @PostMapping("/create") + public void create(@RequestBody JournalRequest request) { + service.create(request); + } + + @PostMapping("/append") + public void append(@RequestBody AppendRequest request) { + service.appendItems(request); + } + + @AOPLog + @PostMapping("/delete") + public void delete(@RequestBody Long thumbId) { + attachmentService.deleteMedia(thumbId); + } + + @AOPLog + @RequestRateLimit + @RequestMapping("/list") + public PageResult list(@RequestBody JournalPage page) { + PageResult pageResult = service.page(page); + + PageResult result = new PageResult<>(); + result.setTotal(pageResult.getTotal()); + result.setList(pageResult.getList().stream().map(item -> { + JournalResponse resp = new JournalResponse(); + resp.setItems(attachmentService.listByBizId(Attachment.BizType.JOURNAL, item.getId())); + BeanUtils.copyProperties(item, resp); + return resp; + }).toList()); + return result; + } + + @AOPLog + @RequestRateLimit + @GetMapping("/list/date") + public Long[] listDate() { + return service.listDate(); + } + + @RequestRateLimit + @GetMapping("/total") + public long total() { + long journal = attachmentService.countByBizId(Attachment.BizType.JOURNAL, null, MediaAttach.Type.SOURCE); + long journalTravel = attachmentService.countByBizId(Attachment.BizType.JOURNAL_TRAVEL, null, MediaAttach.Type.SOURCE); + return journal + journalTravel; + } + + @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); + } + + @AOPLog + @RequestRateLimit + @PostMapping("/moment/create") + public List createMoment(@RequestBody String[] tempFileIds) { + return service.createMoment(tempFileIds); + } + + @AOPLog + @RequestRateLimit + @PostMapping("/moment/list") + public List listMoment() { + return service.listMoment(); + } + + @AOPLog + @RequestRateLimit + @PostMapping("/moment/filter") + public String[] filterExistMoment(@RequestBody String[] md5s) { + return service.filterExistMoment(md5s); + } + + @AOPLog + @RequestRateLimit + @PostMapping("/moment/delete") + public void deleteMoment(@RequestBody Long[] thumbIds) { + service.deleteMoment(thumbIds); + } + + @AOPLog + @RequestRateLimit + @PostMapping("/moment/archive") + public void archiveMoment(@RequestBody ArchiveRequest request) { + service.archiveMoment(request); + } +} diff --git a/src/main/java/com/imyeyu/api/modules/journal/entity/Journal.java b/src/main/java/com/imyeyu/api/modules/journal/entity/Journal.java new file mode 100644 index 0000000..9f2eba4 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/entity/Journal.java @@ -0,0 +1,41 @@ +package com.imyeyu.api.modules.journal.entity; + +import com.imyeyu.spring.entity.Entity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author 夜雨 + * @since 2025-09-26 15:48 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class Journal extends Entity { + + /** + * + * + * @author 夜雨 + * @since 2025-10-09 18:44 + */ + public enum Type { + + NORMAL, + + PORTFOLIO + } + + private Type type; + + private String idea; + + private Double lat; + + private Double lng; + + private String location; + + private String weather; + + private String pusher; +} diff --git a/src/main/java/com/imyeyu/api/modules/journal/mapper/JournalMapper.java b/src/main/java/com/imyeyu/api/modules/journal/mapper/JournalMapper.java new file mode 100644 index 0000000..f605a5c --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/mapper/JournalMapper.java @@ -0,0 +1,23 @@ +package com.imyeyu.api.modules.journal.mapper; + +import com.imyeyu.api.modules.journal.entity.Journal; +import com.imyeyu.spring.mapper.BaseMapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * @author 夜雨 + * @since 2025-09-26 15:54 + */ +public interface JournalMapper extends BaseMapper { + + @Select("SELECT COUNT(1) FROM `journal` WHERE `type` = #{type}") + long countByType(Journal.Type type); + + @Select("SELECT * FROM `journal` WHERE `type` = #{type} AND `deleted_at` IS NULL ORDER BY `created_at` DESC LIMIT #{offset}, #{limit}") + List listByType(Journal.Type type, long offset, int limit); + + @Select("SELECT created_at FROM `journal` WHERE `deleted_at` IS NULL") + Long[] listDate(); +} diff --git a/src/main/java/com/imyeyu/api/modules/journal/service/JournalService.java b/src/main/java/com/imyeyu/api/modules/journal/service/JournalService.java new file mode 100644 index 0000000..e9a4ad3 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/service/JournalService.java @@ -0,0 +1,43 @@ +package com.imyeyu.api.modules.journal.service; + +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.vo.AppendRequest; +import com.imyeyu.api.modules.journal.vo.ArchiveRequest; +import com.imyeyu.api.modules.journal.vo.JournalPage; +import com.imyeyu.api.modules.journal.vo.JournalRequest; +import com.imyeyu.java.bean.timi.TimiException; +import com.imyeyu.spring.bean.PageResult; +import com.imyeyu.spring.service.DeletableService; + +import java.util.List; + +/** + * @author 夜雨 + * @since 2025-09-26 15:53 + */ +public interface JournalService extends DeletableService { + + PageResult page(JournalPage page) throws TimiException; + + Long[] listDate() throws TimiException; + + void create(JournalRequest request) throws TimiException; + + void appendItems(AppendRequest request) throws TimiException; + + String[] filterExistMoment(String[] md5s) throws TimiException; + + List createMoment(String[] tempFileIds) throws TimiException; + + List listMoment() throws TimiException; + + void deleteMoment(Long[] thumbIds) throws TimiException; + + void archiveMoment(ArchiveRequest request) throws TimiException; + + Travel getTravel() throws TimiException; + + void updateTravelLuggage(Travel.Luggage luggage) throws TimiException; +} diff --git a/src/main/java/com/imyeyu/api/modules/journal/service/implement/JournalServiceImplement.java b/src/main/java/com/imyeyu/api/modules/journal/service/implement/JournalServiceImplement.java new file mode 100644 index 0000000..28aa03a --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/service/implement/JournalServiceImplement.java @@ -0,0 +1,230 @@ +package com.imyeyu.api.modules.journal.service.implement; + +import com.google.gson.Gson; +import com.imyeyu.api.config.dbsource.TimiServerDBConfig; +import com.imyeyu.api.modules.common.bean.MediaAttach; +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.Setting; +import com.imyeyu.api.modules.common.service.AttachmentService; +import com.imyeyu.api.modules.common.service.SettingService; +import com.imyeyu.api.modules.common.service.TempFileService; +import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest; +import com.imyeyu.api.modules.journal.bean.Travel; +import com.imyeyu.api.modules.journal.entity.Journal; +import com.imyeyu.api.modules.journal.mapper.JournalMapper; +import com.imyeyu.api.modules.journal.service.JournalService; +import com.imyeyu.api.modules.journal.vo.AppendRequest; +import com.imyeyu.api.modules.journal.vo.ArchiveRequest; +import com.imyeyu.api.modules.journal.vo.JournalPage; +import com.imyeyu.api.modules.journal.vo.JournalRequest; +import com.imyeyu.io.IO; +import com.imyeyu.java.TimiJava; +import com.imyeyu.java.bean.timi.TimiCode; +import com.imyeyu.java.bean.timi.TimiException; +import com.imyeyu.spring.bean.Page; +import com.imyeyu.spring.bean.PageResult; +import com.imyeyu.spring.mapper.BaseMapper; +import com.imyeyu.spring.service.AbstractEntityService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author 夜雨 + * @since 2025-09-26 15:54 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class JournalServiceImplement extends AbstractEntityService implements JournalService { + + private final Gson gson; + + private final SettingService settingService; + private final TempFileService tempFileService; + private final AttachmentService attachmentService; + + private final JournalMapper mapper; + + @Override + protected BaseMapper mapper() { + return mapper; + } + + @Override + public PageResult page(JournalPage page) { + PageResult result = new PageResult<>(); + result.setTotal(mapper.countByType(page.getType())); + result.setList(mapper.listByType(page.getType(), page.getOffset(), page.getLimit())); + return result; + } + + @Override + public Long[] listDate() throws TimiException { + return mapper.listDate(); + } + + @Transactional(TimiServerDBConfig.ROLLBACKER) + @Override + public void create(JournalRequest request) throws TimiException { + try { + Journal journal = new Journal(); + BeanUtils.copyProperties(request, journal); + super.create(journal); + + String[] tempFileIds = request.getTempFileIds(); + if (TimiJava.isEmpty(tempFileIds)) { + return; + } + for (int i = 0; i < tempFileIds.length; i++) { + TempFileMetaData metadata = tempFileService.metadata(tempFileIds[i]); + File file = tempFileService.get(tempFileIds[i]); + + AttachmentRequest sourceAttach = new AttachmentRequest(); + sourceAttach.setName(metadata.getOriginalName()); + sourceAttach.setBizType(Attachment.BizType.JOURNAL); + sourceAttach.setBizId(journal.getId()); + sourceAttach.setInputStream(IO.getInputStream(file)); + attachmentService.createMedia(sourceAttach); + } + } catch (Exception e) { + log.error("create journal error", e); + throw new TimiException(TimiCode.ERROR).msgKey("TODO create journal error"); + } + } + + @Override + public void appendItems(AppendRequest request) throws TimiException { + TimiException.required(request.getTempFileIds(), "not found or empty tempFileIds"); + try { + Journal journal = get(request.getId()); + + String[] tempFileIds = request.getTempFileIds(); + for (int i = 0; i < tempFileIds.length; i++) { + TempFileMetaData metadata = tempFileService.metadata(tempFileIds[i]); + File file = tempFileService.get(tempFileIds[i]); + + AttachmentRequest sourceAttach = new AttachmentRequest(); + sourceAttach.setName(metadata.getOriginalName()); + sourceAttach.setBizType(Attachment.BizType.JOURNAL); + sourceAttach.setBizId(journal.getId()); + sourceAttach.setInputStream(IO.getInputStream(file)); + attachmentService.createMedia(sourceAttach); + } + } catch (Exception e) { + log.error("create journal error", e); + throw new TimiException(TimiCode.ERROR).msgKey("TODO create journal error"); + } + } + + @Override + public String[] filterExistMoment(String[] md5s) throws TimiException { + if (TimiJava.isEmpty(md5s)) { + return null; + } + Set dbMD5 = attachmentService.listByMd5s(Attachment.BizType.JOURNAL_MOMENT, null, List.of(MediaAttach.Type.SOURCE), Arrays.asList(md5s)) + .stream() + .map(Attachment::getMd5) + .collect(Collectors.toSet()); + return Arrays.stream(md5s).filter(md5 -> !dbMD5.contains(md5)).toArray(String[]::new); + } + + @Override + public List createMoment(String[] tempFileIds) throws TimiException { + if (TimiJava.isEmpty(tempFileIds)) { + return null; + } + try { + List thumbResult = new ArrayList<>(); + for (int i = 0; i < tempFileIds.length; i++) { + TempFileMetaData metadata = tempFileService.metadata(tempFileIds[i]); + File file = tempFileService.get(tempFileIds[i]); + + AttachmentRequest sourceAttach = new AttachmentRequest(); + sourceAttach.setName(metadata.getOriginalName()); + sourceAttach.setBizType(Attachment.BizType.JOURNAL_MOMENT); + sourceAttach.setBizId(0L); + sourceAttach.setAttachTypeValue(MediaAttach.Type.SOURCE); + sourceAttach.setSize(file.length()); + sourceAttach.setInputStream(IO.getInputStream(file)); + thumbResult.add(attachmentService.createMedia(sourceAttach)); + } + return thumbResult; + } catch (Exception e) { + log.error("create moment error", e); + throw new TimiException(TimiCode.ERROR).msgKey("TODO create moment error"); + } + } + + @Override + public List listMoment() throws TimiException { + Page page = new Page(0, Integer.MAX_VALUE); + LinkedHashMap orderMap = new LinkedHashMap<>(); + orderMap.put("created_at", BaseMapper.OrderType.DESC); + page.setOrderMap(orderMap); + return attachmentService.pageByBizId(Attachment.BizType.JOURNAL_MOMENT, 0L, List.of(MediaAttach.Type.THUMB), page).getList(); + } + + @Override + public void deleteMoment(Long[] thumbIds) throws TimiException { + for (int i = 0; i < thumbIds.length; i++) { + attachmentService.deleteMedia(thumbIds[i]); + } + } + + @Override + public void archiveMoment(ArchiveRequest request) throws TimiException { + try { + Journal journal = new Journal(); + BeanUtils.copyProperties(request, journal); + super.create(journal); + + Long[] thumbIds = request.getThumbIds(); + if (TimiJava.isEmpty(thumbIds)) { + return; + } + for (int i = 0; i < thumbIds.length; i++) { + Attachment thumbAttach = attachmentService.get(thumbIds[i]); + thumbAttach.setBizType(Attachment.BizType.JOURNAL); + thumbAttach.setBizId(journal.getId()); + attachmentService.update(thumbAttach); + + MediaAttach.ExtData extData = gson.fromJson(thumbAttach.getExt(), MediaAttach.ExtData.class); + Attachment sourceAttach = attachmentService.get(extData.getSourceId()); + sourceAttach.setBizType(Attachment.BizType.JOURNAL); + sourceAttach.setBizId(journal.getId()); + attachmentService.update(sourceAttach); + } + } catch (Exception e) { + log.error("archive journal error", e); + 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); + } +} diff --git a/src/main/java/com/imyeyu/api/modules/journal/util/JournalAPIInterceptor.java b/src/main/java/com/imyeyu/api/modules/journal/util/JournalAPIInterceptor.java new file mode 100644 index 0000000..e1ab453 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/util/JournalAPIInterceptor.java @@ -0,0 +1,47 @@ +package com.imyeyu.api.modules.journal.util; + +import com.imyeyu.api.modules.common.bean.SettingKey; +import com.imyeyu.api.modules.common.service.SettingService; +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 jakarta.annotation.PostConstruct; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +/** + * @author 夜雨 + * @version 2023-11-23 17:09 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class JournalAPIInterceptor implements HandlerInterceptor { + + public static final String PATH = "/journal/**"; + + private final SettingService settingService; + + private String[] keys; + + @PostConstruct + private void postConstruct() { + keys = settingService.getAsString(SettingKey.JOURNAL_KEY).split(","); + } + + public boolean preHandle(@NonNull HttpServletRequest req, @NonNull HttpServletResponse resp, @NonNull Object handler) { + String key = TimiJava.firstNotEmpty(TimiSpring.getHeader("Key"), TimiSpring.getRequestArg("key")); + for (int i = 0; i < keys.length; i++) { + if (keys[i].equals(key)) { + return true; + } + } + throw new TimiException(TimiCode.ARG_MISS).msgKey("invalid.key"); + } +} diff --git a/src/main/java/com/imyeyu/api/modules/journal/vo/AppendRequest.java b/src/main/java/com/imyeyu/api/modules/journal/vo/AppendRequest.java new file mode 100644 index 0000000..fb66269 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/vo/AppendRequest.java @@ -0,0 +1,15 @@ +package com.imyeyu.api.modules.journal.vo; + +import lombok.Data; + +/** + * @author 夜雨 + * @since 2025-09-30 20:37 + */ +@Data +public class AppendRequest { + + private Long id; + + private String[] tempFileIds; +} \ No newline at end of file diff --git a/src/main/java/com/imyeyu/api/modules/journal/vo/ArchiveRequest.java b/src/main/java/com/imyeyu/api/modules/journal/vo/ArchiveRequest.java new file mode 100644 index 0000000..2b671a1 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/vo/ArchiveRequest.java @@ -0,0 +1,16 @@ +package com.imyeyu.api.modules.journal.vo; + +import com.imyeyu.api.modules.journal.entity.Journal; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author 夜雨 + * @since 2025-10-20 15:29 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class ArchiveRequest extends Journal { + + private Long[] thumbIds; +} diff --git a/src/main/java/com/imyeyu/api/modules/journal/vo/JournalPage.java b/src/main/java/com/imyeyu/api/modules/journal/vo/JournalPage.java new file mode 100644 index 0000000..eff42ce --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/vo/JournalPage.java @@ -0,0 +1,17 @@ +package com.imyeyu.api.modules.journal.vo; + +import com.imyeyu.api.modules.journal.entity.Journal; +import com.imyeyu.spring.bean.Page; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author 夜雨 + * @since 2025-10-09 18:48 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class JournalPage extends Page { + + private Journal.Type type; +} \ No newline at end of file diff --git a/src/main/java/com/imyeyu/api/modules/journal/vo/JournalRequest.java b/src/main/java/com/imyeyu/api/modules/journal/vo/JournalRequest.java new file mode 100644 index 0000000..e0eaa57 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/vo/JournalRequest.java @@ -0,0 +1,18 @@ +package com.imyeyu.api.modules.journal.vo; + +import com.imyeyu.api.modules.journal.entity.Journal; +import com.imyeyu.spring.annotation.table.Transient; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author 夜雨 + * @since 2025-09-26 15:56 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class JournalRequest extends Journal { + + @Transient + private String[] tempFileIds; +} diff --git a/src/main/java/com/imyeyu/api/modules/journal/vo/JournalResponse.java b/src/main/java/com/imyeyu/api/modules/journal/vo/JournalResponse.java new file mode 100644 index 0000000..1e767af --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/journal/vo/JournalResponse.java @@ -0,0 +1,19 @@ +package com.imyeyu.api.modules.journal.vo; + +import com.imyeyu.api.modules.common.entity.Attachment; +import com.imyeyu.api.modules.journal.entity.Journal; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * @author 夜雨 + * @since 2025-09-26 15:56 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class JournalResponse extends Journal { + + private List items; +} \ No newline at end of file