去除 fastjson2 依赖
This commit is contained in:
14
pom.xml
14
pom.xml
@@ -178,20 +178,6 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.fastjson2</groupId>
|
|
||||||
<artifactId>fastjson2</artifactId>
|
|
||||||
<version>2.0.23</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-annotations</artifactId>
|
|
||||||
<version>2.14.1</version><!--$NO-MVN-MAN-VER$-->
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15to18 -->
|
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15to18 -->
|
||||||
<!-- sha224 哈希套件 -->
|
<!-- sha224 哈希套件 -->
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ public class Rk {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String prepareDogHash(String email) {
|
public static String prepareDogHash(String email) {
|
||||||
|
if (email == null) email = "";
|
||||||
email = email.toLowerCase(Locale.ENGLISH);
|
email = email.toLowerCase(Locale.ENGLISH);
|
||||||
|
|
||||||
RBucket<String> gravatarHashBucket = redisson.getBucket(getGravatarKey(EMAIL_HASH_PREFIX + email));
|
RBucket<String> gravatarHashBucket = redisson.getBucket(getGravatarKey(EMAIL_HASH_PREFIX + email));
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package me.qwq.doghouse.config;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
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.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@@ -21,11 +22,13 @@ import me.qwq.doghouse.service.ConfigService;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Doghouse 配置项
|
* Doghouse 配置项
|
||||||
|
* <p>
|
||||||
|
* 指定 RedisCacheManager 序列化器后需要重新指定启用 CacheProperties 的自动装配
|
||||||
* @author Doghole
|
* @author Doghole
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties(DoghouseProperties.class)
|
@EnableConfigurationProperties({DoghouseProperties.class, CacheProperties.class})
|
||||||
@Import(ConfigAutoRegistrar.class)
|
@Import(ConfigAutoRegistrar.class)
|
||||||
public class DoghouseConfig implements WebMvcConfigurer {
|
public class DoghouseConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
@@ -90,4 +93,5 @@ public class DoghouseConfig implements WebMvcConfigurer {
|
|||||||
resolver.setCheckExistence(true); // 文件不存在就跳过,交给下一个 resolver
|
resolver.setCheckExistence(true); // 文件不存在就跳过,交给下一个 resolver
|
||||||
return resolver;
|
return resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package me.qwq.doghouse.controller.admin;
|
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.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
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.LayPageResp;
|
||||||
import me.qwq.doghouse.pojo.dto.R;
|
import me.qwq.doghouse.pojo.dto.R;
|
||||||
import me.qwq.doghouse.service.AssetService;
|
import me.qwq.doghouse.service.AssetService;
|
||||||
|
import me.qwq.doghouse.util.DateUtils;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package me.qwq.doghouse.controller.admin.post;
|
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.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
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 com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
@@ -56,13 +57,19 @@ public abstract class AbstractAdminPostController<C extends IPostTypeConfig<C>,
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
AssetService assetService;
|
AssetService assetService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
MetaService metaService;
|
MetaService metaService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RelationshipService relationshipService;
|
RelationshipService relationshipService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
PostTypeComponent postTypeComponent;
|
PostTypeComponent postTypeComponent;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ObjectMapper objectMapper;
|
||||||
|
|
||||||
C postTypeConfig;
|
C postTypeConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,9 +143,10 @@ public abstract class AbstractAdminPostController<C extends IPostTypeConfig<C>,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
|
* @throws JsonProcessingException
|
||||||
*/
|
*/
|
||||||
@GetMapping("/edit")
|
@GetMapping("/edit")
|
||||||
public String edit(@RequestParam(required = false) Long postId) {
|
public String edit(@RequestParam(required = false) Long postId) throws JsonProcessingException {
|
||||||
|
|
||||||
PostTypeEnum postType = getPostTypeConfig().getPostType();
|
PostTypeEnum postType = getPostTypeConfig().getPostType();
|
||||||
|
|
||||||
@@ -148,7 +156,7 @@ public abstract class AbstractAdminPostController<C extends IPostTypeConfig<C>,
|
|||||||
request.setAttribute("title", "编辑 - " + post.getPostTitle());
|
request.setAttribute("title", "编辑 - " + post.getPostTitle());
|
||||||
List<Asset> assets = assetService.list(
|
List<Asset> assets = assetService.list(
|
||||||
new LambdaQueryWrapper<Asset>().eq(Asset::getFromPostId, postId));
|
new LambdaQueryWrapper<Asset>().eq(Asset::getFromPostId, postId));
|
||||||
request.setAttribute("assets", StringEscapeUtils.escapeEcmaScript(JSONObject.toJSONString(assets)));
|
request.setAttribute("assets", StringEscapeUtils.escapeEcmaScript(objectMapper.writeValueAsString(assets)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
request.setAttribute("title", "新增" + postType.getNote());
|
request.setAttribute("title", "新增" + postType.getNote());
|
||||||
|
|||||||
@@ -20,14 +20,13 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.qwq.dogface.Dogface;
|
import me.qwq.dogface.Dogface;
|
||||||
import me.qwq.doghouse.component.Rk;
|
import me.qwq.doghouse.component.Rk;
|
||||||
import me.qwq.doghouse.exception.PageNotFoundException;
|
import me.qwq.doghouse.exception.PageNotFoundException;
|
||||||
|
import me.qwq.doghouse.pojo.dto.DailyPostCommentStats;
|
||||||
import me.qwq.doghouse.pojo.dto.R;
|
import me.qwq.doghouse.pojo.dto.R;
|
||||||
import me.qwq.doghouse.service.CommentService;
|
import me.qwq.doghouse.service.CommentService;
|
||||||
import me.qwq.doghouse.service.StatisticsService;
|
import me.qwq.doghouse.service.StatisticsService;
|
||||||
@@ -132,7 +131,7 @@ public class ApiControllerV1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path="/getPassDaysStatistics", produces="application/json")
|
@GetMapping(path="/getPassDaysStatistics", produces="application/json")
|
||||||
public JSONObject getPassDaysStatistics(Integer passDays) {
|
public DailyPostCommentStats getPassDaysStatistics(Integer passDays) {
|
||||||
return statisticsService.getPostAndCommentCountsWithDates(passDays, null);
|
return statisticsService.getPostAndCommentCountsWithDates(passDays, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,11 +162,11 @@ public class ApiControllerV1 {
|
|||||||
svgRoot.setAttribute("viewBox", String.format("0 0 %d %d", w, h));
|
svgRoot.setAttribute("viewBox", String.format("0 0 %d %d", w, h));
|
||||||
|
|
||||||
// 获取 n 日以来的文章和评论统计
|
// 获取 n 日以来的文章和评论统计
|
||||||
JSONObject jo = statisticsService.getPostAndCommentCountsWithDates(total, null);
|
DailyPostCommentStats s = statisticsService.getPostAndCommentCountsWithDates(total, null);
|
||||||
|
|
||||||
List<String> dates = jo.getList("dates", String.class);
|
List<String> dates = s.dates();
|
||||||
List<Integer> postCounts = jo.getList("postCounts", Integer.class);
|
List<Integer> postCounts = s.postCounts();
|
||||||
List<Integer> commentCounts = jo.getList("commentCounts", Integer.class);
|
List<Integer> commentCounts = s.commentCounts();
|
||||||
|
|
||||||
for (int col = 0; col < cols; col++) {
|
for (int col = 0; col < cols; col++) {
|
||||||
for (int row = 0; row < rows; row++) {
|
for (int row = 0; row < rows; row++) {
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package me.qwq.doghouse.controller.api.v2;
|
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.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
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.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
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.dogface.Dogface;
|
||||||
import me.qwq.doghouse.controller.common.BaseController;
|
import me.qwq.doghouse.controller.common.BaseController;
|
||||||
@@ -38,8 +41,8 @@ public class CommentApiControllerV2 extends BaseController {
|
|||||||
Dogface dogface;
|
Dogface dogface;
|
||||||
|
|
||||||
@PostMapping("/preview")
|
@PostMapping("/preview")
|
||||||
public R<?> preview(@RequestBody JSONObject jo) {
|
public R<?> preview(@RequestBody JsonNode jo) {
|
||||||
String markDown = MarkDownUtils.commentToHtml(jo.getString("content"));
|
String markDown = MarkDownUtils.commentToHtml(jo.get("content").asText());
|
||||||
return R.ok(markDown);
|
return R.ok(markDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,16 +57,16 @@ public class CommentApiControllerV2 extends BaseController {
|
|||||||
throw RException.badRequest("非法请求");
|
throw RException.badRequest("非法请求");
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONObject jo = new JSONObject();
|
Map<String, Object> dto = new HashMap<>();
|
||||||
jo.put("author", commentForEdit.getAuthor());
|
dto.put("author", commentForEdit.getAuthor());
|
||||||
jo.put("isMarkdown", commentForEdit.isMarkdown());
|
dto.put("isMarkdown", commentForEdit.isMarkdown());
|
||||||
jo.put("email", commentForEdit.getEmail());
|
dto.put("email", commentForEdit.getEmail());
|
||||||
jo.put("url", commentForEdit.getUrl());
|
dto.put("url", commentForEdit.getUrl());
|
||||||
jo.put("content", commentForEdit.getContent());
|
dto.put("content", commentForEdit.getContent());
|
||||||
jo.put("subscribeReply", commentForEdit.isSubscribeReply());
|
dto.put("subscribeReply", commentForEdit.isSubscribeReply());
|
||||||
jo.put("commentStatu", commentForEdit.getCommentStatus());
|
dto.put("commentStatu", commentForEdit.getCommentStatus());
|
||||||
jo.put("id", commentForEdit.getId());
|
dto.put("id", commentForEdit.getId());
|
||||||
|
|
||||||
return R.ok(jo);
|
return R.ok(dto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package me.qwq.doghouse.controller.blog;
|
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.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
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.pojo.dto.PageQuery;
|
||||||
import me.qwq.doghouse.service.*;
|
import me.qwq.doghouse.service.*;
|
||||||
import me.qwq.doghouse.service.post.PostService;
|
import me.qwq.doghouse.service.post.PostService;
|
||||||
|
import me.qwq.doghouse.util.DateUtils;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jdom2.Document;
|
import org.jdom2.Document;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package me.qwq.doghouse.controller.blog.post;
|
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 lombok.extern.slf4j.Slf4j;
|
||||||
import me.qwq.doghouse.entity.config.WikiConfig;
|
import me.qwq.doghouse.entity.config.WikiConfig;
|
||||||
import me.qwq.doghouse.entity.Post;
|
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.service.post.WikiService;
|
||||||
import me.qwq.doghouse.util.EscapeUnescapeUtils;
|
import me.qwq.doghouse.util.EscapeUnescapeUtils;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
@@ -28,6 +31,9 @@ import java.util.List;
|
|||||||
@RequestMapping("/wiki")
|
@RequestMapping("/wiki")
|
||||||
public class WikiPaginationController extends AbstractPaginationController<WikiConfig, WikiService> {
|
public class WikiPaginationController extends AbstractPaginationController<WikiConfig, WikiService> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ObjectMapper objectMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 首页
|
* 首页
|
||||||
*/
|
*/
|
||||||
@@ -44,9 +50,10 @@ public class WikiPaginationController extends AbstractPaginationController<WikiC
|
|||||||
* Wiki 树形菜单点击
|
* Wiki 树形菜单点击
|
||||||
* @param postId
|
* @param postId
|
||||||
* @return
|
* @return
|
||||||
|
* @throws JsonProcessingException
|
||||||
*/
|
*/
|
||||||
@GetMapping({"/list", "/list/", "/list/{postId}"})
|
@GetMapping({"/list", "/list/", "/list/{postId}"})
|
||||||
public String listFrontWikisOnly(@PathVariable(name="postId", required=false) Long postId) {
|
public String listFrontWikisOnly(@PathVariable(name="postId", required=false) Long postId) throws JsonProcessingException {
|
||||||
request.setAttribute("wikis", listFrontWikis(postId));
|
request.setAttribute("wikis", listFrontWikis(postId));
|
||||||
return postTypeComponent.getTemplatePath(getPostType(), "side-only");
|
return postTypeComponent.getTemplatePath(getPostType(), "side-only");
|
||||||
}
|
}
|
||||||
@@ -56,10 +63,11 @@ public class WikiPaginationController extends AbstractPaginationController<WikiC
|
|||||||
* 放在控制器这里只是方便前端模板调用,并且能获得 service 的缓存能力
|
* 放在控制器这里只是方便前端模板调用,并且能获得 service 的缓存能力
|
||||||
* @param postId
|
* @param postId
|
||||||
* @return
|
* @return
|
||||||
|
* @throws JsonProcessingException
|
||||||
*/
|
*/
|
||||||
public List<Post> listFrontWikis(Long postId) {
|
public List<Post> listFrontWikis(Long postId) throws JsonProcessingException {
|
||||||
List<Long> unfolded = WikiService.getUnfoldedWikis(request);
|
List<Long> unfolded = WikiService.getUnfoldedWikis(request);
|
||||||
String unfoldedStr = unfolded == null ? "[]" : JSON.toJSONString(unfolded);
|
String unfoldedStr = unfolded == null ? "[]" : objectMapper.writeValueAsString(unfolded);
|
||||||
unfoldedStr = EscapeUnescapeUtils.escape(unfoldedStr);
|
unfoldedStr = EscapeUnescapeUtils.escape(unfoldedStr);
|
||||||
Cookie unfoldedCookie = new Cookie(WikiService.UNFOLDED_WIKIS, unfoldedStr);
|
Cookie unfoldedCookie = new Cookie(WikiService.UNFOLDED_WIKIS, unfoldedStr);
|
||||||
unfoldedCookie.setPath("/");
|
unfoldedCookie.setPath("/");
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import lombok.EqualsAndHashCode;
|
|||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import me.qwq.doghouse.enums.PostStatusEnum;
|
import me.qwq.doghouse.enums.PostStatusEnum;
|
||||||
import me.qwq.doghouse.enums.PostTypeEnum;
|
import me.qwq.doghouse.enums.PostTypeEnum;
|
||||||
import me.qwq.doghouse.interfaces.IAvatarUrl;
|
|
||||||
import me.qwq.doghouse.interfaces.IFriendlyName;
|
import me.qwq.doghouse.interfaces.IFriendlyName;
|
||||||
import me.qwq.doghouse.interfaces.IPostPassMess;
|
import me.qwq.doghouse.interfaces.IPostPassMess;
|
||||||
import me.qwq.doghouse.validator.FriendlyNameValid;
|
import me.qwq.doghouse.validator.FriendlyNameValid;
|
||||||
@@ -41,7 +40,7 @@ import me.qwq.doghouse.validator.FriendlyNameValid;
|
|||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@FriendlyNameValid
|
@FriendlyNameValid
|
||||||
public class Post extends Model<Post> implements Serializable, IPostPassMess<Post>, ITreeView<Post>, IAvatarUrl, IFriendlyName {
|
public class Post extends Model<Post> implements Serializable, IPostPassMess<Post>, ITreeView<Post>, IFriendlyName {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
|||||||
@@ -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<MarkdownConfig> {
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package me.qwq.doghouse.pojo.dto;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public record DailyPostCommentStats(
|
||||||
|
List<String> dates,
|
||||||
|
List<Integer> postCounts,
|
||||||
|
List<Integer> commentCounts
|
||||||
|
) implements Serializable {}
|
||||||
@@ -7,7 +7,8 @@ import me.qwq.doghouse.entity.RawConfig;
|
|||||||
import me.qwq.doghouse.interfaces.IConfig;
|
import me.qwq.doghouse.interfaces.IConfig;
|
||||||
import me.qwq.doghouse.util.SpringContextHolder;
|
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.BiMap;
|
||||||
import com.google.common.collect.HashBiMap;
|
import com.google.common.collect.HashBiMap;
|
||||||
|
|
||||||
@@ -40,6 +41,9 @@ public class ConfigService extends BaseServiceImpl<ConfigMapper, RawConfig> {
|
|||||||
@Autowired
|
@Autowired
|
||||||
Reflections reflections;
|
Reflections reflections;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从
|
* 从
|
||||||
* <b><code> field </code></b>
|
* <b><code> field </code></b>
|
||||||
@@ -198,8 +202,15 @@ public class ConfigService extends BaseServiceImpl<ConfigMapper, RawConfig> {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
T iConfig =
|
T iConfig;
|
||||||
JSONObject.parseObject(rawConfig.getConfigValue(), clazz);
|
try {
|
||||||
|
iConfig = objectMapper.readValue(rawConfig.getConfigValue(), clazz);
|
||||||
|
}
|
||||||
|
catch (JsonProcessingException e) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Failed to deserialize config: " + info.field(), e
|
||||||
|
);
|
||||||
|
}
|
||||||
setCache(iConfig);
|
setCache(iConfig);
|
||||||
return iConfig;
|
return iConfig;
|
||||||
}
|
}
|
||||||
@@ -222,7 +233,15 @@ public class ConfigService extends BaseServiceImpl<ConfigMapper, RawConfig> {
|
|||||||
else {
|
else {
|
||||||
rawConfig.setUpdateTime(LocalDateTime.now());
|
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();
|
iConfig.beforeSaving();
|
||||||
|
|
||||||
if (saveOrUpdate(rawConfig)) {
|
if (saveOrUpdate(rawConfig)) {
|
||||||
|
|||||||
@@ -4,15 +4,13 @@ import java.text.DecimalFormat;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -25,6 +23,7 @@ import me.qwq.doghouse.entity.Post;
|
|||||||
import me.qwq.doghouse.enums.CommentStatusEnum;
|
import me.qwq.doghouse.enums.CommentStatusEnum;
|
||||||
import me.qwq.doghouse.enums.PostStatusEnum;
|
import me.qwq.doghouse.enums.PostStatusEnum;
|
||||||
import me.qwq.doghouse.enums.PostTypeEnum;
|
import me.qwq.doghouse.enums.PostTypeEnum;
|
||||||
|
import me.qwq.doghouse.pojo.dto.DailyPostCommentStats;
|
||||||
import me.qwq.doghouse.service.post.PostService;
|
import me.qwq.doghouse.service.post.PostService;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -86,15 +85,24 @@ public class StatisticsService {
|
|||||||
*/
|
*/
|
||||||
@CacheEvictionTask
|
@CacheEvictionTask
|
||||||
@Cacheable(value=CacheConstants.Statistics.DAILY_POST_AND_COMMENT_COUNTS)
|
@Cacheable(value=CacheConstants.Statistics.DAILY_POST_AND_COMMENT_COUNTS)
|
||||||
public JSONObject getPostAndCommentCountsWithDates(Integer passDays, PostTypeEnum postType) {
|
public DailyPostCommentStats getPostAndCommentCountsWithDates(Integer passDays, PostTypeEnum postType) {
|
||||||
JSONObject jo = new JSONObject();
|
Map<String, String> map =
|
||||||
Map<String, String> map = mapper.getPostAndCommentCountsWithDates(passDays, postType);
|
mapper.getPostAndCommentCountsWithDates(passDays, postType);
|
||||||
jo.put("dates", map.get("dates").split(","));
|
|
||||||
jo.put("postCounts", Arrays.asList(map.get("postCounts").split(",")).stream()
|
List<String> dates =
|
||||||
.map(s -> Integer.valueOf(s)).collect(Collectors.toList()));
|
Arrays.asList(map.get("dates").split(","));
|
||||||
jo.put("commentCounts", Arrays.asList(map.get("commentCounts").split(",")).stream()
|
|
||||||
.map(s -> Integer.valueOf(s)).collect(Collectors.toList()));
|
List<Integer> postCounts =
|
||||||
return jo;
|
Arrays.stream(map.get("postCounts").split(","))
|
||||||
|
.map(Integer::valueOf)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
List<Integer> commentCounts =
|
||||||
|
Arrays.stream(map.get("commentCounts").split(","))
|
||||||
|
.map(Integer::valueOf)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return new DailyPostCommentStats(dates, postCounts, commentCounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PostStatistic getPostStatistic(Post post) {
|
public PostStatistic getPostStatistic(Post post) {
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ import org.springframework.core.io.support.ResourcePatternResolver;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.function.ThrowingSupplier;
|
import org.springframework.util.function.ThrowingSupplier;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.qwq.doghouse.config.DoghouseProperties;
|
import me.qwq.doghouse.config.DoghouseProperties;
|
||||||
@@ -43,6 +44,8 @@ public class ThemeService {
|
|||||||
private volatile List<ThemeInfo> cachedThemes = Collections.emptyList();
|
private volatile List<ThemeInfo> cachedThemes = Collections.emptyList();
|
||||||
private List<ThemeInfo> internalThemes = new ArrayList<>();
|
private List<ThemeInfo> internalThemes = new ArrayList<>();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
DoghouseProperties doghouseProperties;
|
DoghouseProperties doghouseProperties;
|
||||||
@@ -294,7 +297,7 @@ public class ThemeService {
|
|||||||
*/
|
*/
|
||||||
private ThemeInfo getThemeInfo(Resource config) throws IOException {
|
private ThemeInfo getThemeInfo(Resource config) throws IOException {
|
||||||
String json = config.getContentAsString(StandardCharsets.UTF_8);
|
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
|
// uri: .../templates/blog/bleaching/config.json
|
||||||
// folderName: bleaching
|
// folderName: bleaching
|
||||||
@@ -331,7 +334,7 @@ public class ThemeService {
|
|||||||
*/
|
*/
|
||||||
private ThemeInfo getThemeInfo(Path configPath) throws IOException {
|
private ThemeInfo getThemeInfo(Path configPath) throws IOException {
|
||||||
String json = Files.readString(configPath);
|
String json = Files.readString(configPath);
|
||||||
ThemeInfo themeInfo = JSONObject.parseObject(json, ThemeInfo.class);
|
ThemeInfo themeInfo = objectMapper.readValue(json, ThemeInfo.class);
|
||||||
|
|
||||||
Path path = configPath.getParent();
|
Path path = configPath.getParent();
|
||||||
themeInfo.setDirectory(path.toString());
|
themeInfo.setDirectory(path.toString());
|
||||||
|
|||||||
@@ -13,10 +13,11 @@ import me.qwq.doghouse.pojo.dto.LayPageReq;
|
|||||||
import me.qwq.doghouse.util.CookieUtils;
|
import me.qwq.doghouse.util.CookieUtils;
|
||||||
import me.qwq.doghouse.util.SessionUtils;
|
import me.qwq.doghouse.util.SessionUtils;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
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.MPJLambdaWrapper;
|
||||||
import com.github.yulichang.wrapper.enums.DefaultFuncEnum;
|
import com.github.yulichang.wrapper.enums.DefaultFuncEnum;
|
||||||
|
|
||||||
@@ -669,8 +670,10 @@ public class WikiService extends AbstractPostService<WikiService, WikiConfig> {
|
|||||||
Cookie cookie = CookieUtils.getCookie(request, UNFOLDED_WIKIS);
|
Cookie cookie = CookieUtils.getCookie(request, UNFOLDED_WIKIS);
|
||||||
if (cookie == null) new ArrayList<>();
|
if (cookie == null) new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
JSONArray ja = JSONArray.parse(cookie.getValue());
|
return new ObjectMapper().readValue(
|
||||||
return ja.toJavaList(Long.class);
|
cookie.getValue(),
|
||||||
|
new TypeReference<List<Long>>() {}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
37
src/main/java/me/qwq/doghouse/util/DateUtils.java
Normal file
37
src/main/java/me/qwq/doghouse/util/DateUtils.java
Normal file
@@ -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<String, DateTimeFormatter> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
18
src/main/java/me/qwq/doghouse/util/JsonUtils.java
Normal file
18
src/main/java/me/qwq/doghouse/util/JsonUtils.java
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
<ul class="tags-ul">
|
<ul class="tags-ul">
|
||||||
<th:block th:each="tag, i : ${@metaService.listMetaCount(MetaTypeEnum.TAG, null)}">
|
<th:block th:each="tag, i : ${@metaService.listMetaCount(MetaTypeEnum.TAG, null)}">
|
||||||
<li
|
<li
|
||||||
th:with="tagJson=${T(com.alibaba.fastjson2.JSONObject).toJSONString(tag)}"
|
th:with="tagJson=${JsonUtils.toJson(tag)}"
|
||||||
th:attr="mid=${tag.mid},tag=${tagJson}">
|
th:attr="mid=${tag.mid},tag=${tagJson}">
|
||||||
<a
|
<a
|
||||||
th:href="@{${'/admin/v2/post/?tagId=' + tag.mid}}"
|
th:href="@{${'/admin/v2/post/?tagId=' + tag.mid}}"
|
||||||
|
|||||||
Reference in New Issue
Block a user