diff --git a/pom.xml b/pom.xml index 53c389d..87fbd45 100644 --- a/pom.xml +++ b/pom.xml @@ -178,20 +178,6 @@ - - - com.alibaba.fastjson2 - fastjson2 - 2.0.23 - - - - - com.fasterxml.jackson.core - jackson-annotations - 2.14.1 - diff --git a/src/main/java/me/qwq/doghouse/component/Rk.java b/src/main/java/me/qwq/doghouse/component/Rk.java index a89eeff..379ab88 100644 --- a/src/main/java/me/qwq/doghouse/component/Rk.java +++ b/src/main/java/me/qwq/doghouse/component/Rk.java @@ -186,7 +186,7 @@ public class Rk { * @return */ public static String prepareDogHash(String email) { - + if (email == null) email = ""; email = email.toLowerCase(Locale.ENGLISH); RBucket gravatarHashBucket = redisson.getBucket(getGravatarKey(EMAIL_HASH_PREFIX + email)); diff --git a/src/main/java/me/qwq/doghouse/config/DoghouseConfig.java b/src/main/java/me/qwq/doghouse/config/DoghouseConfig.java index 6752ac1..230b88f 100644 --- a/src/main/java/me/qwq/doghouse/config/DoghouseConfig.java +++ b/src/main/java/me/qwq/doghouse/config/DoghouseConfig.java @@ -3,6 +3,7 @@ package me.qwq.doghouse.config; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.cache.CacheProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; @@ -21,11 +22,13 @@ import me.qwq.doghouse.service.ConfigService; /** * Doghouse 配置项 + *

+ * 指定 RedisCacheManager 序列化器后需要重新指定启用 CacheProperties 的自动装配 * @author Doghole * */ @Configuration -@EnableConfigurationProperties(DoghouseProperties.class) +@EnableConfigurationProperties({DoghouseProperties.class, CacheProperties.class}) @Import(ConfigAutoRegistrar.class) public class DoghouseConfig implements WebMvcConfigurer { @@ -90,4 +93,5 @@ public class DoghouseConfig implements WebMvcConfigurer { resolver.setCheckExistence(true); // 文件不存在就跳过,交给下一个 resolver return resolver; } + } diff --git a/src/main/java/me/qwq/doghouse/controller/admin/AssetController.java b/src/main/java/me/qwq/doghouse/controller/admin/AssetController.java index 1c9c020..60dc615 100644 --- a/src/main/java/me/qwq/doghouse/controller/admin/AssetController.java +++ b/src/main/java/me/qwq/doghouse/controller/admin/AssetController.java @@ -1,6 +1,5 @@ package me.qwq.doghouse.controller.admin; -import com.alibaba.fastjson2.util.DateUtils; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.github.yulichang.wrapper.MPJLambdaWrapper; @@ -18,6 +17,8 @@ import me.qwq.doghouse.pojo.dto.LayPageReq; import me.qwq.doghouse.pojo.dto.LayPageResp; import me.qwq.doghouse.pojo.dto.R; import me.qwq.doghouse.service.AssetService; +import me.qwq.doghouse.util.DateUtils; + import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; diff --git a/src/main/java/me/qwq/doghouse/controller/admin/post/AbstractAdminPostController.java b/src/main/java/me/qwq/doghouse/controller/admin/post/AbstractAdminPostController.java index 5bb8724..bf72e45 100644 --- a/src/main/java/me/qwq/doghouse/controller/admin/post/AbstractAdminPostController.java +++ b/src/main/java/me/qwq/doghouse/controller/admin/post/AbstractAdminPostController.java @@ -1,10 +1,11 @@ package me.qwq.doghouse.controller.admin.post; -import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.yulichang.wrapper.MPJLambdaWrapper; import jakarta.validation.Valid; @@ -56,12 +57,18 @@ public abstract class AbstractAdminPostController, @Autowired AssetService assetService; + @Autowired MetaService metaService; + @Autowired RelationshipService relationshipService; + @Autowired PostTypeComponent postTypeComponent; + + @Autowired + ObjectMapper objectMapper; C postTypeConfig; @@ -136,9 +143,10 @@ public abstract class AbstractAdminPostController, /** * 编辑 + * @throws JsonProcessingException */ @GetMapping("/edit") - public String edit(@RequestParam(required = false) Long postId) { + public String edit(@RequestParam(required = false) Long postId) throws JsonProcessingException { PostTypeEnum postType = getPostTypeConfig().getPostType(); @@ -148,7 +156,7 @@ public abstract class AbstractAdminPostController, request.setAttribute("title", "编辑 - " + post.getPostTitle()); List assets = assetService.list( new LambdaQueryWrapper().eq(Asset::getFromPostId, postId)); - request.setAttribute("assets", StringEscapeUtils.escapeEcmaScript(JSONObject.toJSONString(assets))); + request.setAttribute("assets", StringEscapeUtils.escapeEcmaScript(objectMapper.writeValueAsString(assets))); } else { request.setAttribute("title", "新增" + postType.getNote()); diff --git a/src/main/java/me/qwq/doghouse/controller/api/v1/ApiControllerV1.java b/src/main/java/me/qwq/doghouse/controller/api/v1/ApiControllerV1.java index 519de15..3fca152 100644 --- a/src/main/java/me/qwq/doghouse/controller/api/v1/ApiControllerV1.java +++ b/src/main/java/me/qwq/doghouse/controller/api/v1/ApiControllerV1.java @@ -20,14 +20,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.alibaba.fastjson2.JSONObject; - import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import me.qwq.dogface.Dogface; import me.qwq.doghouse.component.Rk; import me.qwq.doghouse.exception.PageNotFoundException; +import me.qwq.doghouse.pojo.dto.DailyPostCommentStats; import me.qwq.doghouse.pojo.dto.R; import me.qwq.doghouse.service.CommentService; import me.qwq.doghouse.service.StatisticsService; @@ -132,7 +131,7 @@ public class ApiControllerV1 { } @GetMapping(path="/getPassDaysStatistics", produces="application/json") - public JSONObject getPassDaysStatistics(Integer passDays) { + public DailyPostCommentStats getPassDaysStatistics(Integer passDays) { return statisticsService.getPostAndCommentCountsWithDates(passDays, null); } @@ -163,11 +162,11 @@ public class ApiControllerV1 { svgRoot.setAttribute("viewBox", String.format("0 0 %d %d", w, h)); // 获取 n 日以来的文章和评论统计 - JSONObject jo = statisticsService.getPostAndCommentCountsWithDates(total, null); + DailyPostCommentStats s = statisticsService.getPostAndCommentCountsWithDates(total, null); - List dates = jo.getList("dates", String.class); - List postCounts = jo.getList("postCounts", Integer.class); - List commentCounts = jo.getList("commentCounts", Integer.class); + List dates = s.dates(); + List postCounts = s.postCounts(); + List commentCounts = s.commentCounts(); for (int col = 0; col < cols; col++) { for (int row = 0; row < rows; row++) { diff --git a/src/main/java/me/qwq/doghouse/controller/api/v2/CommentApiControllerV2.java b/src/main/java/me/qwq/doghouse/controller/api/v2/CommentApiControllerV2.java index 9c2f1a3..badb987 100644 --- a/src/main/java/me/qwq/doghouse/controller/api/v2/CommentApiControllerV2.java +++ b/src/main/java/me/qwq/doghouse/controller/api/v2/CommentApiControllerV2.java @@ -1,5 +1,8 @@ package me.qwq.doghouse.controller.api.v2; +import java.util.HashMap; +import java.util.Map; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -8,7 +11,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.alibaba.fastjson2.JSONObject; +import com.fasterxml.jackson.databind.JsonNode; import me.qwq.dogface.Dogface; import me.qwq.doghouse.controller.common.BaseController; @@ -38,8 +41,8 @@ public class CommentApiControllerV2 extends BaseController { Dogface dogface; @PostMapping("/preview") - public R preview(@RequestBody JSONObject jo) { - String markDown = MarkDownUtils.commentToHtml(jo.getString("content")); + public R preview(@RequestBody JsonNode jo) { + String markDown = MarkDownUtils.commentToHtml(jo.get("content").asText()); return R.ok(markDown); } @@ -54,16 +57,16 @@ public class CommentApiControllerV2 extends BaseController { throw RException.badRequest("非法请求"); } - JSONObject jo = new JSONObject(); - jo.put("author", commentForEdit.getAuthor()); - jo.put("isMarkdown", commentForEdit.isMarkdown()); - jo.put("email", commentForEdit.getEmail()); - jo.put("url", commentForEdit.getUrl()); - jo.put("content", commentForEdit.getContent()); - jo.put("subscribeReply", commentForEdit.isSubscribeReply()); - jo.put("commentStatu", commentForEdit.getCommentStatus()); - jo.put("id", commentForEdit.getId()); + Map dto = new HashMap<>(); + dto.put("author", commentForEdit.getAuthor()); + dto.put("isMarkdown", commentForEdit.isMarkdown()); + dto.put("email", commentForEdit.getEmail()); + dto.put("url", commentForEdit.getUrl()); + dto.put("content", commentForEdit.getContent()); + dto.put("subscribeReply", commentForEdit.isSubscribeReply()); + dto.put("commentStatu", commentForEdit.getCommentStatus()); + dto.put("id", commentForEdit.getId()); - return R.ok(jo); + return R.ok(dto); } } diff --git a/src/main/java/me/qwq/doghouse/controller/blog/SitemapController.java b/src/main/java/me/qwq/doghouse/controller/blog/SitemapController.java index 24d4dd5..0b89741 100644 --- a/src/main/java/me/qwq/doghouse/controller/blog/SitemapController.java +++ b/src/main/java/me/qwq/doghouse/controller/blog/SitemapController.java @@ -1,7 +1,6 @@ package me.qwq.doghouse.controller.blog; -import com.alibaba.fastjson2.util.DateUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -18,6 +17,7 @@ import me.qwq.doghouse.interfaces.IPostTypeConfig; import me.qwq.doghouse.pojo.dto.PageQuery; import me.qwq.doghouse.service.*; import me.qwq.doghouse.service.post.PostService; +import me.qwq.doghouse.util.DateUtils; import org.apache.commons.lang3.StringUtils; import org.jdom2.Document; diff --git a/src/main/java/me/qwq/doghouse/controller/blog/post/WikiPaginationController.java b/src/main/java/me/qwq/doghouse/controller/blog/post/WikiPaginationController.java index c9df5da..f44fe6a 100644 --- a/src/main/java/me/qwq/doghouse/controller/blog/post/WikiPaginationController.java +++ b/src/main/java/me/qwq/doghouse/controller/blog/post/WikiPaginationController.java @@ -1,7 +1,9 @@ package me.qwq.doghouse.controller.blog.post; -import com.alibaba.fastjson2.JSON; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + import lombok.extern.slf4j.Slf4j; import me.qwq.doghouse.entity.config.WikiConfig; import me.qwq.doghouse.entity.Post; @@ -9,6 +11,7 @@ import me.qwq.doghouse.pojo.bo.PostPassJar; import me.qwq.doghouse.service.post.WikiService; import me.qwq.doghouse.util.EscapeUnescapeUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -28,6 +31,9 @@ import java.util.List; @RequestMapping("/wiki") public class WikiPaginationController extends AbstractPaginationController { + @Autowired + ObjectMapper objectMapper; + /** * 首页 */ @@ -44,9 +50,10 @@ public class WikiPaginationController extends AbstractPaginationController listFrontWikis(Long postId) { + public List listFrontWikis(Long postId) throws JsonProcessingException { List unfolded = WikiService.getUnfoldedWikis(request); - String unfoldedStr = unfolded == null ? "[]" : JSON.toJSONString(unfolded); + String unfoldedStr = unfolded == null ? "[]" : objectMapper.writeValueAsString(unfolded); unfoldedStr = EscapeUnescapeUtils.escape(unfoldedStr); Cookie unfoldedCookie = new Cookie(WikiService.UNFOLDED_WIKIS, unfoldedStr); unfoldedCookie.setPath("/"); diff --git a/src/main/java/me/qwq/doghouse/entity/Post.java b/src/main/java/me/qwq/doghouse/entity/Post.java index 8e72222..a308e54 100644 --- a/src/main/java/me/qwq/doghouse/entity/Post.java +++ b/src/main/java/me/qwq/doghouse/entity/Post.java @@ -27,7 +27,6 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import me.qwq.doghouse.enums.PostStatusEnum; import me.qwq.doghouse.enums.PostTypeEnum; -import me.qwq.doghouse.interfaces.IAvatarUrl; import me.qwq.doghouse.interfaces.IFriendlyName; import me.qwq.doghouse.interfaces.IPostPassMess; import me.qwq.doghouse.validator.FriendlyNameValid; @@ -41,7 +40,7 @@ import me.qwq.doghouse.validator.FriendlyNameValid; @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @FriendlyNameValid -public class Post extends Model implements Serializable, IPostPassMess, ITreeView, IAvatarUrl, IFriendlyName { +public class Post extends Model implements Serializable, IPostPassMess, ITreeView, IFriendlyName { private static final long serialVersionUID = 1L; diff --git a/src/main/java/me/qwq/doghouse/entity/config/MarkdownConfig.java b/src/main/java/me/qwq/doghouse/entity/config/MarkdownConfig.java deleted file mode 100644 index 33d71fe..0000000 --- a/src/main/java/me/qwq/doghouse/entity/config/MarkdownConfig.java +++ /dev/null @@ -1,39 +0,0 @@ -package me.qwq.doghouse.entity.config; - -import java.io.Serializable; - -import com.alibaba.fastjson2.JSONObject; -import com.baomidou.mybatisplus.core.toolkit.StringUtils; - -import jodd.io.FileUtil; -import lombok.Data; -import lombok.experimental.Accessors; -import lombok.extern.slf4j.Slf4j; -import me.qwq.doghouse.annotation.ConfigInfo; -import me.qwq.doghouse.interfaces.IConfig; - -@SuppressWarnings("serial") -@Data -@Accessors(chain=true) -@ConfigInfo(field="markdown", name="Markdown 设置", initDefault=true) -@Slf4j -public class MarkdownConfig implements Serializable, IConfig { - - - private static final String DEFAULT_MERMAID_CONFIG = ""; - - private String mermaidConfig = DEFAULT_MERMAID_CONFIG; - - public MarkdownConfig afterSaving() { - if (StringUtils.isNotBlank(mermaidConfig)) { - try { - JSONObject jo = JSONObject.parse(mermaidConfig); - FileUtil.writeString("./conf/mermaid/config.json", jo.toJSONString()); - } catch (Exception e) { - log.warn("Save mermaid self-defined css failed", e); - } - } - return this; - } - -} diff --git a/src/main/java/me/qwq/doghouse/pojo/dto/DailyPostCommentStats.java b/src/main/java/me/qwq/doghouse/pojo/dto/DailyPostCommentStats.java new file mode 100644 index 0000000..fe4cc1c --- /dev/null +++ b/src/main/java/me/qwq/doghouse/pojo/dto/DailyPostCommentStats.java @@ -0,0 +1,10 @@ +package me.qwq.doghouse.pojo.dto; + +import java.io.Serializable; +import java.util.List; + +public record DailyPostCommentStats( + List dates, + List postCounts, + List commentCounts +) implements Serializable {} \ No newline at end of file diff --git a/src/main/java/me/qwq/doghouse/service/ConfigService.java b/src/main/java/me/qwq/doghouse/service/ConfigService.java index e650ee3..a211757 100644 --- a/src/main/java/me/qwq/doghouse/service/ConfigService.java +++ b/src/main/java/me/qwq/doghouse/service/ConfigService.java @@ -7,7 +7,8 @@ import me.qwq.doghouse.entity.RawConfig; import me.qwq.doghouse.interfaces.IConfig; import me.qwq.doghouse.util.SpringContextHolder; -import com.alibaba.fastjson2.JSONObject; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; @@ -40,6 +41,9 @@ public class ConfigService extends BaseServiceImpl { @Autowired Reflections reflections; + @Autowired + private ObjectMapper objectMapper; + /** * 从 * field @@ -198,8 +202,15 @@ public class ConfigService extends BaseServiceImpl { } return null; } - T iConfig = - JSONObject.parseObject(rawConfig.getConfigValue(), clazz); + T iConfig; + try { + iConfig = objectMapper.readValue(rawConfig.getConfigValue(), clazz); + } + catch (JsonProcessingException e) { + throw new IllegalStateException( + "Failed to deserialize config: " + info.field(), e + ); + } setCache(iConfig); return iConfig; } @@ -222,7 +233,15 @@ public class ConfigService extends BaseServiceImpl { else { rawConfig.setUpdateTime(LocalDateTime.now()); } - rawConfig.setConfigValue(JSONObject.toJSONString(iConfig)); + try { + rawConfig.setConfigValue( + objectMapper.writeValueAsString(iConfig) + ); + } catch (JsonProcessingException e) { + throw new IllegalStateException( + "Failed to serialize config: " + info.field(), e + ); + } iConfig.beforeSaving(); if (saveOrUpdate(rawConfig)) { diff --git a/src/main/java/me/qwq/doghouse/service/StatisticsService.java b/src/main/java/me/qwq/doghouse/service/StatisticsService.java index 93599b5..4b177e0 100644 --- a/src/main/java/me/qwq/doghouse/service/StatisticsService.java +++ b/src/main/java/me/qwq/doghouse/service/StatisticsService.java @@ -4,15 +4,13 @@ import java.text.DecimalFormat; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.util.Arrays; +import java.util.List; import java.util.Map; -import java.util.stream.Collectors; - import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; -import com.alibaba.fastjson2.JSONObject; import com.github.yulichang.wrapper.MPJLambdaWrapper; import lombok.Getter; @@ -25,6 +23,7 @@ import me.qwq.doghouse.entity.Post; import me.qwq.doghouse.enums.CommentStatusEnum; import me.qwq.doghouse.enums.PostStatusEnum; import me.qwq.doghouse.enums.PostTypeEnum; +import me.qwq.doghouse.pojo.dto.DailyPostCommentStats; import me.qwq.doghouse.service.post.PostService; @Service @@ -86,15 +85,24 @@ public class StatisticsService { */ @CacheEvictionTask @Cacheable(value=CacheConstants.Statistics.DAILY_POST_AND_COMMENT_COUNTS) - public JSONObject getPostAndCommentCountsWithDates(Integer passDays, PostTypeEnum postType) { - JSONObject jo = new JSONObject(); - Map map = mapper.getPostAndCommentCountsWithDates(passDays, postType); - jo.put("dates", map.get("dates").split(",")); - jo.put("postCounts", Arrays.asList(map.get("postCounts").split(",")).stream() - .map(s -> Integer.valueOf(s)).collect(Collectors.toList())); - jo.put("commentCounts", Arrays.asList(map.get("commentCounts").split(",")).stream() - .map(s -> Integer.valueOf(s)).collect(Collectors.toList())); - return jo; + public DailyPostCommentStats getPostAndCommentCountsWithDates(Integer passDays, PostTypeEnum postType) { + Map map = + mapper.getPostAndCommentCountsWithDates(passDays, postType); + + List dates = + Arrays.asList(map.get("dates").split(",")); + + List postCounts = + Arrays.stream(map.get("postCounts").split(",")) + .map(Integer::valueOf) + .toList(); + + List commentCounts = + Arrays.stream(map.get("commentCounts").split(",")) + .map(Integer::valueOf) + .toList(); + + return new DailyPostCommentStats(dates, postCounts, commentCounts); } public PostStatistic getPostStatistic(Post post) { diff --git a/src/main/java/me/qwq/doghouse/service/ThemeService.java b/src/main/java/me/qwq/doghouse/service/ThemeService.java index 9d12cc7..dbe9373 100644 --- a/src/main/java/me/qwq/doghouse/service/ThemeService.java +++ b/src/main/java/me/qwq/doghouse/service/ThemeService.java @@ -25,7 +25,8 @@ import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.stereotype.Service; import org.springframework.util.function.ThrowingSupplier; -import com.alibaba.fastjson2.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; + import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import me.qwq.doghouse.config.DoghouseProperties; @@ -43,6 +44,8 @@ public class ThemeService { private volatile List cachedThemes = Collections.emptyList(); private List internalThemes = new ArrayList<>(); + @Autowired + private ObjectMapper objectMapper; @Autowired DoghouseProperties doghouseProperties; @@ -294,7 +297,7 @@ public class ThemeService { */ private ThemeInfo getThemeInfo(Resource config) throws IOException { String json = config.getContentAsString(StandardCharsets.UTF_8); - ThemeInfo themeInfo = JSONObject.parseObject(json, ThemeInfo.class); + ThemeInfo themeInfo = objectMapper.readValue(json, ThemeInfo.class); // uri: .../templates/blog/bleaching/config.json // folderName: bleaching @@ -331,7 +334,7 @@ public class ThemeService { */ private ThemeInfo getThemeInfo(Path configPath) throws IOException { String json = Files.readString(configPath); - ThemeInfo themeInfo = JSONObject.parseObject(json, ThemeInfo.class); + ThemeInfo themeInfo = objectMapper.readValue(json, ThemeInfo.class); Path path = configPath.getParent(); themeInfo.setDirectory(path.toString()); diff --git a/src/main/java/me/qwq/doghouse/service/post/WikiService.java b/src/main/java/me/qwq/doghouse/service/post/WikiService.java index 2cdf946..3aff424 100644 --- a/src/main/java/me/qwq/doghouse/service/post/WikiService.java +++ b/src/main/java/me/qwq/doghouse/service/post/WikiService.java @@ -13,10 +13,11 @@ import me.qwq.doghouse.pojo.dto.LayPageReq; import me.qwq.doghouse.util.CookieUtils; import me.qwq.doghouse.util.SessionUtils; -import com.alibaba.fastjson2.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.enums.DefaultFuncEnum; @@ -669,8 +670,10 @@ public class WikiService extends AbstractPostService { Cookie cookie = CookieUtils.getCookie(request, UNFOLDED_WIKIS); if (cookie == null) new ArrayList<>(); try { - JSONArray ja = JSONArray.parse(cookie.getValue()); - return ja.toJavaList(Long.class); + return new ObjectMapper().readValue( + cookie.getValue(), + new TypeReference>() {} + ); } catch (Exception e) { return null; diff --git a/src/main/java/me/qwq/doghouse/util/DateUtils.java b/src/main/java/me/qwq/doghouse/util/DateUtils.java new file mode 100644 index 0000000..6de8115 --- /dev/null +++ b/src/main/java/me/qwq/doghouse/util/DateUtils.java @@ -0,0 +1,37 @@ +package me.qwq.doghouse.util; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public final class DateUtils { + + // 缓存 formatter,行为接近 fastjson2 + private static final Map FORMATTER_CACHE = + new ConcurrentHashMap<>(); + + private DateUtils() { + } + + /** + * 格式化 LocalDateTime + * + * @param dateTime LocalDateTime + * @param pattern 日期格式,如 yyyy-MM-dd HH:mm:ss + * @return 格式化后的字符串 + */ + public static String format(LocalDateTime dateTime, String pattern) { + if (dateTime == null) { + return null; + } + if (pattern == null || pattern.isEmpty()) { + throw new IllegalArgumentException("pattern must not be null or empty"); + } + + DateTimeFormatter formatter = + FORMATTER_CACHE.computeIfAbsent(pattern, DateTimeFormatter::ofPattern); + + return dateTime.format(formatter); + } +} diff --git a/src/main/java/me/qwq/doghouse/util/ImageBase64Utils.java b/src/main/java/me/qwq/doghouse/util/ImageBase64Utils.java deleted file mode 100644 index 6c70f35..0000000 --- a/src/main/java/me/qwq/doghouse/util/ImageBase64Utils.java +++ /dev/null @@ -1,70 +0,0 @@ -package me.qwq.doghouse.util; -import java.io.*; -import java.nio.file.*; -import java.util.Base64; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.util.StreamUtils; - -public class ImageBase64Utils { - - /** - * 从文件系统路径读取图片并转 base64 - */ - public static String fromFileSystem(Path imagePath) throws IOException { - if (imagePath == null || !Files.exists(imagePath)) { - return null; - } - - byte[] bytes = Files.readAllBytes(imagePath); - String mimeType = Files.probeContentType(imagePath); - - return toDataUrl(bytes, mimeType); - } - - /** - * 从 classpath 读取图片并转 base64(支持 jar 内) - */ - public static String fromClasspath(String classpathLocation) throws IOException { - ClassPathResource resource = new ClassPathResource(classpathLocation); - if (!resource.exists()) { - return null; - } - - byte[] bytes; - try (InputStream is = resource.getInputStream()) { - bytes = StreamUtils.copyToByteArray(is); - } - - String mimeType = guessMimeType(classpathLocation); - return toDataUrl(bytes, mimeType); - } - - /** - * 生成 data:image/...;base64,... - */ - private static String toDataUrl(byte[] bytes, String mimeType) { - if (bytes == null || bytes.length == 0) { - return null; - } - - if (mimeType == null) { - mimeType = "image/png"; // 兜底 - } - - String base64 = Base64.getEncoder().encodeToString(bytes); - return "data:" + mimeType + ";base64," + base64; - } - - /** - * 根据文件名猜测 MIME - */ - private static String guessMimeType(String filename) { - String lower = filename.toLowerCase(); - if (lower.endsWith(".png")) return "image/png"; - if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg"; - if (lower.endsWith(".gif")) return "image/gif"; - if (lower.endsWith(".webp")) return "image/webp"; - return "image/png"; - } -} \ No newline at end of file diff --git a/src/main/java/me/qwq/doghouse/util/JsonUtils.java b/src/main/java/me/qwq/doghouse/util/JsonUtils.java new file mode 100644 index 0000000..ee6f649 --- /dev/null +++ b/src/main/java/me/qwq/doghouse/util/JsonUtils.java @@ -0,0 +1,18 @@ +package me.qwq.doghouse.util; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import me.qwq.doghouse.annotation.StaticAttribute; + +@StaticAttribute +public final class JsonUtils { + private static final ObjectMapper MAPPER = new ObjectMapper(); + + public static String toJson(Object o) { + try { + return MAPPER.writeValueAsString(o); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/main/resources/templates/admin/tag/index.html b/src/main/resources/templates/admin/tag/index.html index fbadefb..4f11cc6 100644 --- a/src/main/resources/templates/admin/tag/index.html +++ b/src/main/resources/templates/admin/tag/index.html @@ -80,7 +80,7 @@