diff --git a/blog4j-api/src/main/java/com/blog4j/api/client/FeignServer.java b/blog4j-api/src/main/java/com/blog4j/api/client/FeignServer.java
index 3e82831..10560b5 100644
--- a/blog4j-api/src/main/java/com/blog4j/api/client/FeignServer.java
+++ b/blog4j-api/src/main/java/com/blog4j/api/client/FeignServer.java
@@ -1,6 +1,7 @@
package com.blog4j.api.client;
import com.blog4j.api.vo.NoticeEmailVo;
+import com.blog4j.common.model.LogVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -67,4 +68,12 @@ public interface FeignServer {
@PostMapping("/sendEmailToUserForApproveOrganization")
void sendEmailToUserForApproveOrganization(@RequestParam("toEmail") String toEmail,
@RequestParam("organizationName") String organizationName);
+
+ /**
+ * 添加日志
+ *
+ * @param logVo 日志信息
+ */
+ @PostMapping("/addLog")
+ void addLog(@RequestBody LogVo logVo);
}
diff --git a/blog4j-article/pom.xml b/blog4j-article/pom.xml
index 41cbce3..e83393e 100644
--- a/blog4j-article/pom.xml
+++ b/blog4j-article/pom.xml
@@ -45,6 +45,10 @@
blog4j-api
1.0-SNAPSHOT
+
+ org.liquibase
+ liquibase-core
+
diff --git a/blog4j-article/src/main/java/com/blog4j/article/aop/LogAspect.java b/blog4j-article/src/main/java/com/blog4j/article/aop/LogAspect.java
new file mode 100644
index 0000000..6393b6c
--- /dev/null
+++ b/blog4j-article/src/main/java/com/blog4j/article/aop/LogAspect.java
@@ -0,0 +1,131 @@
+package com.blog4j.article.aop;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.json.JSONUtil;
+import com.blog4j.api.client.FeignUser;
+import com.blog4j.api.vo.UserInfoVo;
+import com.blog4j.article.component.AsyncService;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.LogResultEnum;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
+import com.blog4j.common.exception.Blog4jException;
+import com.blog4j.common.exception.InvalidRequestException;
+import com.blog4j.common.model.LogVo;
+import com.blog4j.common.utils.CommonUtil;
+import com.blog4j.common.utils.OperationLogHolder;
+import com.blog4j.common.utils.RealIpUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/18 14:30
+ **/
+@Slf4j
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@Component
+@Aspect
+public class LogAspect {
+ private final FeignUser feignUser;
+ private final AsyncService asyncService;
+
+ @Pointcut("@annotation(com.blog4j.common.annotation.OperationLog)")
+ public void log() {}
+
+ @AfterThrowing(pointcut = "log()", throwing = "e")
+ public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
+ String errMsg = e.getMessage();
+ if (e instanceof Blog4jException) {
+ Blog4jException blog4jException = (Blog4jException) e;
+ errMsg = blog4jException.getErrMsg();
+ } else if (e instanceof InvalidRequestException) {
+ InvalidRequestException invalidRequestException = (InvalidRequestException) e;
+ errMsg = invalidRequestException.getErrMsg();
+ }
+
+ log.error("接口异常: [{}]", errMsg);
+ LogVo logVo = OperationLogHolder.getLogVo();
+ logVo.setResult(LogResultEnum.FAIL.getResult()).setErrMsg(errMsg);
+ OperationLogHolder.setLogVo(logVo);
+ }
+
+ @Around("log()")
+ public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
+ long startTime = System.currentTimeMillis();
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ Method method = signature.getMethod();
+ LogVo logVo = getAnnotationInfo(method);
+ logVo.setParam(JSONUtil.toJsonStr(joinPoint.getArgs()))
+ .setResult(LogResultEnum.SUCCESS.getResult());
+ // 方法名
+ String methodName = joinPoint.getSignature().getName();
+ logVo.setMethodName(methodName);
+
+ // 得到request
+ HttpServletRequest request = ((ServletRequestAttributes)
+ Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+ logVo.setIpAddress(RealIpUtil.getRealIp(request)).setUrl(request.getRequestURL().toString());
+ UserInfoVo userInfo = getUserInfo();
+ if (Objects.nonNull(userInfo)) {
+ logVo.setUserId(userInfo.getUserId()).setUserName(userInfo.getUserName());
+ }
+
+ String className = joinPoint.getTarget().getClass().getName();
+ logVo.setClassName(className)
+ .setTime(System.currentTimeMillis() - startTime)
+ .setCreateTime(CommonUtil.getCurrentDateTime());
+ OperationLogHolder.setLogVo(logVo);
+ return joinPoint.proceed();
+ }
+
+ @After("log()")
+ public void doAfter(JoinPoint joinPoint) {
+ LogVo logVo = OperationLogHolder.getLogVo();
+ OperationLogHolder.removeLogVo();
+ asyncService.addLog(logVo);
+ }
+
+ private LogVo getAnnotationInfo(Method method ) {
+ LogVo log = new LogVo();
+ OperationLog annotation = method.getAnnotation(OperationLog.class);
+ if (annotation != null) {
+ OperationTypeEnum operationTypeEnum = annotation.operationType();
+ ModuleTypeEnum module = annotation.module();
+ String description = annotation.description();
+ log.setModuleType(module.getType())
+ .setOperationType(operationTypeEnum.getType())
+ .setDescription(description);
+ }
+ return log;
+ }
+
+ private UserInfoVo getUserInfo() {
+ String userId = "";
+ try {
+ userId = StpUtil.getLoginIdAsString();
+ return feignUser.getUserInfoByUserId(userId);
+ } catch (Exception exception) {
+ log.warn("user not login");
+ }
+ return null;
+ }
+}
diff --git a/blog4j-article/src/main/java/com/blog4j/article/api/ApiApplyArticleController.java b/blog4j-article/src/main/java/com/blog4j/article/api/ApiApplyArticleController.java
deleted file mode 100644
index a1dd663..0000000
--- a/blog4j-article/src/main/java/com/blog4j/article/api/ApiApplyArticleController.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.blog4j.article.api;
-
-import cn.dev33.satoken.annotation.SaCheckLogin;
-import cn.dev33.satoken.annotation.SaCheckRole;
-import cn.dev33.satoken.annotation.SaMode;
-import com.blog4j.article.entity.ApplyArticleEntity;
-import com.blog4j.article.service.ApplyArticleService;
-import com.blog4j.article.vo.req.ApplyArticleListReqVo;
-import com.blog4j.common.model.Result;
-import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
-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 javax.validation.Valid;
-import java.util.List;
-
-/**
- * @author 98k灬
- * @version v1.0.0
- * @Description : 功能描述
- * @Create on : 2024/7/24 12:15
- **/
-@RestController
-@RequestMapping("/api/apply-article")
-@RequiredArgsConstructor(onConstructor_ = @Autowired)
-public class ApiApplyArticleController {
- private final ApplyArticleService articleService;
-}
diff --git a/blog4j-article/src/main/java/com/blog4j/article/api/ApiArticleController.java b/blog4j-article/src/main/java/com/blog4j/article/api/ApiArticleController.java
index 3883ddd..8c622cd 100644
--- a/blog4j-article/src/main/java/com/blog4j/article/api/ApiArticleController.java
+++ b/blog4j-article/src/main/java/com/blog4j/article/api/ApiArticleController.java
@@ -11,6 +11,8 @@ import com.blog4j.article.vo.req.UserArticleReqVo;
import com.blog4j.article.vo.resp.ArticleCategoryNumsRespVo;
import com.blog4j.article.vo.resp.ArticleDetailRespVo;
import com.blog4j.article.vo.resp.ArticleRespVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
import com.blog4j.common.model.Result;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
@@ -45,6 +47,7 @@ public class ApiArticleController {
* @param reqVo 查询条件
* @return 文章列表
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取文章列表(门户端)")
@SaIgnore
@PostMapping("/portalArticleList")
public Result portalArticleList(@RequestBody PortalArticleListReqVo reqVo) {
@@ -58,6 +61,7 @@ public class ApiArticleController {
* @param articleId 文章ID
* @return 文章信息
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "根据文章ID获取文章信息")
@GetMapping("/info/{articleId}")
public Result info(@PathVariable("articleId") String articleId) {
ArticleDetailRespVo respVo = articleService.articleInfo(articleId);
@@ -69,6 +73,7 @@ public class ApiArticleController {
*
* @return 文章列表
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取排行榜的文章")
@SaIgnore
@GetMapping("/getViewsArticle")
public Result getWeekViewsArticle() {
@@ -82,6 +87,7 @@ public class ApiArticleController {
* @param articleId 文章ID
* @return 成功
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取文章浏览量")
@SaIgnore
@GetMapping("/article_views/{articleId}")
public Result articleViews(@PathVariable("articleId") String articleId) {
@@ -95,6 +101,7 @@ public class ApiArticleController {
* @param articleId 文章ID
* @return 文章信息
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取当前文章的上一篇和下一篇")
@SaIgnore
@GetMapping("/getNextAndPreviousArticle/{articleId}")
public Result getNextAndPreviousArticle(@PathVariable("articleId") String articleId) {
@@ -108,6 +115,7 @@ public class ApiArticleController {
* @param articleId 文章ID
* @return 推荐文章列表
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取推荐文章列表")
@SaIgnore
@GetMapping("/getRecommendArticle/{articleId}")
public Result getRecommendArticle(@PathVariable("articleId") String articleId) {
@@ -120,6 +128,7 @@ public class ApiArticleController {
*
* @return 最新文章列表
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取最新文章列表")
@SaIgnore
@GetMapping("/getNewArticleList")
public Result getNewArticleList() {
@@ -133,6 +142,7 @@ public class ApiArticleController {
* @param reqVo 请求信息
* @return 文章信息
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "根据分类ID获取文章信息")
@SaIgnore
@PostMapping("/getByCategoryId")
public Result getByCategoryId(@RequestBody @Valid ArticleByCategoryIdReqVo reqVo) {
@@ -146,6 +156,7 @@ public class ApiArticleController {
* @param reqVo 请求
* @return 组织信息
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "根据组织ID获取组织文章列表")
@SaIgnore
@PostMapping("/organizationArticleList")
public Result organizationArticleList(@RequestBody @Valid OrganizationArticleListReqVo reqVo) {
@@ -159,6 +170,7 @@ public class ApiArticleController {
* @param reqVo 请求信息
* @return 用户文章
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取用户的文章")
@PostMapping("/getUserArticle")
public Result getUserArticle(@RequestBody @Valid UserArticleReqVo reqVo) {
PageInfo pageInfo = articleService.getUserArticle(reqVo);
@@ -170,6 +182,7 @@ public class ApiArticleController {
*
* @return 用户的文章数、分类数
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取用户的文章数、分类数")
@GetMapping("/getArticleCategoryNums")
public Result getArticleCategoryNums(@RequestParam(value = "userId") String userId) {
ArticleCategoryNumsRespVo respVo = articleService.getArticleCategoryNums(userId);
@@ -182,6 +195,7 @@ public class ApiArticleController {
* @param reqVo 请求信息
* @return 收藏文章
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取用户的收藏文章")
@PostMapping("/getFavoriteArticleByUserId")
public Result getFavoriteArticleByUserId(@RequestBody @Valid FavoriteArticleByUserIdReqVo reqVo) {
PageInfo pageInfo = articleService.getFavoriteArticleByUserId(reqVo);
diff --git a/blog4j-article/src/main/java/com/blog4j/article/api/ApiCategoryController.java b/blog4j-article/src/main/java/com/blog4j/article/api/ApiCategoryController.java
index f1a0bd5..a9aec27 100644
--- a/blog4j-article/src/main/java/com/blog4j/article/api/ApiCategoryController.java
+++ b/blog4j-article/src/main/java/com/blog4j/article/api/ApiCategoryController.java
@@ -7,6 +7,9 @@ import com.blog4j.article.service.CategoryService;
import com.blog4j.article.vo.req.CategoryByUserIdReqVo;
import com.blog4j.article.vo.req.CategoryListReqVo;
import com.blog4j.article.vo.resp.CategoryRespVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
import com.blog4j.common.model.Result;
import com.github.pagehelper.PageInfo;
import javafx.print.Collation;
@@ -40,6 +43,9 @@ public class ApiCategoryController {
* @param categoryId 分类ID
* @return 分类信息
*/
+ @OperationLog(operationType= OperationTypeEnum.QUERY,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "根据分类ID查询分类信息")
@GetMapping("/info/{categoryId}")
public Result info(@PathVariable("categoryId") String categoryId) {
CategoryEntity category = categoryService.getById(categoryId);
@@ -52,6 +58,9 @@ public class ApiCategoryController {
* @param userId 创建者ID
* @return 分类列表
*/
+ @OperationLog(operationType= OperationTypeEnum.QUERY,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "根据创建者ID查询分类列表")
@GetMapping("/getInfoByCreaterId/{userId}")
public Result getInfoByCreaterId(@PathVariable("userId") String userId) {
List category = categoryService.getInfoByCreaterId(userId);
@@ -64,6 +73,9 @@ public class ApiCategoryController {
* @param reqVo 请求信息
* @return 分类列表
*/
+ @OperationLog(operationType= OperationTypeEnum.QUERY,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "门户端查询分类列表")
@SaIgnore
@PostMapping("/category_list")
public Result categoryList(@RequestBody @Valid CategoryListReqVo reqVo) {
@@ -77,6 +89,9 @@ public class ApiCategoryController {
* @param reqVo 请求信息
* @return 分类信息列表
*/
+ @OperationLog(operationType= OperationTypeEnum.QUERY,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "根据用户ID获取分类信息列表")
@PostMapping("/getCategoryByUserId")
public Result getCategoryByUserId(@RequestBody @Valid CategoryByUserIdReqVo reqVo) {
PageInfo pageInfo = categoryService.getCategoryByUserId(reqVo);
diff --git a/blog4j-article/src/main/java/com/blog4j/article/api/ApiCommentController.java b/blog4j-article/src/main/java/com/blog4j/article/api/ApiCommentController.java
index 3724a35..519199d 100644
--- a/blog4j-article/src/main/java/com/blog4j/article/api/ApiCommentController.java
+++ b/blog4j-article/src/main/java/com/blog4j/article/api/ApiCommentController.java
@@ -5,6 +5,9 @@ import com.blog4j.article.entity.CommentEntity;
import com.blog4j.article.model.Comment;
import com.blog4j.article.service.CommentService;
import com.blog4j.article.vo.req.CommentReqVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
import com.blog4j.common.model.Result;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
@@ -34,6 +37,7 @@ public class ApiCommentController {
* @param reqVo 请求信息
* @return 评论列表
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取文章评论列表")
@SaIgnore
@PostMapping("/commentList")
public Result commentList(@RequestBody @Valid CommentReqVo reqVo) {
diff --git a/blog4j-article/src/main/java/com/blog4j/article/api/ApiLabelController.java b/blog4j-article/src/main/java/com/blog4j/article/api/ApiLabelController.java
index c0098af..e6723dd 100644
--- a/blog4j-article/src/main/java/com/blog4j/article/api/ApiLabelController.java
+++ b/blog4j-article/src/main/java/com/blog4j/article/api/ApiLabelController.java
@@ -3,6 +3,9 @@ package com.blog4j.article.api;
import com.blog4j.article.entity.LabelEntity;
import com.blog4j.article.service.LabelService;
import com.blog4j.article.vo.req.LabelListReqVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
import com.blog4j.common.model.Result;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
@@ -35,6 +38,9 @@ public class ApiLabelController {
* @param categoryId 分类ID
* @return 标签信息列表
*/
+ @OperationLog(operationType= OperationTypeEnum.QUERY,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "根据分类ID查询标签信息列表")
@GetMapping("/getByCategoryId/{categoryId}")
public Result getByCategoryId(@PathVariable("categoryId") String categoryId) {
List list = labelService.getByCategoryId(categoryId);
@@ -46,6 +52,9 @@ public class ApiLabelController {
*
* @return 标签列表
*/
+ @OperationLog(operationType= OperationTypeEnum.QUERY,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "根据创建者ID获取标签列表")
@GetMapping("/getListByCreaterId")
public Result getListByCreaterId() {
List list = labelService.getListByCreaterId();
@@ -58,6 +67,9 @@ public class ApiLabelController {
* @param reqVo 请求信息
* @return 标签列表
*/
+ @OperationLog(operationType= OperationTypeEnum.QUERY,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "标签列表查询")
@PostMapping("/list")
public Result list(@RequestBody @Valid LabelListReqVo reqVo) {
List list = labelService.getLabelList(reqVo);
@@ -70,6 +82,9 @@ public class ApiLabelController {
* @param labelId 标签ID
* @return 详情信息
*/
+ @OperationLog(operationType= OperationTypeEnum.QUERY,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "根据标签ID查询详情信息")
@GetMapping("/info/{labelId}")
public Result info(@PathVariable("labelId") String labelId) {
LabelEntity label = labelService.getById(labelId);
diff --git a/blog4j-article/src/main/java/com/blog4j/article/component/AsyncService.java b/blog4j-article/src/main/java/com/blog4j/article/component/AsyncService.java
index 3c87087..193cdc8 100644
--- a/blog4j-article/src/main/java/com/blog4j/article/component/AsyncService.java
+++ b/blog4j-article/src/main/java/com/blog4j/article/component/AsyncService.java
@@ -8,6 +8,7 @@ import com.blog4j.api.vo.NoticeEmailVo;
import com.blog4j.article.entity.ArticleEntity;
import com.blog4j.article.mapper.ArticleMapper;
import com.blog4j.article.service.impl.ArticleServiceImpl;
+import com.blog4j.common.model.LogVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
@@ -107,4 +108,9 @@ public class AsyncService {
feignServer.sendSystemEmailToArticleCreater(email, articleTitle);
log.info("====================文章审批后,给创建者发送邮件通知成功====================");
}
+
+ @Async
+ public void addLog(LogVo logVo) {
+ feignServer.addLog(logVo);
+ }
}
diff --git a/blog4j-article/src/main/java/com/blog4j/article/controller/ApplyArticleController.java b/blog4j-article/src/main/java/com/blog4j/article/controller/ApplyArticleController.java
index ae6b3ba..21c0924 100644
--- a/blog4j-article/src/main/java/com/blog4j/article/controller/ApplyArticleController.java
+++ b/blog4j-article/src/main/java/com/blog4j/article/controller/ApplyArticleController.java
@@ -7,6 +7,9 @@ import com.blog4j.article.service.ApplyArticleService;
import com.blog4j.article.vo.req.ApplyArticleListReqVo;
import com.blog4j.article.vo.req.ApproveArticleReqVo;
import com.blog4j.article.vo.resp.ApplyArticleRespVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
import com.blog4j.common.model.Result;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
@@ -31,11 +34,14 @@ public class ApplyArticleController {
private final ApplyArticleService applyArticleService;
/**
- * 分页加条件查询申请文章信息列表
+ * 分页查询申请文章信息列表
*
* @param reqVo 请求
* @return 文章信息列表
*/
+ @OperationLog(operationType= OperationTypeEnum.QUERY,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "分页查询申请文章信息列表")
@SaCheckLogin
@PostMapping("/list")
public Result list(@RequestBody @Valid ApplyArticleListReqVo reqVo) {
@@ -49,6 +55,9 @@ public class ApplyArticleController {
* @param reqVo 审批信息
* @return 审批成功
*/
+ @OperationLog(operationType= OperationTypeEnum.EDIT,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "审批文章")
@SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN"}, mode = SaMode.OR)
@PostMapping("/approve")
public Result approve(@RequestBody @Valid ApproveArticleReqVo reqVo) {
diff --git a/blog4j-article/src/main/java/com/blog4j/article/controller/ArticleController.java b/blog4j-article/src/main/java/com/blog4j/article/controller/ArticleController.java
index bb0065d..d83cdf1 100644
--- a/blog4j-article/src/main/java/com/blog4j/article/controller/ArticleController.java
+++ b/blog4j-article/src/main/java/com/blog4j/article/controller/ArticleController.java
@@ -16,6 +16,8 @@ import com.blog4j.article.vo.req.FavoriteReqVo;
import com.blog4j.article.vo.req.LikeArticleReqVo;
import com.blog4j.article.vo.resp.ArticleDetailRespVo;
import com.blog4j.article.vo.resp.ArticleStatusRespVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
import com.blog4j.common.model.Result;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
@@ -52,6 +54,7 @@ public class ArticleController {
* @param articleListReqVo 查询条件
* @return 文章列表
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取文章列表(后台管理端)")
@SaCheckPermission(value = "ARTICLE:LIST")
@PostMapping("/list")
public Result list(@RequestBody ArticleListReqVo articleListReqVo) {
diff --git a/blog4j-article/src/main/java/com/blog4j/article/controller/CategoryController.java b/blog4j-article/src/main/java/com/blog4j/article/controller/CategoryController.java
index 0c06a09..60a3993 100644
--- a/blog4j-article/src/main/java/com/blog4j/article/controller/CategoryController.java
+++ b/blog4j-article/src/main/java/com/blog4j/article/controller/CategoryController.java
@@ -11,6 +11,9 @@ import com.blog4j.article.vo.req.CreateCategoryReqVo;
import com.blog4j.article.vo.req.DeleteCategoryReqVo;
import com.blog4j.article.vo.req.SaveCategoryLabelReqVo;
import com.blog4j.article.vo.resp.CategoryRespVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
import com.blog4j.common.model.Result;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
@@ -42,6 +45,9 @@ public class CategoryController {
* @param reqVo 待删除的分类ID列表
* @return 删除成功
*/
+ @OperationLog(operationType= OperationTypeEnum.DELETE,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "删除分类信息")
@SaCheckPermission(value = "CATEGORY:DELETE")
@PostMapping ("/delete")
public Result delete(@RequestBody @Valid DeleteCategoryReqVo reqVo) {
@@ -55,6 +61,9 @@ public class CategoryController {
* @param reqVo 分类信息
* @return 创建成功
*/
+ @OperationLog(operationType= OperationTypeEnum.INSERT,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "创建分类信息")
@SaCheckPermission(value = "CATEGORY:ADD")
@PostMapping("/create")
public Result create(@RequestBody @Valid CreateCategoryReqVo reqVo) {
@@ -68,6 +77,9 @@ public class CategoryController {
* @param reqVo 分类信息
* @return 编辑成功
*/
+ @OperationLog(operationType= OperationTypeEnum.EDIT,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "编辑分类信息")
@PostMapping("/edit")
public Result edit(@RequestBody @Valid CategoryEditReqVo reqVo) {
categoryService.edit(reqVo);
@@ -80,6 +92,9 @@ public class CategoryController {
* @param reqVo 请求信息
* @return 保存成功
*/
+ @OperationLog(operationType= OperationTypeEnum.INSERT,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "保存分类下的标签信息")
@PostMapping("/saveCategoryLabel")
public Result saveCategoryLabel(@RequestBody @Valid SaveCategoryLabelReqVo reqVo) {
categoryService.saveCategoryLabel(reqVo);
@@ -92,6 +107,7 @@ public class CategoryController {
* @param reqVo 查询条件
* @return 文章分类信息
*/
+ @OperationLog(module= ModuleTypeEnum.ARTICLE, description = "获取文章分类信息列表")
@SaCheckPermission("CATEGORY:LIST")
@PostMapping("/list")
public Result list(@RequestBody @Valid CategoryListReqVo reqVo) {
diff --git a/blog4j-article/src/main/java/com/blog4j/article/controller/CommentController.java b/blog4j-article/src/main/java/com/blog4j/article/controller/CommentController.java
index 94a66c7..8a4e24d 100644
--- a/blog4j-article/src/main/java/com/blog4j/article/controller/CommentController.java
+++ b/blog4j-article/src/main/java/com/blog4j/article/controller/CommentController.java
@@ -3,6 +3,9 @@ package com.blog4j.article.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.blog4j.article.service.CommentService;
import com.blog4j.article.vo.req.SendCommentReqVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
import com.blog4j.common.model.Result;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
@@ -26,11 +29,14 @@ public class CommentController {
private final CommentService commentService;
/**
- * 给文章评论
+ * 新增文章评论
*
* @param reqVo 评论信息
* @return 评论成功
*/
+ @OperationLog(operationType= OperationTypeEnum.INSERT,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "新增文章评论")
@SaCheckLogin
@PostMapping("/sendComment")
public Result sendComment(@RequestBody @Valid SendCommentReqVo reqVo) {
diff --git a/blog4j-article/src/main/java/com/blog4j/article/controller/LabelController.java b/blog4j-article/src/main/java/com/blog4j/article/controller/LabelController.java
index 34d6c2f..50927ff 100644
--- a/blog4j-article/src/main/java/com/blog4j/article/controller/LabelController.java
+++ b/blog4j-article/src/main/java/com/blog4j/article/controller/LabelController.java
@@ -5,6 +5,9 @@ import com.blog4j.article.service.LabelService;
import com.blog4j.article.vo.req.CreateLabelReqVo;
import com.blog4j.article.vo.req.DeleteLabelReqVo;
import com.blog4j.article.vo.req.EditLabelReqVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
import com.blog4j.common.model.Result;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
@@ -33,6 +36,9 @@ public class LabelController {
* @param reqVo 请求信息
* @return 编辑成功
*/
+ @OperationLog(operationType= OperationTypeEnum.EDIT,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "编辑标签信息")
@SaCheckPermission("LABEL:EDIT")
@PostMapping("/edit")
public Result edit(@RequestBody @Valid EditLabelReqVo reqVo) {
@@ -46,6 +52,9 @@ public class LabelController {
* @param reqVo 请求信息
* @return 创建成功
*/
+ @OperationLog(operationType= OperationTypeEnum.INSERT,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "创建标签信息")
@SaCheckPermission("LABEL:ADD")
@PostMapping("/create")
public Result create(@RequestBody @Valid CreateLabelReqVo reqVo) {
@@ -59,6 +68,9 @@ public class LabelController {
* @param reqVo 请求信息
* @return 删除成功
*/
+ @OperationLog(operationType= OperationTypeEnum.DELETE,
+ module= ModuleTypeEnum.ARTICLE,
+ description = "删除标签信息")
@SaCheckPermission("LABEL:DELETE")
@PostMapping("/delete")
public Result delete(@RequestBody @Valid DeleteLabelReqVo reqVo) {
diff --git a/blog4j-article/src/main/resources/application-dev.yml b/blog4j-article/src/main/resources/application-dev.yml
index ced1e89..f16ee36 100644
--- a/blog4j-article/src/main/resources/application-dev.yml
+++ b/blog4j-article/src/main/resources/application-dev.yml
@@ -1,11 +1,13 @@
spring:
+ liquibase:
+ change-log: classpath:/liquibase/master.xml
datasource:
# driver-class-name: com.mysql.cj.jdbc.Driver
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
# url: jdbc:mysql://sh-cdb-b593hl8o.sql.tencentcdb.com:63556/blog4j-article?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true
- url: jdbc:p6spy:mysql://sh-cdb-b593hl8o.sql.tencentcdb.com:63556/blog4j-article?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true
- username: blog4j_article_dev
- password: 4897458Hk!@
+ url: jdbc:p6spy:mysql://localhost:3306/blog4j-article?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true
+ username: root
+ password: 4897458hk
cloud:
nacos:
discovery:
diff --git a/blog4j-article/src/main/resources/application-prod.yml b/blog4j-article/src/main/resources/application-prod.yml
index fabdc39..13b462f 100644
--- a/blog4j-article/src/main/resources/application-prod.yml
+++ b/blog4j-article/src/main/resources/application-prod.yml
@@ -1,8 +1,10 @@
spring:
+# liquibase:
+# change-log: classpath:/liquibase/master.xml
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://sh-cdb-b593hl8o.sql.tencentcdb.com:63556/blog4j-article?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true
- username: blog4j_article_dev
+ url: jdbc:mysql://sh-cdb-m53tmbii.sql.tencentcdb.com:20855/blog4j-article?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true
+ username: root
password: 4897458Hk!@
cloud:
nacos:
diff --git a/blog4j-article/src/main/resources/application.yml b/blog4j-article/src/main/resources/application.yml
index b4aa084..883f8fb 100644
--- a/blog4j-article/src/main/resources/application.yml
+++ b/blog4j-article/src/main/resources/application.yml
@@ -16,4 +16,10 @@ sa-token:
jwt-secret-key: asdasdasifhueuiwyurfewbfjsdafjk
token-name: Authentication
timeout: 86400
- is-concurrent: false
\ No newline at end of file
+ is-concurrent: false
+
+jasypt:
+ encryptor:
+ password: blog4j_test
+ algorithm: PBEWithMD5AndDES
+ iv-generator-classname: org.jasypt.iv.NoIvGenerator
\ No newline at end of file
diff --git a/blog4j-article/src/main/resources/liquibase/changelog/database_change.xml b/blog4j-article/src/main/resources/liquibase/changelog/database_change.xml
new file mode 100644
index 0000000..73558a6
--- /dev/null
+++ b/blog4j-article/src/main/resources/liquibase/changelog/database_change.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blog4j-article/src/main/resources/liquibase/master.xml b/blog4j-article/src/main/resources/liquibase/master.xml
new file mode 100644
index 0000000..2b9d02d
--- /dev/null
+++ b/blog4j-article/src/main/resources/liquibase/master.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/blog4j-article/src/main/resources/liquibase/upgrade/20240823/t_article_init_ddl_20240823123545.sql b/blog4j-article/src/main/resources/liquibase/upgrade/20240823/t_article_init_ddl_20240823123545.sql
new file mode 100644
index 0000000..1a384e9
--- /dev/null
+++ b/blog4j-article/src/main/resources/liquibase/upgrade/20240823/t_article_init_ddl_20240823123545.sql
@@ -0,0 +1,162 @@
+/*
+ Navicat MySQL Data Transfer
+
+ Source Server : blog4j-user-dev
+ Source Server Type : MySQL
+ Source Server Version : 50736 (5.7.36-txsql-log)
+ Source Host : sh-cdb-b593hl8o.sql.tencentcdb.com:63556
+ Source Schema : blog4j-article
+
+ Target Server Type : MySQL
+ Target Server Version : 50736 (5.7.36-txsql-log)
+ File Encoding : 65001
+
+ Date: 23/08/2024 12:36:59
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for t_apply_article
+-- ----------------------------
+DROP TABLE IF EXISTS `t_apply_article`;
+CREATE TABLE `t_apply_article` (
+ `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键',
+ `article_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章ID',
+ `article_title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章标题',
+ `apply_user_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '申请人ID',
+ `apply_user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '申请人名称',
+ `apply_user_role_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '申请人的角色ID',
+ `apply_user_role_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '申请人的角色名称',
+ `organization_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组织ID',
+ `organization_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组织名称',
+ `deleted` int(11) NOT NULL DEFAULT 0 COMMENT '是否已被删除',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE INDEX `idx_uni_article_id`(`article_id`) USING BTREE COMMENT '文章ID唯一索引'
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '文章审批信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for t_article
+-- ----------------------------
+DROP TABLE IF EXISTS `t_article`;
+CREATE TABLE `t_article` (
+ `article_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章ID',
+ `category_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '分类ID',
+ `category_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '分类名称',
+ `label_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标签ID',
+ `label_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标签名称',
+ `cover` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章封面',
+ `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章标题',
+ `md_content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章内容',
+ `html_content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章html内容',
+ `author_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章的作者ID',
+ `author_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章的作者名称',
+ `status` int(11) NOT NULL COMMENT '文章状态(1:草稿 2:待发布 3:已发布)',
+ `approve_status` int(11) NOT NULL COMMENT '审批状态(1:待审批 2:审批通过 3:审批拒绝)',
+ `approve_user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '审批人用户ID',
+ `approve_user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '审批人用户名称',
+ `approve_time` datetime NULL DEFAULT NULL COMMENT '审批时间',
+ `approve_message` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '审批留言',
+ `article_type` int(11) NOT NULL COMMENT '文章类型(1:原创 2:转载)',
+ `curation_link` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '转载的链接',
+ `summary` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '摘要',
+ `public_type` int(11) NOT NULL COMMENT '文章公开类型(1:仅对自己公开 2:仅对组织内成员公开 3:所有人公开)',
+ `cron_release_time` datetime NULL DEFAULT NULL COMMENT '定时发布的时间',
+ `timed_release` int(11) NOT NULL COMMENT '是否定时发布',
+ `publish_user_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '发布人用户ID',
+ `stick` int(11) NOT NULL DEFAULT 0 COMMENT '是否置顶(1:是 0:否)',
+ `allow_comment` int(11) NOT NULL COMMENT '是否允许评论',
+ `allow_download` int(11) NOT NULL COMMENT '是否允许下载',
+ `views` int(11) NOT NULL COMMENT '浏览数',
+ `likes` int(11) NOT NULL COMMENT '点赞数',
+ `auto_publish` int(11) NOT NULL DEFAULT 0 COMMENT '是否自动发布(1:是 0:否)',
+ `deleted` int(11) NOT NULL DEFAULT 0 COMMENT '是否已被删除',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ PRIMARY KEY (`article_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '文章信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for t_category
+-- ----------------------------
+DROP TABLE IF EXISTS `t_category`;
+CREATE TABLE `t_category` (
+ `category_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '分类ID',
+ `category_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '分类代码',
+ `category_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '分类名称',
+ `cover` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '背景图片',
+ `status` int(11) NOT NULL COMMENT '状态',
+ `creater` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建者ID',
+ `creater_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建者名称',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ PRIMARY KEY (`category_id`) USING BTREE,
+ UNIQUE INDEX `idx_uni_name_userid`(`category_name`, `creater`) USING BTREE,
+ UNIQUE INDEX `idx_uni_code_userid`(`category_code`, `creater`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '文章分类信息' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for t_category_label_rel
+-- ----------------------------
+DROP TABLE IF EXISTS `t_category_label_rel`;
+CREATE TABLE `t_category_label_rel` (
+ `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `category_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '分类ID',
+ `label_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标签ID',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE INDEX `idx_uni_categoryId_lableId`(`category_id`, `label_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 43 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '分类标签关系表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for t_comment
+-- ----------------------------
+DROP TABLE IF EXISTS `t_comment`;
+CREATE TABLE `t_comment` (
+ `comment_id` int(20) NOT NULL AUTO_INCREMENT COMMENT '评论ID',
+ `parent_id` int(20) NOT NULL COMMENT '评论父ID',
+ `article_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章ID',
+ `content` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '评论内容',
+ `comment_user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '评论的作者ID',
+ `target_user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '被评论者的ID',
+ `deleted` int(11) NOT NULL DEFAULT 0 COMMENT '是否已被删除',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ PRIMARY KEY (`comment_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '文章评论信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for t_favorite
+-- ----------------------------
+DROP TABLE IF EXISTS `t_favorite`;
+CREATE TABLE `t_favorite` (
+ `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户ID',
+ `article_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章ID',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE INDEX `idx_uni_userid_articleid`(`user_id`, `article_id`) USING BTREE COMMENT '用户ID和文章ID唯一索引',
+ INDEX `idx_nor_article_id`(`article_id`) USING BTREE,
+ INDEX `idx_nor_user_id`(`user_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户收藏的文章信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for t_label
+-- ----------------------------
+DROP TABLE IF EXISTS `t_label`;
+CREATE TABLE `t_label` (
+ `label_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键',
+ `label_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标签代码',
+ `label_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标签名称',
+ `status` int(11) NOT NULL COMMENT '标签状态',
+ `creater` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建者用户ID',
+ `creater_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建者用户名称',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ PRIMARY KEY (`label_id`) USING BTREE,
+ UNIQUE INDEX `idx_uni_name_userid`(`label_name`, `creater`) USING BTREE,
+ UNIQUE INDEX `idx_uni_code_userid`(`label_code`, `creater`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '标签信息表' ROW_FORMAT = Dynamic;
+
+
diff --git a/blog4j-auth/src/main/java/com/blog4j/auth/AuthApplication.java b/blog4j-auth/src/main/java/com/blog4j/auth/AuthApplication.java
index ab22e30..0452598 100644
--- a/blog4j-auth/src/main/java/com/blog4j/auth/AuthApplication.java
+++ b/blog4j-auth/src/main/java/com/blog4j/auth/AuthApplication.java
@@ -4,6 +4,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.scheduling.annotation.EnableAsync;
/**
* @author 98k灬
@@ -14,6 +15,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.blog4j")
+@EnableAsync
public class AuthApplication {
/**
* 启动
diff --git a/blog4j-auth/src/main/java/com/blog4j/auth/aop/LogAspect.java b/blog4j-auth/src/main/java/com/blog4j/auth/aop/LogAspect.java
new file mode 100644
index 0000000..06952e1
--- /dev/null
+++ b/blog4j-auth/src/main/java/com/blog4j/auth/aop/LogAspect.java
@@ -0,0 +1,131 @@
+package com.blog4j.auth.aop;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.json.JSONUtil;
+import com.blog4j.api.client.FeignUser;
+import com.blog4j.api.vo.UserInfoVo;
+import com.blog4j.auth.component.AsyncService;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.LogResultEnum;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
+import com.blog4j.common.exception.Blog4jException;
+import com.blog4j.common.exception.InvalidRequestException;
+import com.blog4j.common.model.LogVo;
+import com.blog4j.common.utils.CommonUtil;
+import com.blog4j.common.utils.OperationLogHolder;
+import com.blog4j.common.utils.RealIpUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/18 14:30
+ **/
+@Slf4j
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@Component
+@Aspect
+public class LogAspect {
+ private final FeignUser feignUser;
+ private final AsyncService asyncService;
+
+ @Pointcut("@annotation(com.blog4j.common.annotation.OperationLog)")
+ public void log() {}
+
+ @AfterThrowing(pointcut = "log()", throwing = "e")
+ public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
+ String errMsg = e.getMessage();
+ if (e instanceof Blog4jException) {
+ Blog4jException blog4jException = (Blog4jException) e;
+ errMsg = blog4jException.getErrMsg();
+ } else if (e instanceof InvalidRequestException) {
+ InvalidRequestException invalidRequestException = (InvalidRequestException) e;
+ errMsg = invalidRequestException.getErrMsg();
+ }
+
+ log.error("接口异常: [{}]", errMsg);
+ LogVo logVo = OperationLogHolder.getLogVo();
+ logVo.setResult(LogResultEnum.FAIL.getResult()).setErrMsg(errMsg);
+ OperationLogHolder.setLogVo(logVo);
+ }
+
+ @Around("log()")
+ public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
+ long startTime = System.currentTimeMillis();
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ Method method = signature.getMethod();
+ LogVo logVo = getAnnotationInfo(method);
+ logVo.setParam(JSONUtil.toJsonStr(joinPoint.getArgs()))
+ .setResult(LogResultEnum.SUCCESS.getResult());
+ // 方法名
+ String methodName = joinPoint.getSignature().getName();
+ logVo.setMethodName(methodName);
+
+ // 得到request
+ HttpServletRequest request = ((ServletRequestAttributes)
+ Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+ logVo.setIpAddress(RealIpUtil.getRealIp(request)).setUrl(request.getRequestURL().toString());
+ UserInfoVo userInfo = getUserInfo();
+ if (Objects.nonNull(userInfo)) {
+ logVo.setUserId(userInfo.getUserId()).setUserName(userInfo.getUserName());
+ }
+
+ String className = joinPoint.getTarget().getClass().getName();
+ logVo.setClassName(className)
+ .setTime(System.currentTimeMillis() - startTime)
+ .setCreateTime(CommonUtil.getCurrentDateTime());
+ OperationLogHolder.setLogVo(logVo);
+ return joinPoint.proceed();
+ }
+
+ @After("log()")
+ public void doAfter(JoinPoint joinPoint) {
+ LogVo logVo = OperationLogHolder.getLogVo();
+ OperationLogHolder.removeLogVo();
+ asyncService.addLog(logVo);
+ }
+
+ private LogVo getAnnotationInfo(Method method ) {
+ LogVo log = new LogVo();
+ OperationLog annotation = method.getAnnotation(OperationLog.class);
+ if (annotation != null) {
+ OperationTypeEnum operationTypeEnum = annotation.operationType();
+ ModuleTypeEnum module = annotation.module();
+ String description = annotation.description();
+ log.setModuleType(module.getType())
+ .setOperationType(operationTypeEnum.getType())
+ .setDescription(description);
+ }
+ return log;
+ }
+
+ private UserInfoVo getUserInfo() {
+ String userId = "";
+ try {
+ userId = StpUtil.getLoginIdAsString();
+ return feignUser.getUserInfoByUserId(userId);
+ } catch (Exception exception) {
+ log.warn("user not login");
+ }
+ return null;
+ }
+}
diff --git a/blog4j-auth/src/main/java/com/blog4j/auth/api/ApiAuthController.java b/blog4j-auth/src/main/java/com/blog4j/auth/api/ApiAuthController.java
index 8fb35e6..c3125d8 100644
--- a/blog4j-auth/src/main/java/com/blog4j/auth/api/ApiAuthController.java
+++ b/blog4j-auth/src/main/java/com/blog4j/auth/api/ApiAuthController.java
@@ -10,6 +10,9 @@ import com.blog4j.auth.vo.req.LoginReqVo;
import com.blog4j.auth.vo.req.PhoneLoginReqVo;
import com.blog4j.auth.vo.req.WebLoginReqVo;
import com.blog4j.auth.vo.resp.AesKeyAndIvRespVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
import com.blog4j.common.model.Result;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.IOUtils;
@@ -43,6 +46,9 @@ public class ApiAuthController {
private final AuthService authService;
private final CaptchaService captchaService;
+ @OperationLog(operationType= OperationTypeEnum.LOGIN,
+ module= ModuleTypeEnum.AUTH,
+ description = "登录")
@SaIgnore()
@PostMapping("/login")
public Result login(@RequestBody @Valid LoginReqVo loginReqVo) {
@@ -52,6 +58,9 @@ public class ApiAuthController {
return Result.ok(loginContext.getSaTokenInfo());
}
+ @OperationLog(operationType= OperationTypeEnum.QUERY,
+ module= ModuleTypeEnum.AUTH,
+ description = "获取图形验证码")
@SaIgnore()
@GetMapping("/captcha.jpg")
public void captcha(HttpServletResponse response, @RequestParam String uuid) throws IOException {
@@ -66,6 +75,7 @@ public class ApiAuthController {
IOUtils.closeQuietly(out);
}
+ @OperationLog(module= ModuleTypeEnum.AUTH, description = "退出", operationType = OperationTypeEnum.DELETE)
@SaCheckLogin
@GetMapping("/logout/{userId}")
public Result logout(@PathVariable("userId") String userId) {
@@ -80,6 +90,9 @@ public class ApiAuthController {
return Result.ok(respVo);
}
+ @OperationLog(operationType= OperationTypeEnum.LOGIN,
+ module= ModuleTypeEnum.AUTH,
+ description = "手机号码登录")
@SaIgnore
@PostMapping("/phone_login")
public Result phoneLogin(@RequestBody @Valid PhoneLoginReqVo reqVo) {
@@ -87,6 +100,9 @@ public class ApiAuthController {
return Result.ok(tokenInfo);
}
+ @OperationLog(operationType= OperationTypeEnum.LOGIN,
+ module= ModuleTypeEnum.AUTH,
+ description = "门户端登录")
@SaIgnore
@PostMapping("/web_login")
public Result webLogin(@RequestBody @Valid WebLoginReqVo reqVo) {
diff --git a/blog4j-auth/src/main/java/com/blog4j/auth/component/AsyncService.java b/blog4j-auth/src/main/java/com/blog4j/auth/component/AsyncService.java
new file mode 100644
index 0000000..96ea41c
--- /dev/null
+++ b/blog4j-auth/src/main/java/com/blog4j/auth/component/AsyncService.java
@@ -0,0 +1,25 @@
+package com.blog4j.auth.component;
+
+import com.blog4j.api.client.FeignServer;
+import com.blog4j.common.model.LogVo;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/20 19:58
+ **/
+@Component
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+public class AsyncService {
+ private final FeignServer feignServer;
+
+ @Async
+ public void addLog(LogVo logVo) {
+ feignServer.addLog(logVo);
+ }
+}
diff --git a/blog4j-common/pom.xml b/blog4j-common/pom.xml
index 8d9553c..005ef04 100644
--- a/blog4j-common/pom.xml
+++ b/blog4j-common/pom.xml
@@ -74,6 +74,11 @@
spring-boot-configuration-processor
true
+
+ com.github.ulisesbocchio
+ jasypt-spring-boot-starter
+ 3.0.3
+
\ No newline at end of file
diff --git a/blog4j-common/src/main/java/com/blog4j/common/annotation/OperationLog.java b/blog4j-common/src/main/java/com/blog4j/common/annotation/OperationLog.java
new file mode 100644
index 0000000..06c6b9c
--- /dev/null
+++ b/blog4j-common/src/main/java/com/blog4j/common/annotation/OperationLog.java
@@ -0,0 +1,40 @@
+package com.blog4j.common.annotation;
+
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 统一日志注解
+ * @Create on : 2024/8/18 13:04
+ **/
+@Target({ ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OperationLog {
+ /**
+ * 日志类型
+ *
+ * @return 日志类型
+ */
+ OperationTypeEnum operationType() default OperationTypeEnum.QUERY;
+
+ /**
+ * 模块
+ *
+ * @return 模块
+ */
+ ModuleTypeEnum module();
+
+ /**
+ * 描述
+ *
+ * @return 描述
+ */
+ String description() default "";
+}
diff --git a/blog4j-common/src/main/java/com/blog4j/common/constants/CommonConstant.java b/blog4j-common/src/main/java/com/blog4j/common/constants/CommonConstant.java
index 283ed27..f43b13c 100644
--- a/blog4j-common/src/main/java/com/blog4j/common/constants/CommonConstant.java
+++ b/blog4j-common/src/main/java/com/blog4j/common/constants/CommonConstant.java
@@ -82,6 +82,11 @@ public class CommonConstant {
*/
public static final int MAX_PAGE_SIZE = 100;
+ /**
+ * 未知异常
+ */
+ public static final String UNKNOWN_ERROR = "未知异常";
+
/**
* 注册成功默认给用户发送的消息
*/
diff --git a/blog4j-common/src/main/java/com/blog4j/common/enums/LogResultEnum.java b/blog4j-common/src/main/java/com/blog4j/common/enums/LogResultEnum.java
new file mode 100644
index 0000000..ac11873
--- /dev/null
+++ b/blog4j-common/src/main/java/com/blog4j/common/enums/LogResultEnum.java
@@ -0,0 +1,27 @@
+package com.blog4j.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/18 14:38
+ **/
+@AllArgsConstructor
+@Getter
+public enum LogResultEnum {
+ /**
+ * 成功
+ */
+ SUCCESS("success"),
+
+ /**
+ * 失败
+ */
+ FAIL("fail"),
+ ;
+
+ private final String result;
+}
diff --git a/blog4j-common/src/main/java/com/blog4j/common/enums/ModuleTypeEnum.java b/blog4j-common/src/main/java/com/blog4j/common/enums/ModuleTypeEnum.java
new file mode 100644
index 0000000..c2ac8b2
--- /dev/null
+++ b/blog4j-common/src/main/java/com/blog4j/common/enums/ModuleTypeEnum.java
@@ -0,0 +1,55 @@
+package com.blog4j.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/18 13:09
+ **/
+@Getter
+@AllArgsConstructor
+public enum ModuleTypeEnum {
+ /**
+ * 文章模块
+ */
+ ARTICLE("article"),
+
+ /**
+ * 用户认证模块
+ */
+ AUTH("auth"),
+
+ /**
+ * 阿里云OSS模块
+ */
+ OSS("oss"),
+
+ /**
+ * 邮件模块
+ */
+ EMAIL("email"),
+
+ /**
+ * 短信模块
+ */
+ SMS("sms"),
+
+ /**
+ * 系统模块
+ */
+ SYSTEM("system"),
+
+ /**
+ * 用户模块
+ */
+ USER("user"),
+
+
+
+ ;
+
+ private final String type;
+}
diff --git a/blog4j-common/src/main/java/com/blog4j/common/enums/OperationTypeEnum.java b/blog4j-common/src/main/java/com/blog4j/common/enums/OperationTypeEnum.java
new file mode 100644
index 0000000..de1af41
--- /dev/null
+++ b/blog4j-common/src/main/java/com/blog4j/common/enums/OperationTypeEnum.java
@@ -0,0 +1,69 @@
+package com.blog4j.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/18 13:06
+ **/
+@Getter
+@AllArgsConstructor
+public enum OperationTypeEnum {
+ /**
+ * 查询
+ */
+ QUERY("query"),
+
+ /**
+ * 新增
+ */
+ INSERT("insert"),
+
+ /**
+ * 编辑
+ */
+ EDIT("edit"),
+
+ /**
+ * 删除
+ */
+ DELETE("delete"),
+
+ /**
+ * 上传
+ */
+ UPLOAD("upload"),
+
+ /**
+ * 下载
+ */
+ DOWNLOAD("download"),
+
+ /**
+ * 登录
+ */
+ LOGIN("login"),
+
+ /**
+ * 注册
+ */
+ REGISTER("register"),
+
+ /**
+ * 导出
+ */
+ EXPORT("export"),
+
+ /**
+ * 导入
+ */
+ IMPORT("import"),
+
+
+ ;
+
+ private final String type;
+}
diff --git a/blog4j-common/src/main/java/com/blog4j/common/model/LogVo.java b/blog4j-common/src/main/java/com/blog4j/common/model/LogVo.java
new file mode 100644
index 0000000..badb92e
--- /dev/null
+++ b/blog4j-common/src/main/java/com/blog4j/common/model/LogVo.java
@@ -0,0 +1,97 @@
+package com.blog4j.common.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/18 20:31
+ **/
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = true)
+@Builder
+public class LogVo implements Serializable {
+ /**
+ * id
+ */
+ private Long id;
+
+ /**
+ * 用户ID
+ */
+ private String userId;
+
+ /**
+ * 用户名称
+ */
+ private String userName;
+
+ /**
+ * 请求URI
+ */
+ private String url;
+
+ /**
+ * 耗时
+ */
+ private long time;
+
+ /**
+ * 请求参数
+ */
+ private String param;
+
+ /**
+ * 登录IP
+ */
+ private String ipAddress;
+
+ /**
+ * 请求结果
+ */
+ private String result;
+
+ /**
+ * 错误信息
+ */
+ private String errMsg;
+
+ /**
+ * 请求类型
+ */
+ private String operationType;
+
+ /**
+ * 模块类型
+ */
+ private String moduleType;
+
+ /**
+ * 创建时间
+ */
+ private String createTime;
+
+ /**
+ * 描述
+ */
+ private String description;
+
+ /**
+ * 方法名
+ */
+ private String methodName;
+
+ /**
+ * 类名
+ */
+ private String className;
+}
diff --git a/blog4j-common/src/main/java/com/blog4j/common/utils/OperationLogHolder.java b/blog4j-common/src/main/java/com/blog4j/common/utils/OperationLogHolder.java
new file mode 100644
index 0000000..72dddab
--- /dev/null
+++ b/blog4j-common/src/main/java/com/blog4j/common/utils/OperationLogHolder.java
@@ -0,0 +1,28 @@
+package com.blog4j.common.utils;
+
+
+import com.blog4j.common.model.LogVo;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/19 12:44
+ **/
+public class OperationLogHolder {
+ private static final ThreadLocal logVoHolder = new ThreadLocal<>();
+
+ public static void setLogVo(LogVo logVo) {
+ logVoHolder.set(logVo);
+ }
+
+
+ public static LogVo getLogVo() {
+ return logVoHolder.get();
+ }
+
+
+ public static void removeLogVo() {
+ logVoHolder.remove();
+ }
+}
diff --git a/blog4j-common/src/main/java/com/blog4j/common/utils/RealIpUtil.java b/blog4j-common/src/main/java/com/blog4j/common/utils/RealIpUtil.java
new file mode 100644
index 0000000..ab99ebb
--- /dev/null
+++ b/blog4j-common/src/main/java/com/blog4j/common/utils/RealIpUtil.java
@@ -0,0 +1,67 @@
+package com.blog4j.common.utils;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/18 17:21
+ **/
+public class RealIpUtil {
+ public static String getRealIp(HttpServletRequest request) {
+ String ip = request.getHeader("x-forwarded-for");
+ if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
+ // 多次反向代理后会有多个ip值,第一个ip才是真实ip
+ if (ip.contains(",")) {
+ ip = ip.split(",")[0];
+ }
+ }
+ // ****以下写法都会判断ip为空才会执行,即执行到ip不为空,后续会跳过,这样写是为了避免超大圈复杂度
+ ip = proxyClientIp(request, ip);
+ ip = wlProxyClientIp(request, ip);
+ ip = httpClientIp(request, ip);
+ ip = httpXForwardedForIp(request, ip);
+ ip = xRealIp(request,ip);
+
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getRemoteAddr();
+ }
+ return ip;
+ }
+
+ private static String proxyClientIp(HttpServletRequest request, String ip) {
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("Proxy-Client-IP");
+ }
+ return ip;
+ }
+
+ private static String wlProxyClientIp(HttpServletRequest request, String ip) {
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ }
+ return ip;
+ }
+
+ private static String httpClientIp(HttpServletRequest request, String ip) {
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_CLIENT_IP");
+ }
+ return ip;
+ }
+
+ private static String httpXForwardedForIp(HttpServletRequest request, String ip) {
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+ }
+ return ip;
+ }
+
+ private static String xRealIp(HttpServletRequest request, String ip) {
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("X-Real-IP");
+ }
+ return ip;
+ }
+}
diff --git a/blog4j-server/pom.xml b/blog4j-server/pom.xml
index 189b1a2..f4ac115 100644
--- a/blog4j-server/pom.xml
+++ b/blog4j-server/pom.xml
@@ -41,11 +41,18 @@
aliyun-sdk-oss
3.10.2
-
org.springframework.boot
spring-boot-starter-mail
+
+ com.github.pagehelper
+ pagehelper-spring-boot-starter
+
+
+ org.liquibase
+ liquibase-core
+
diff --git a/blog4j-server/src/main/java/com/blog4j/server/common/aop/AsyncService.java b/blog4j-server/src/main/java/com/blog4j/server/common/aop/AsyncService.java
new file mode 100644
index 0000000..94ef3f6
--- /dev/null
+++ b/blog4j-server/src/main/java/com/blog4j/server/common/aop/AsyncService.java
@@ -0,0 +1,30 @@
+package com.blog4j.server.common.aop;
+
+import com.blog4j.common.model.LogVo;
+import com.blog4j.server.modules.log.service.LogService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/20 19:58
+ **/
+@Component
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+public class AsyncService {
+ private final LogService logService;
+
+ /**
+ * 异步添加日志信息
+ *
+ * @param logVo 日志信息
+ */
+ @Async
+ public void addLog(LogVo logVo) {
+ logService.addLog(logVo);
+ }
+}
diff --git a/blog4j-server/src/main/java/com/blog4j/server/common/aop/LogAspect.java b/blog4j-server/src/main/java/com/blog4j/server/common/aop/LogAspect.java
new file mode 100644
index 0000000..1fde073
--- /dev/null
+++ b/blog4j-server/src/main/java/com/blog4j/server/common/aop/LogAspect.java
@@ -0,0 +1,130 @@
+package com.blog4j.server.common.aop;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.json.JSONUtil;
+import com.blog4j.api.client.FeignUser;
+import com.blog4j.api.vo.UserInfoVo;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.LogResultEnum;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
+import com.blog4j.common.exception.Blog4jException;
+import com.blog4j.common.exception.InvalidRequestException;
+import com.blog4j.common.model.LogVo;
+import com.blog4j.common.utils.CommonUtil;
+import com.blog4j.common.utils.OperationLogHolder;
+import com.blog4j.common.utils.RealIpUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/18 14:30
+ **/
+@Slf4j
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@Component
+@Aspect
+public class LogAspect {
+ private final FeignUser feignUser;
+ private final AsyncService asyncService;
+
+ @Pointcut("@annotation(com.blog4j.common.annotation.OperationLog)")
+ public void log() {}
+
+ @AfterThrowing(pointcut = "log()", throwing = "e")
+ public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
+ String errMsg = e.getMessage();
+ if (e instanceof Blog4jException) {
+ Blog4jException blog4jException = (Blog4jException) e;
+ errMsg = blog4jException.getErrMsg();
+ } else if (e instanceof InvalidRequestException) {
+ InvalidRequestException invalidRequestException = (InvalidRequestException) e;
+ errMsg = invalidRequestException.getErrMsg();
+ }
+
+ log.error("接口异常: [{}]", errMsg);
+ LogVo logVo = OperationLogHolder.getLogVo();
+ logVo.setResult(LogResultEnum.FAIL.getResult()).setErrMsg(errMsg);
+ OperationLogHolder.setLogVo(logVo);
+ }
+
+ @Around("log()")
+ public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
+ long startTime = System.currentTimeMillis();
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ Method method = signature.getMethod();
+ LogVo logVo = getAnnotationInfo(method);
+ logVo.setParam(JSONUtil.toJsonStr(joinPoint.getArgs()))
+ .setResult(LogResultEnum.SUCCESS.getResult());
+ // 方法名
+ String methodName = joinPoint.getSignature().getName();
+ logVo.setMethodName(methodName);
+
+ // 得到request
+ HttpServletRequest request = ((ServletRequestAttributes)
+ Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+ logVo.setIpAddress(RealIpUtil.getRealIp(request)).setUrl(request.getRequestURL().toString());
+ UserInfoVo userInfo = getUserInfo();
+ if (Objects.nonNull(userInfo)) {
+ logVo.setUserId(userInfo.getUserId()).setUserName(userInfo.getUserName());
+ }
+
+ String className = joinPoint.getTarget().getClass().getName();
+ logVo.setClassName(className)
+ .setTime(System.currentTimeMillis() - startTime)
+ .setCreateTime(CommonUtil.getCurrentDateTime());
+ OperationLogHolder.setLogVo(logVo);
+ return joinPoint.proceed();
+ }
+
+ @After("log()")
+ public void doAfter(JoinPoint joinPoint) {
+ LogVo logVo = OperationLogHolder.getLogVo();
+ OperationLogHolder.removeLogVo();
+ asyncService.addLog(logVo);
+ }
+
+ private LogVo getAnnotationInfo(Method method ) {
+ LogVo log = new LogVo();
+ OperationLog annotation = method.getAnnotation(OperationLog.class);
+ if (annotation != null) {
+ OperationTypeEnum operationTypeEnum = annotation.operationType();
+ ModuleTypeEnum module = annotation.module();
+ String description = annotation.description();
+ log.setModuleType(module.getType())
+ .setOperationType(operationTypeEnum.getType())
+ .setDescription(description);
+ }
+ return log;
+ }
+
+ private UserInfoVo getUserInfo() {
+ String userId = "";
+ try {
+ userId = StpUtil.getLoginIdAsString();
+ return feignUser.getUserInfoByUserId(userId);
+ } catch (Exception exception) {
+ log.warn("user not login");
+ }
+ return null;
+ }
+}
diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/email/controller/EmailController.java b/blog4j-server/src/main/java/com/blog4j/server/modules/email/controller/EmailController.java
index ee32b0e..c781cb2 100644
--- a/blog4j-server/src/main/java/com/blog4j/server/modules/email/controller/EmailController.java
+++ b/blog4j-server/src/main/java/com/blog4j/server/modules/email/controller/EmailController.java
@@ -1,6 +1,9 @@
package com.blog4j.server.modules.email.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
+import com.blog4j.common.annotation.OperationLog;
+import com.blog4j.common.enums.ModuleTypeEnum;
+import com.blog4j.common.enums.OperationTypeEnum;
import com.blog4j.common.model.Result;
import com.blog4j.server.modules.email.service.EmailService;
import lombok.RequiredArgsConstructor;
@@ -28,6 +31,9 @@ public class EmailController {
* @param email 邮件
* @return 发送成功
*/
+ @OperationLog(operationType= OperationTypeEnum.INSERT,
+ module= ModuleTypeEnum.EMAIL,
+ description = "发送邮件验证码")
@SaCheckLogin
@GetMapping("/sendEmail")
public Result sendEmail(@RequestParam("email") String email) {
diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/email/controller/inner/EmailFeignController.java b/blog4j-server/src/main/java/com/blog4j/server/modules/inner/ServerFeignController.java
similarity index 85%
rename from blog4j-server/src/main/java/com/blog4j/server/modules/email/controller/inner/EmailFeignController.java
rename to blog4j-server/src/main/java/com/blog4j/server/modules/inner/ServerFeignController.java
index a250897..50aead9 100644
--- a/blog4j-server/src/main/java/com/blog4j/server/modules/email/controller/inner/EmailFeignController.java
+++ b/blog4j-server/src/main/java/com/blog4j/server/modules/inner/ServerFeignController.java
@@ -1,13 +1,12 @@
-package com.blog4j.server.modules.email.controller.inner;
+package com.blog4j.server.modules.inner;
import com.blog4j.api.client.FeignServer;
import com.blog4j.api.vo.NoticeEmailVo;
-import com.blog4j.common.model.Result;
+import com.blog4j.common.model.LogVo;
import com.blog4j.server.modules.email.service.EmailService;
+import com.blog4j.server.modules.log.service.LogService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
-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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@@ -16,13 +15,14 @@ import org.springframework.web.bind.annotation.RestController;
* @author 98k灬
* @version v1.0.0
* @Description : 功能描述
- * @Create on : 2024/8/14 13:19
+ * @Create on : 2024/8/19 19:52
**/
@RestController
@RequestMapping("/feign")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
-public class EmailFeignController implements FeignServer {
+public class ServerFeignController implements FeignServer {
private final EmailService emailService;
+ private final LogService logService;
/**
* 发送邮件给文章审批人
@@ -87,4 +87,14 @@ public class EmailFeignController implements FeignServer {
public void sendEmailToUserForApproveOrganization(String toEmail, String organizationName) {
emailService.sendEmailToUserForApproveOrganization(toEmail, organizationName);
}
+
+ /**
+ * 添加日志
+ *
+ * @param logVo 日志信息
+ */
+ @Override
+ public void addLog(LogVo logVo) {
+ logService.addLog(logVo);
+ }
}
diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/log/controller/LogController.java b/blog4j-server/src/main/java/com/blog4j/server/modules/log/controller/LogController.java
new file mode 100644
index 0000000..e4490d8
--- /dev/null
+++ b/blog4j-server/src/main/java/com/blog4j/server/modules/log/controller/LogController.java
@@ -0,0 +1,42 @@
+package com.blog4j.server.modules.log.controller;
+
+import cn.dev33.satoken.annotation.SaCheckLogin;
+import com.blog4j.common.model.Result;
+import com.blog4j.server.modules.log.service.LogService;
+import com.blog4j.server.modules.log.vo.req.LogListReqVo;
+import com.blog4j.server.modules.log.vo.resp.LogRespVo;
+import com.github.pagehelper.PageInfo;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+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 javax.validation.Valid;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/20 12:12
+ **/
+@RequestMapping("/log")
+@RestController
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+public class LogController {
+ private final LogService logService;
+
+ /**
+ * 日志信息分页查询
+ *
+ * @param reqVo 请求
+ * @return 日志信息
+ */
+ @SaCheckLogin
+ @PostMapping("/logList")
+ public Result logList(@RequestBody @Valid LogListReqVo reqVo) {
+ PageInfo pageInfo = logService.logList(reqVo);
+ return Result.ok(pageInfo);
+ }
+}
diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/log/entity/LogEntity.java b/blog4j-server/src/main/java/com/blog4j/server/modules/log/entity/LogEntity.java
new file mode 100644
index 0000000..a5ceb97
--- /dev/null
+++ b/blog4j-server/src/main/java/com/blog4j/server/modules/log/entity/LogEntity.java
@@ -0,0 +1,100 @@
+package com.blog4j.server.modules.log.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/7/29 21:44
+ **/
+@Data
+@TableName("t_log")
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = true)
+public class LogEntity {
+ /**
+ * 主键
+ */
+ @TableId(value = "id", type = IdType.ID_WORKER)
+ private Long id;
+
+ /**
+ * 用户ID
+ */
+ private String userId;
+
+ /**
+ * 用户名称
+ */
+ private String userName;
+
+ /**
+ * 请求URI
+ */
+ private String url;
+
+ /**
+ * 耗时
+ */
+ private long time;
+
+ /**
+ * 请求参数
+ */
+ private String param;
+
+ /**
+ * 登录IP
+ */
+ private String ipAddress;
+
+ /**
+ * 请求结果
+ */
+ private String result;
+
+ /**
+ * 错误信息
+ */
+ private String errMsg;
+
+ /**
+ * 请求类型
+ */
+ private String operationType;
+
+ /**
+ * 模块类型
+ */
+ private String moduleType;
+
+ /**
+ * 创建时间
+ */
+ private String createTime;
+
+ /**
+ * 描述
+ */
+ private String description;
+
+ /**
+ * 方法名
+ */
+ private String methodName;
+
+ /**
+ * 类名
+ */
+ private String className;
+}
diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/log/entity/LoginLogEntity.java b/blog4j-server/src/main/java/com/blog4j/server/modules/log/entity/LoginLogEntity.java
deleted file mode 100644
index 69beb21..0000000
--- a/blog4j-server/src/main/java/com/blog4j/server/modules/log/entity/LoginLogEntity.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.blog4j.server.modules.log.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-/**
- * @author 98k灬
- * @version v1.0.0
- * @Description : 功能描述
- * @Create on : 2024/7/29 21:44
- **/
-@Data
-@TableName("t_login_log")
-public class LoginLogEntity {
- /**
- * 主键
- */
- @TableId(value = "id", type = IdType.AUTO)
- private Integer id;
-
- /**
- * 用户ID
- */
- private String userId;
-
- /**
- * 登录时间
- */
- private String loginTime;
-
- /**
- * 请求参数
- */
- private String param;
-
- /**
- * 登录IP
- */
- private String ipAddress;
-
- /**
- * 登录结果
- */
- private Integer result;
-
- /**
- * 登录类型
- */
- private Integer loginType;
-}
diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/log/mapper/LoginLogMapper.java b/blog4j-server/src/main/java/com/blog4j/server/modules/log/mapper/LogMapper.java
similarity index 67%
rename from blog4j-server/src/main/java/com/blog4j/server/modules/log/mapper/LoginLogMapper.java
rename to blog4j-server/src/main/java/com/blog4j/server/modules/log/mapper/LogMapper.java
index 2b55787..f4b62f9 100644
--- a/blog4j-server/src/main/java/com/blog4j/server/modules/log/mapper/LoginLogMapper.java
+++ b/blog4j-server/src/main/java/com/blog4j/server/modules/log/mapper/LogMapper.java
@@ -1,7 +1,7 @@
package com.blog4j.server.modules.log.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.blog4j.server.modules.log.entity.LoginLogEntity;
+import com.blog4j.server.modules.log.entity.LogEntity;
import org.apache.ibatis.annotations.Mapper;
/**
@@ -11,5 +11,5 @@ import org.apache.ibatis.annotations.Mapper;
* @Create on : 2024/7/29 21:47
**/
@Mapper
-public interface LoginLogMapper extends BaseMapper {
+public interface LogMapper extends BaseMapper {
}
diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/log/service/LogService.java b/blog4j-server/src/main/java/com/blog4j/server/modules/log/service/LogService.java
new file mode 100644
index 0000000..81926e9
--- /dev/null
+++ b/blog4j-server/src/main/java/com/blog4j/server/modules/log/service/LogService.java
@@ -0,0 +1,31 @@
+package com.blog4j.server.modules.log.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.blog4j.common.model.LogVo;
+import com.blog4j.server.modules.log.entity.LogEntity;
+import com.blog4j.server.modules.log.vo.req.LogListReqVo;
+import com.blog4j.server.modules.log.vo.resp.LogRespVo;
+import com.github.pagehelper.PageInfo;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/19 19:54
+ **/
+public interface LogService extends IService {
+ /**
+ * 添加日志
+ *
+ * @param logVo 日志信息
+ */
+ void addLog(LogVo logVo);
+
+ /**
+ * 日志信息分页查询
+ *
+ * @param reqVo 请求
+ * @return 日志信息
+ */
+ PageInfo logList(LogListReqVo reqVo);
+}
diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/log/service/impl/LogServiceImpl.java b/blog4j-server/src/main/java/com/blog4j/server/modules/log/service/impl/LogServiceImpl.java
new file mode 100644
index 0000000..94874da
--- /dev/null
+++ b/blog4j-server/src/main/java/com/blog4j/server/modules/log/service/impl/LogServiceImpl.java
@@ -0,0 +1,187 @@
+package com.blog4j.server.modules.log.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.blog4j.common.constants.CommonConstant;
+import com.blog4j.common.enums.OperationTypeEnum;
+import com.blog4j.common.model.LogVo;
+import com.blog4j.server.modules.log.entity.LogEntity;
+import com.blog4j.server.modules.log.mapper.LogMapper;
+import com.blog4j.server.modules.log.service.LogService;
+import com.blog4j.server.modules.log.vo.req.LogListReqVo;
+import com.blog4j.server.modules.log.vo.resp.LogRespVo;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author 98k灬
+ * @version v1.0.0
+ * @Description : 功能描述
+ * @Create on : 2024/8/19 19:54
+ **/
+@Service
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+public class LogServiceImpl extends ServiceImpl
+ implements LogService {
+ @Value("${custom.logEnabled}")
+ private boolean logEnabled;
+
+ @Value("${custom.queryLogEnabled}")
+ private boolean queryLogEnabled;
+
+ /**
+ * 添加日志
+ *
+ * @param logVo 日志信息
+ */
+ @Override
+ public void addLog(LogVo logVo) {
+ if (!logEnabled) {
+ return;
+ }
+
+ if (StringUtils.equals(logVo.getOperationType(), OperationTypeEnum.QUERY.getType())
+ && !queryLogEnabled) {
+ return;
+ }
+ LogEntity logEntity = new LogEntity();
+ logEntity.setId(null);
+ BeanUtils.copyProperties(logVo, logEntity);
+ this.baseMapper.insert(logEntity);
+ }
+
+ /**
+ * 日志信息分页查询
+ *
+ * @param reqVo 请求
+ * @return 日志信息
+ */
+ @Override
+ public PageInfo logList(LogListReqVo reqVo) {
+ Integer pageNo = reqVo.getPageNo();
+ Integer pageSize = reqVo.getPageSize();
+ if (pageSize > CommonConstant.MAX_PAGE_SIZE) {
+ pageSize = CommonConstant.MAX_PAGE_SIZE;
+ }
+ String operationType = reqVo.getOperationType();
+ String module = reqVo.getModule();
+ String result = reqVo.getResult();
+
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper()
+ .orderByDesc(LogEntity::getCreateTime);
+
+ if (StringUtils.isNotBlank(operationType)) {
+ wrapper.eq(LogEntity::getOperationType, operationType);
+ }
+
+ if (StringUtils.isNotBlank(module)) {
+ wrapper.eq(LogEntity::getModuleType, module);
+ }
+
+ if (StringUtils.isNotBlank(result)) {
+ wrapper.eq(LogEntity::getResult, result);
+ }
+
+ Page