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 page = PageHelper.startPage(pageNo, pageSize); + List list = this.baseMapper.selectList(wrapper); + if (CollectionUtils.isEmpty(list)) { + return new PageInfo<>(new ArrayList<>()); + } + + List collect = list.stream().map(item -> { + LogRespVo respVo = new LogRespVo(); + BeanUtils.copyProperties(item, respVo); + return respVo; + }).collect(Collectors.toList()); + + for (LogRespVo respVo : collect) { + respVo.setOperationType(handleOperationType(respVo.getOperationType())); + respVo.setModuleType(handleModuleType(respVo.getModuleType())); + } + + PageInfo pageInfo = new PageInfo<>(collect); + pageInfo.setTotal(page.getTotal()); + return pageInfo; + } + + private String handleModuleType(String moduleType) { + String res ; + switch (moduleType) { + case "article": + res = "文章"; + break; + case "auth": + res = "用户认证"; + break; + case "oss": + res = "阿里云OSS"; + break; + case "email": + res = "邮件"; + break; + case "sms": + res = "短信"; + break; + case "system": + res = "系统"; + break; + case "user": + res = "用户"; + break; + default: + res = ""; + } + return res; + } + + private String handleOperationType(String operationType) { + String res; + switch (operationType) { + case "query": + res = "查询"; + break; + case "insert": + res = "新增"; + break; + case "edit": + res = "编辑"; + break; + case "delete": + res = "删除"; + break; + case "upload": + res = "上传"; + break; + case "download": + res = "下载"; + break; + case "login": + res = "登录"; + break; + case "register": + res = "注册"; + break; + case "export": + res = "导出"; + break; + case "import": + res = "导入"; + break; + default: + res = ""; + } + return res; + } +} diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/log/vo/req/LogListReqVo.java b/blog4j-server/src/main/java/com/blog4j/server/modules/log/vo/req/LogListReqVo.java new file mode 100644 index 0000000..5d9f8f2 --- /dev/null +++ b/blog4j-server/src/main/java/com/blog4j/server/modules/log/vo/req/LogListReqVo.java @@ -0,0 +1,49 @@ +package com.blog4j.server.modules.log.vo.req; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotNull; + +/** + * @author 98k灬 + * @version v1.0.0 + * @Description : 功能描述 + * @Create on : 2024/8/20 12:14 + **/ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Accessors(chain = true) +public class LogListReqVo { + /** + * 当前页 + */ + @NotNull(message = "当前页不能为空") + private Integer pageNo; + + /** + * 每页大小 + */ + @NotNull(message = "每页大小不能为空") + private Integer pageSize; + + /** + * 操作类型 + */ + private String operationType; + + /** + * 操作模块 + */ + private String module; + + /** + * 响应结果 + */ + private String result; +} diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/log/vo/resp/LogRespVo.java b/blog4j-server/src/main/java/com/blog4j/server/modules/log/vo/resp/LogRespVo.java new file mode 100644 index 0000000..4875f3b --- /dev/null +++ b/blog4j-server/src/main/java/com/blog4j/server/modules/log/vo/resp/LogRespVo.java @@ -0,0 +1,84 @@ +package com.blog4j.server.modules.log.vo.resp; + +import lombok.Data; + +/** + * @author 98k灬 + * @version v1.0.0 + * @Description : 功能描述 + * @Create on : 2024/8/19 21:16 + **/ +@Data +public class LogRespVo { + 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/oss/controller/OssController.java b/blog4j-server/src/main/java/com/blog4j/server/modules/oss/controller/OssController.java index d291e3d..23b5645 100644 --- a/blog4j-server/src/main/java/com/blog4j/server/modules/oss/controller/OssController.java +++ b/blog4j-server/src/main/java/com/blog4j/server/modules/oss/controller/OssController.java @@ -3,6 +3,9 @@ package com.blog4j.server.modules.oss.controller; import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckRole; import cn.dev33.satoken.annotation.SaMode; +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.oss.service.OssService; import lombok.RequiredArgsConstructor; @@ -33,6 +36,9 @@ public class OssController { * @param type 类型 * @return 上传后的访问路径 */ + @OperationLog(operationType= OperationTypeEnum.UPLOAD, + module= ModuleTypeEnum.OSS, + description = "上传") @SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN", "ORDINARY"}, mode = SaMode.OR) @PostMapping("/upload") public Result upload(MultipartFile file, String type) { @@ -46,6 +52,9 @@ public class OssController { * @param filePath 文件路径 * @return 删除成功 */ + @OperationLog(operationType= OperationTypeEnum.DELETE, + module= ModuleTypeEnum.OSS, + description = "删除文件") @SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN", "COMPOSER"}, mode = SaMode.OR) @GetMapping("/delete") public Result delete(@RequestParam String filePath) { @@ -58,6 +67,9 @@ public class OssController { * * @return 文件存储路径 */ + @OperationLog(operationType= OperationTypeEnum.DOWNLOAD, + module= ModuleTypeEnum.OSS, + description = "下载用户导入模板文件") @SaCheckLogin @GetMapping("/downloadUserImportTemplate") public Result downloadUserImportTemplate() { @@ -70,6 +82,9 @@ public class OssController { * * @return 文件存储路径 */ + @OperationLog(operationType= OperationTypeEnum.DOWNLOAD, + module= ModuleTypeEnum.OSS, + description = "下载组织导入模板文件") @SaCheckLogin @GetMapping("/downloadOrganizationImportTemplate") public Result downloadOrganizationImportTemplate() { diff --git a/blog4j-server/src/main/java/com/blog4j/server/modules/sms/controller/ApiSmsController.java b/blog4j-server/src/main/java/com/blog4j/server/modules/sms/controller/ApiSmsController.java index bfe183f..6ac27e5 100644 --- a/blog4j-server/src/main/java/com/blog4j/server/modules/sms/controller/ApiSmsController.java +++ b/blog4j-server/src/main/java/com/blog4j/server/modules/sms/controller/ApiSmsController.java @@ -1,6 +1,9 @@ package com.blog4j.server.modules.sms.controller; import cn.dev33.satoken.annotation.SaIgnore; +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.sms.service.SmsService; import lombok.RequiredArgsConstructor; @@ -28,6 +31,9 @@ public class ApiSmsController { * @param phone 手机号码 * @return 短信验证码 */ + @OperationLog(operationType= OperationTypeEnum.INSERT, + module= ModuleTypeEnum.OSS, + description = "获取短信验证码") @SaIgnore @GetMapping("/getPhoneCode/{type}/{phone}") public Result getPhoneCode(@PathVariable("phone") String phone, @PathVariable("type") String type) { diff --git a/blog4j-server/src/main/resources/application-dev.yml b/blog4j-server/src/main/resources/application-dev.yml index e46c887..dc2ea3c 100644 --- a/blog4j-server/src/main/resources/application-dev.yml +++ b/blog4j-server/src/main/resources/application-dev.yml @@ -1,9 +1,11 @@ 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-server?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true + url: jdbc:mysql://localhost:3306/blog4j-server?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true username: root - password: 4897458Hk!@ + password: 4897458hk cloud: nacos: discovery: @@ -27,4 +29,8 @@ spring: # 连接池中的最大空闲连接 max-idle: 10 # 连接池中的最小空闲连接 - min-idle: 0 \ No newline at end of file + min-idle: 0 + +custom: + logEnabled: true # 是否开启日志记录功能 + queryLogEnabled: true # 是否开启查询日志记录功能 \ No newline at end of file diff --git a/blog4j-server/src/main/resources/application.yml b/blog4j-server/src/main/resources/application.yml index 9d6f1cd..d14685e 100644 --- a/blog4j-server/src/main/resources/application.yml +++ b/blog4j-server/src/main/resources/application.yml @@ -2,6 +2,8 @@ server: port: 9500 spring: + main: + allow-circular-references: true servlet: multipart: max-file-size: 10MB @@ -30,4 +32,10 @@ sa-token: email: from: 2915524550@qq.com - subject: 西瓜博客 \ No newline at end of file + subject: 西瓜博客 + +jasypt: + encryptor: + password: blog4j_test + algorithm: PBEWithMD5AndDES + iv-generator-classname: org.jasypt.iv.NoIvGenerator \ No newline at end of file diff --git a/blog4j-server/src/main/resources/liquibase/changelog/database_change.xml b/blog4j-server/src/main/resources/liquibase/changelog/database_change.xml new file mode 100644 index 0000000..3167747 --- /dev/null +++ b/blog4j-server/src/main/resources/liquibase/changelog/database_change.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/blog4j-server/src/main/resources/liquibase/master.xml b/blog4j-server/src/main/resources/liquibase/master.xml new file mode 100644 index 0000000..2b9d02d --- /dev/null +++ b/blog4j-server/src/main/resources/liquibase/master.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/blog4j-server/src/main/resources/liquibase/upgrade/20240823/t_server_init_ddl_20240823124256.sql b/blog4j-server/src/main/resources/liquibase/upgrade/20240823/t_server_init_ddl_20240823124256.sql new file mode 100644 index 0000000..aac52b7 --- /dev/null +++ b/blog4j-server/src/main/resources/liquibase/upgrade/20240823/t_server_init_ddl_20240823124256.sql @@ -0,0 +1,59 @@ +/* + 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-server + + Target Server Type : MySQL + Target Server Version : 50736 (5.7.36-txsql-log) + File Encoding : 65001 + + Date: 23/08/2024 12:43:44 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for t_log +-- ---------------------------- +DROP TABLE IF EXISTS `t_log`; +CREATE TABLE `t_log` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户ID', + `user_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户名称', + `url` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '请求URI', + `time` bigint(20) NOT NULL COMMENT '耗时', + `param` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '请求参数', + `method_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '方法名称', + `class_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '类名', + `ip_address` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'IP地址', + `result` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '结果', + `err_msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '错误信息', + `operation_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '操作类型', + `module_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模块类型', + `description` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '描述', + `create_time` datetime NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '日志信息表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Table structure for t_record +-- ---------------------------- +DROP TABLE IF EXISTS `t_record`; +CREATE TABLE `t_record` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户ID', + `type` int(11) NOT NULL COMMENT '类型(1:下载 2:上传)', + `times` int(11) NOT NULL COMMENT '次数', + `date` date NOT NULL COMMENT '日期', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_uni_userid_type_date`(`user_id`, `type`, `date`) USING BTREE, + INDEX `idx_nor_userId`(`user_id`) USING BTREE, + INDEX `idx_nor_type`(`type`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户上传下载次数记录' ROW_FORMAT = DYNAMIC; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/blog4j-server/src/main/resources/mapper/LogMapper.xml b/blog4j-server/src/main/resources/mapper/LogMapper.xml new file mode 100644 index 0000000..54d1f5a --- /dev/null +++ b/blog4j-server/src/main/resources/mapper/LogMapper.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/blog4j-server/src/main/resources/mapper/LoginLogMapper.xml b/blog4j-server/src/main/resources/mapper/LoginLogMapper.xml deleted file mode 100644 index 4d7d36f..0000000 --- a/blog4j-server/src/main/resources/mapper/LoginLogMapper.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/blog4j-system/pom.xml b/blog4j-system/pom.xml index 323f6c9..e390bbe 100644 --- a/blog4j-system/pom.xml +++ b/blog4j-system/pom.xml @@ -41,6 +41,10 @@ com.github.pagehelper pagehelper-spring-boot-starter + + org.liquibase + liquibase-core + diff --git a/blog4j-system/src/main/java/com/blog4j/system/SystemApplication.java b/blog4j-system/src/main/java/com/blog4j/system/SystemApplication.java index 32105dc..1800f8f 100644 --- a/blog4j-system/src/main/java/com/blog4j/system/SystemApplication.java +++ b/blog4j-system/src/main/java/com/blog4j/system/SystemApplication.java @@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.scheduling.annotation.EnableAsync; /** * @author 98k灬 @@ -16,6 +17,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients; @EnableDiscoveryClient @EnableFeignClients(basePackages = "com.blog4j") @EnableCaching +@EnableAsync public class SystemApplication { public static void main(String[] args) { SpringApplication.run(SystemApplication.class, args); diff --git a/blog4j-system/src/main/java/com/blog4j/system/aop/LogAspect.java b/blog4j-system/src/main/java/com/blog4j/system/aop/LogAspect.java new file mode 100644 index 0000000..707c95f --- /dev/null +++ b/blog4j-system/src/main/java/com/blog4j/system/aop/LogAspect.java @@ -0,0 +1,131 @@ +package com.blog4j.system.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 com.blog4j.system.component.AsyncService; +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-system/src/main/java/com/blog4j/system/api/ApiBarrageController.java b/blog4j-system/src/main/java/com/blog4j/system/api/ApiBarrageController.java index 84cf882..2f278d9 100644 --- a/blog4j-system/src/main/java/com/blog4j/system/api/ApiBarrageController.java +++ b/blog4j-system/src/main/java/com/blog4j/system/api/ApiBarrageController.java @@ -1,5 +1,8 @@ package com.blog4j.system.api; +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.system.entity.BarrageEntity; import com.blog4j.system.service.BarrageService; @@ -28,6 +31,9 @@ public class ApiBarrageController { * * @return 网站弹幕留言列表 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.SYSTEM, + description = "获取网站弹幕留言列表") @GetMapping("/list") public Result list() { return Result.ok(barrageService.list()); @@ -39,6 +45,9 @@ public class ApiBarrageController { * @param barrage 留言信息 * @return 成功 */ + @OperationLog(operationType= OperationTypeEnum.INSERT, + module= ModuleTypeEnum.SYSTEM, + description = "弹幕留言") @PostMapping("/addBarrage") public Result addBarrage(@RequestBody BarrageEntity barrage) { BarrageEntity barrage1 = barrageService.addBarrage(barrage); diff --git a/blog4j-system/src/main/java/com/blog4j/system/api/ApiChartController.java b/blog4j-system/src/main/java/com/blog4j/system/api/ApiChartController.java index 8c6ec59..ad0871d 100644 --- a/blog4j-system/src/main/java/com/blog4j/system/api/ApiChartController.java +++ b/blog4j-system/src/main/java/com/blog4j/system/api/ApiChartController.java @@ -1,6 +1,9 @@ package com.blog4j.system.api; 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.system.service.ChartService; import com.blog4j.system.vo.resp.ChartInfoRespVo; @@ -28,6 +31,9 @@ public class ApiChartController { * * @return 首页大屏的信息 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.SYSTEM, + description = "统计首页大屏的信息") @SaCheckLogin @GetMapping("/chartInfo") public Result chartInfo() { @@ -40,6 +46,9 @@ public class ApiChartController { * * @return 一年内文章贡献度 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.SYSTEM, + description = "获取一年内文章贡献度") @SaCheckLogin @GetMapping("/getContributeData") public Result getContributeData() { diff --git a/blog4j-system/src/main/java/com/blog4j/system/api/ApiSystemController.java b/blog4j-system/src/main/java/com/blog4j/system/api/ApiSystemController.java index c916a89..a6924a1 100644 --- a/blog4j-system/src/main/java/com/blog4j/system/api/ApiSystemController.java +++ b/blog4j-system/src/main/java/com/blog4j/system/api/ApiSystemController.java @@ -3,7 +3,10 @@ package com.blog4j.system.api; import com.blog4j.api.vo.OssBaseConfigVo; import com.blog4j.api.vo.WebInfoVo; import com.blog4j.api.vo.SystemBaseConfigVo; +import com.blog4j.common.annotation.OperationLog; +import com.blog4j.common.enums.ModuleTypeEnum; import com.blog4j.common.enums.NoticeTypeEnum; +import com.blog4j.common.enums.OperationTypeEnum; import com.blog4j.common.model.Result; import com.blog4j.system.entity.OssExtendConfigEntity; import com.blog4j.system.entity.WebInfoEntity; @@ -46,6 +49,9 @@ public class ApiSystemController { * * @return 系统基础配置信息 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.SYSTEM, + description = "获取系统基础配置信息") @GetMapping("/getBaseSystemConfig") public Result getBaseSystemConfig() { SystemBaseConfigVo configVo = systemService.getBaseSystemConfig(); @@ -57,6 +63,9 @@ public class ApiSystemController { * * @return 网站配置信息 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.SYSTEM, + description = "获取网站配置信息") @GetMapping("/getWebInfo") public Result getWebInfo() { WebInfoEntity webInfo = webInfoService.getOne(null); @@ -70,6 +79,9 @@ public class ApiSystemController { * * @return OSS基础配置信息 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.SYSTEM, + description = "获取OSS基础配置信息") @GetMapping("/getOssBaseConfig") public Result getOssBaseConfig() { OssBaseConfigVo ossBaseConfigVo = ossBaseConfigService.getOssBaseConfig(); @@ -81,6 +93,9 @@ public class ApiSystemController { * * @return OSS基础配置信息 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.SYSTEM, + description = "获取OSS扩展配置信息") @GetMapping("/getOssExtendConfig") public Result getOssExtendConfig() { OssExtendConfigEntity ossBaseConfigVo = ossBaseConfigService.getOssExtendConfig(); @@ -92,6 +107,9 @@ public class ApiSystemController { * * @return 公告信息 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.SYSTEM, + description = "获取系统公告信息") @GetMapping("/systemNotice") public Result systemNotice() { NoticeRespVo respVo = noticeService.systemNotice(NoticeTypeEnum.SYSTEM_NOTICE.getCode()); @@ -104,6 +122,9 @@ public class ApiSystemController { * @param reqVo 请求信息 * @return 全部公告信息 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.SYSTEM, + description = "获取全部公告信息") @PostMapping("/allNotice") public Result allNotice(@RequestBody @Valid NoticeListReqVo reqVo) { PageInfo pageInfo = noticeService.allNotice(reqVo); @@ -116,6 +137,9 @@ public class ApiSystemController { * @param id 公共ID * @return 告详情 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.SYSTEM, + description = "获取公告详情") @GetMapping("/noticeDetail/{id}") public Result noticeDetail(@PathVariable("id") Integer id) { NoticeRespVo respVo = noticeService.noticeDetail(id); diff --git a/blog4j-system/src/main/java/com/blog4j/system/component/AsyncService.java b/blog4j-system/src/main/java/com/blog4j/system/component/AsyncService.java new file mode 100644 index 0000000..474f202 --- /dev/null +++ b/blog4j-system/src/main/java/com/blog4j/system/component/AsyncService.java @@ -0,0 +1,30 @@ +package com.blog4j.system.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; + + /** + * 异步添加日志信息 + * + * @param logVo 日志信息 + */ + @Async + public void addLog(LogVo logVo) { + feignServer.addLog(logVo); + } +} diff --git a/blog4j-system/src/main/java/com/blog4j/system/controller/SystemController.java b/blog4j-system/src/main/java/com/blog4j/system/controller/SystemController.java index 9915c70..434fc8a 100644 --- a/blog4j-system/src/main/java/com/blog4j/system/controller/SystemController.java +++ b/blog4j-system/src/main/java/com/blog4j/system/controller/SystemController.java @@ -2,6 +2,9 @@ package com.blog4j.system.controller; import cn.dev33.satoken.annotation.SaCheckRole; import cn.dev33.satoken.annotation.SaMode; +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.common.utils.CommonUtil; import com.blog4j.system.entity.WebInfoEntity; @@ -48,6 +51,9 @@ public class SystemController { * @param reqVo 请求信息 * @return 保存成功 */ + @OperationLog(operationType= OperationTypeEnum.INSERT, + module= ModuleTypeEnum.SYSTEM, + description = "保存系统配置信息") @SaCheckRole(value = "SUPER_ADMIN") @PostMapping("/saveBaseSystemConfig") public Result saveBaseSystemConfig(@RequestBody @Valid SaveSystemReqVo reqVo) { @@ -61,6 +67,9 @@ public class SystemController { * @param reqVo 请求信息 * @return 保存成功 */ + @OperationLog(operationType= OperationTypeEnum.INSERT, + module= ModuleTypeEnum.SYSTEM, + description = "保存网站配置信息") @SaCheckRole(value = "SUPER_ADMIN") @PostMapping("/saveWebInfo") public Result saveWebInfo(@RequestBody @Valid SaveWebInfoReqVo reqVo) { @@ -77,6 +86,9 @@ public class SystemController { * @param reqVo 请求信息 * @return 编辑成功 */ + @OperationLog(operationType= OperationTypeEnum.EDIT, + module= ModuleTypeEnum.SYSTEM, + description = "编辑公告") @SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN"}, mode = SaMode.OR) @PostMapping("/editNotice") public Result editNotice(@RequestBody @Valid EditNoticeReqVo reqVo) { @@ -90,6 +102,9 @@ public class SystemController { * @param id 公告ID * @return 删除成功 */ + @OperationLog(operationType= OperationTypeEnum.DELETE, + module= ModuleTypeEnum.SYSTEM, + description = "删除公告") @SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN"}, mode = SaMode.OR) @GetMapping("/delNotice/{id}") public Result delNotice(@PathVariable("id") Integer id) { @@ -103,6 +118,9 @@ public class SystemController { * @param reqVo 请求信息 * @return 创建成功 */ + @OperationLog(operationType= OperationTypeEnum.INSERT, + module= ModuleTypeEnum.SYSTEM, + description = "创建公告") @SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN"}, mode = SaMode.OR) @PostMapping("/createNotice") public Result createNotice(@RequestBody @Valid CreateNoticeReqVo reqVo) { @@ -116,6 +134,9 @@ public class SystemController { * @param reqVo 请求信息 * @return 保存成功 */ + @OperationLog(operationType= OperationTypeEnum.INSERT, + module= ModuleTypeEnum.SYSTEM, + description = "保存OSS基础配置信息") @SaCheckRole(value = "SUPER_ADMIN") @PostMapping("/saveOssConfig") public Result saveOssConfig(@RequestBody @Valid SaveOssBaseConfigReqVo reqVo) { @@ -129,6 +150,9 @@ public class SystemController { * @param reqVo 请求信息 * @return 保存成功 */ + @OperationLog(operationType= OperationTypeEnum.INSERT, + module= ModuleTypeEnum.SYSTEM, + description = "保存OSS扩展配置信息") @SaCheckRole(value = "SUPER_ADMIN") @PostMapping("/saveOssExtendConfig") public Result saveOssExtendConfig(@RequestBody @Valid SaveOssExtendConfigReqVo reqVo) { diff --git a/blog4j-system/src/main/resources/application-dev.yml b/blog4j-system/src/main/resources/application-dev.yml index bf2e654..8af2d21 100644 --- a/blog4j-system/src/main/resources/application-dev.yml +++ b/blog4j-system/src/main/resources/application-dev.yml @@ -1,9 +1,11 @@ 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-system?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true + url: jdbc:mysql://localhost:3306/blog4j-system?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true username: root - password: 4897458Hk!@ + password: 4897458hk cloud: nacos: discovery: diff --git a/blog4j-system/src/main/resources/application.yml b/blog4j-system/src/main/resources/application.yml index 961f6a6..edab016 100644 --- a/blog4j-system/src/main/resources/application.yml +++ b/blog4j-system/src/main/resources/application.yml @@ -20,4 +20,9 @@ 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-system/src/main/resources/liquibase/changelog/database_change.xml b/blog4j-system/src/main/resources/liquibase/changelog/database_change.xml new file mode 100644 index 0000000..56cf59f --- /dev/null +++ b/blog4j-system/src/main/resources/liquibase/changelog/database_change.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/blog4j-system/src/main/resources/liquibase/master.xml b/blog4j-system/src/main/resources/liquibase/master.xml new file mode 100644 index 0000000..2b9d02d --- /dev/null +++ b/blog4j-system/src/main/resources/liquibase/master.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/blog4j-system/src/main/resources/liquibase/upgrade/20240823/t_system_init_ddl_20240823124956.sql b/blog4j-system/src/main/resources/liquibase/upgrade/20240823/t_system_init_ddl_20240823124956.sql new file mode 100644 index 0000000..7310e83 --- /dev/null +++ b/blog4j-system/src/main/resources/liquibase/upgrade/20240823/t_system_init_ddl_20240823124956.sql @@ -0,0 +1,196 @@ +/* + 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-system + + Target Server Type : MySQL + Target Server Version : 50736 (5.7.36-txsql-log) + File Encoding : 65001 + + Date: 23/08/2024 12:49:53 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for t_barrage +-- ---------------------------- +DROP TABLE IF EXISTS `t_barrage`; +CREATE TABLE `t_barrage` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户ID', + `message_content` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '留言内容', + `create_time` datetime NOT NULL COMMENT '创建时间', + `user_avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户头像' +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '网站弹幕留言表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_img_valid_rules +-- ---------------------------- +DROP TABLE IF EXISTS `t_img_valid_rules`; +CREATE TABLE `t_img_valid_rules` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `img_rule_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '图片审核规则代码', + `enabled` int(11) NOT NULL DEFAULT 1 COMMENT '是否启用', + `img_rule_desc` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '规则描述', + `img_rule_confidence` int(11) NOT NULL COMMENT '信任分', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_nor_enabled`(`enabled`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '图片审核规则' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_notice +-- ---------------------------- +DROP TABLE IF EXISTS `t_notice`; +CREATE TABLE `t_notice` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `notice_title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '公告标题', + `notice_version` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '公告版本', + `notice_content` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '公告内容', + `creater` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '公告创建人', + `notice_type` int(11) NOT NULL COMMENT '公告类型(1:系统公告 2:组织公告)', + `organization_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '组织ID(公告类型是组织公告时必填)', + `notice_status` int(11) NOT NULL COMMENT '公告状态(1:待发布 2:已发布 )', + `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_version`(`notice_version`, `notice_type`, `deleted`) USING BTREE, + INDEX `idx_nor_type_delete`(`notice_type`, `deleted`) USING BTREE, + INDEX `idx_nor_ststus_delete`(`notice_status`, `deleted`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '公告信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_oss_base_config +-- ---------------------------- +DROP TABLE IF EXISTS `t_oss_base_config`; +CREATE TABLE `t_oss_base_config` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `end_point` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '终端', + `bucket_domain` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '域', + `bucket_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '桶名', + `access_key_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'accessKeyId', + `access_key_secret` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'accessKeySecret', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_uni_bucket_name`(`bucket_name`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'OSS基本配置信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_oss_extend_config +-- ---------------------------- +DROP TABLE IF EXISTS `t_oss_extend_config`; +CREATE TABLE `t_oss_extend_config` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `article_img_storage_directory` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '文章中图片存储目录', + `file_storage_directory` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '文件存储目录', + `user_avatar_storage_directory` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户头像存储目录', + `organization_avatar_storage_directory` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '组织头像存储目录', + `user_homepage_storage_directory` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户主页背景图存储目录', + `category_cover_storage_directory` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '分类背景图存储目录', + `website_cover_directory` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '网站背景图存储目录', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '阿里云OSS扩展信息' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_system +-- ---------------------------- +DROP TABLE IF EXISTS `t_system`; +CREATE TABLE `t_system` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `open_sms` int(11) NOT NULL DEFAULT 1 COMMENT '是否开启短信功能(0:不开启 1:开启)', + `open_msm` int(11) NOT NULL DEFAULT 1 COMMENT '是否开启邮件功能(0:不开启 1:开启)', + `open_upload` int(11) NOT NULL DEFAULT 1 COMMENT '是否开启上传文件功能(0:不开启 1:开启)', + `open_download` int(11) NOT NULL COMMENT '是否开启下载文件功能', + `upload_day_times` int(11) NOT NULL COMMENT '单个用户每天上传文件的次数', + `download_day_times` int(11) NOT NULL COMMENT '单个用户每天下载文件的次数', + `user_month_update_pwd_times` int(11) NOT NULL DEFAULT 3 COMMENT '用户每个月允许修改密码的次数', + `user_import_template_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '导入用户信息模板存储路径', + `organization_import_template_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '导入组织信息模板存储路径', + `user_default_avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户默认头像', + `user_default_homepage` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户默认背景图', + `open_text_valid` int(11) NOT NULL DEFAULT 1 COMMENT '是否开启文本审核功能(0:不开启 1:开启)', + `open_img_valid` int(11) NOT NULL DEFAULT 1 COMMENT '是否开启图片审核功能(0:不开启 1:开启)', + `init_password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户初始密码', + `aes_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'AES前后端加解密的KEY', + `aes_iv` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'AES前后端加解密的IV', + `organization_max_capacity` int(11) NOT NULL COMMENT '单个组织最大容纳人数', + `user_join_organization_max_num` int(11) NOT NULL COMMENT '单个用户允许加入的组织数', + `article_approve_require` int(11) NOT NULL COMMENT '发布文章是否需要审批', + `approve_article_open_email_notify` int(11) NOT NULL COMMENT '文章审批后是否需要邮件通知', + `approve_organization_open_email_notify` int(11) NOT NULL COMMENT '组织审批后是否需要邮件通知', + `approve_role_open_email_notify` int(11) NOT NULL COMMENT '角色审批后是否需要邮件通知', + `approve_user_open_email_notify` int(11) NOT NULL COMMENT '用户审批后是否需要邮件通知', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统配置' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_text_valid_rules +-- ---------------------------- +DROP TABLE IF EXISTS `t_text_valid_rules`; +CREATE TABLE `t_text_valid_rules` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `text_rule_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '文本审核规则代码', + `enabled` int(11) NULL DEFAULT 1 COMMENT '是否启用', + `text_rule_desc` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '规则描述', + `text_rule_confidence` int(11) NOT NULL COMMENT '规则信任分', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_nor_enabled`(`enabled`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '文本审核的规则' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_visit +-- ---------------------------- +DROP TABLE IF EXISTS `t_visit`; +CREATE TABLE `t_visit` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `date` date NOT NULL COMMENT '日期', + `count` int(11) NOT NULL DEFAULT 0 COMMENT '访问量', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_uni_date`(`date`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '网站访问量' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_webinfo +-- ---------------------------- +DROP TABLE IF EXISTS `t_webinfo`; +CREATE TABLE `t_webinfo` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `web_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '网站名称', + `web_title` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '网站标题', + `background_image` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '网站背景图片', + `time_scope` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '时间范围', + `beian_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '备案号', + `beian_user` 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 (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '网站信息' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_work_order +-- ---------------------------- +DROP TABLE IF EXISTS `t_work_order`; +CREATE TABLE `t_work_order` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `creater_user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '创建人ID', + `word_order_type` int(11) NOT NULL COMMENT '工单类型(1:需求 2:问题 3:求助)', + `title` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '工单标题', + `description` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '简要描述', + `email_notify` int(11) NOT NULL COMMENT '是否邮件通知处理结果', + `handle_status` int(11) NOT NULL COMMENT '状态(1:待处理 3:处理中 3:已处理)', + `hndle_result` int(11) NULL DEFAULT NULL COMMENT '处理结果(1:同意 2:驳回)', + `handle_message` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '处理结果留言(处理结果为驳回时必填)', + `handle_time` datetime NULL DEFAULT NULL COMMENT '处理时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '工单发起时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_nor_creater_user_id`(`creater_user_id`) USING BTREE, + INDEX `idx_nor_type`(`word_order_type`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '工单信息' ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/blog4j-user/pom.xml b/blog4j-user/pom.xml index aba57bf..1535cad 100644 --- a/blog4j-user/pom.xml +++ b/blog4j-user/pom.xml @@ -40,48 +40,10 @@ blog4j-api 1.0-SNAPSHOT + + org.liquibase + liquibase-core + - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - com.spotify - docker-maven-plugin - 1.2.0 - - - http://120.46.46.173:2375 - - ${project.artifactId}:${project.version} - - true - - src/main/docker - - - - / - - ${project.build.directory} - - ${project.build.finalName}.jar - - - - - - - \ No newline at end of file diff --git a/blog4j-user/src/main/java/com/blog4j/user/aop/LogAspect.java b/blog4j-user/src/main/java/com/blog4j/user/aop/LogAspect.java new file mode 100644 index 0000000..ff20bed --- /dev/null +++ b/blog4j-user/src/main/java/com/blog4j/user/aop/LogAspect.java @@ -0,0 +1,131 @@ +package com.blog4j.user.aop; + +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.json.JSONUtil; +import com.blog4j.common.annotation.OperationLog; +import com.blog4j.common.enums.ModuleTypeEnum; +import com.blog4j.common.enums.OperationTypeEnum; +import com.blog4j.common.enums.LogResultEnum; +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 com.blog4j.user.component.AsyncService; +import com.blog4j.user.entity.UserEntity; +import com.blog4j.user.mapper.UserMapper; +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 UserMapper userMapper; + 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()); + UserEntity 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 UserEntity getUserInfo() { + String userId = ""; + try { + userId = StpUtil.getLoginIdAsString(); + return userMapper.selectById(userId); + } catch (Exception exception) { + log.warn("user not login"); + } + return null; + } +} diff --git a/blog4j-user/src/main/java/com/blog4j/user/api/ApiOrganizationController.java b/blog4j-user/src/main/java/com/blog4j/user/api/ApiOrganizationController.java index c4feb36..6a85e5a 100644 --- a/blog4j-user/src/main/java/com/blog4j/user/api/ApiOrganizationController.java +++ b/blog4j-user/src/main/java/com/blog4j/user/api/ApiOrganizationController.java @@ -1,6 +1,9 @@ package com.blog4j.user.api; import cn.dev33.satoken.annotation.SaIgnore; +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.user.service.OrganizationService; import com.blog4j.user.vo.resp.OrganizationInfoRespVo; @@ -31,6 +34,9 @@ public class ApiOrganizationController { * @param organizationId 组织ID * @return 组织信息 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.USER, + description = "根据组织ID获取组织信息") @SaIgnore @GetMapping("/organizationInfo") public Result organizationInfo(@RequestParam("organizationId") String organizationId) { @@ -44,6 +50,9 @@ public class ApiOrganizationController { * @param organizationId 组织ID * @return 组织成员数 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.USER, + description = "根据组织ID获取组织成员数") @SaIgnore @GetMapping("/organizationMembers") public Result organizationMembers(@RequestParam("organizationId") String organizationId) { @@ -57,6 +66,9 @@ public class ApiOrganizationController { * @param keyword 关键字 * @return 组织列表 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.USER, + description = "获取组织列表") @GetMapping("/organizationList") public Result organizationList(@RequestParam(value = "keyword", required = false) String keyword) { List list = organizationService.organizationListByKeyword(keyword); diff --git a/blog4j-user/src/main/java/com/blog4j/user/api/ApiRoleController.java b/blog4j-user/src/main/java/com/blog4j/user/api/ApiRoleController.java index 98896fa..e8d0aba 100644 --- a/blog4j-user/src/main/java/com/blog4j/user/api/ApiRoleController.java +++ b/blog4j-user/src/main/java/com/blog4j/user/api/ApiRoleController.java @@ -1,6 +1,9 @@ package com.blog4j.user.api; import com.blog4j.api.vo.RoleInfoVo; +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.user.service.RoleService; import lombok.RequiredArgsConstructor; @@ -28,6 +31,9 @@ public class ApiRoleController { * @param userId 用户ID * @return 角色信息 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.USER, + description = "根据用户ID获取角色信息") @GetMapping("/getRoleInfoByUserId/{userId}") public Result getRoleInfoByUserId(@PathVariable("userId") String userId) { RoleInfoVo info = roleService.getRoleInfoByUserId(userId); diff --git a/blog4j-user/src/main/java/com/blog4j/user/api/ApiUserController.java b/blog4j-user/src/main/java/com/blog4j/user/api/ApiUserController.java index dbeee98..21b5fef 100644 --- a/blog4j-user/src/main/java/com/blog4j/user/api/ApiUserController.java +++ b/blog4j-user/src/main/java/com/blog4j/user/api/ApiUserController.java @@ -1,5 +1,8 @@ package com.blog4j.user.api; +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.user.service.UserService; import com.blog4j.user.vo.req.RegisterReqVo; @@ -33,6 +36,9 @@ public class ApiUserController { * @param userId 用户ID * @return 用户信息 */ + @OperationLog(operationType= OperationTypeEnum.QUERY, + module= ModuleTypeEnum.USER, + description = "根据用户ID获取用户信息") @GetMapping("/info") public Result info(@RequestParam("userId") String userId) { UserInfoRespVo respVo = userService.userInfo(userId); @@ -45,6 +51,9 @@ public class ApiUserController { * @param reqVo 注册信息 * @return 注册成功 */ + @OperationLog(operationType= OperationTypeEnum.REGISTER, + module= ModuleTypeEnum.USER, + description = "用户注册") @PostMapping("/register") public Result register(@RequestBody @Valid RegisterReqVo reqVo) { userService.register(reqVo); diff --git a/blog4j-user/src/main/java/com/blog4j/user/component/AsyncService.java b/blog4j-user/src/main/java/com/blog4j/user/component/AsyncService.java index d6019fe..b303b76 100644 --- a/blog4j-user/src/main/java/com/blog4j/user/component/AsyncService.java +++ b/blog4j-user/src/main/java/com/blog4j/user/component/AsyncService.java @@ -3,13 +3,12 @@ package com.blog4j.user.component; import com.blog4j.api.client.FeignServer; import com.blog4j.api.vo.MessageVo; import com.blog4j.api.vo.NoticeEmailVo; -import com.blog4j.common.constants.CommonConstant; import com.blog4j.common.enums.MessageStatusEnum; import com.blog4j.common.enums.YesOrNoEnum; +import com.blog4j.common.model.LogVo; import com.blog4j.common.utils.CommonUtil; import com.blog4j.user.entity.MessageEntity; import com.blog4j.user.mapper.MessageMapper; -import com.blog4j.user.utils.UserUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; @@ -115,4 +114,9 @@ public class AsyncService { .build(); messageMapper.insert(message); } + + @Async + public void addLog(LogVo logVo) { + feignServer.addLog(logVo); + } } diff --git a/blog4j-user/src/main/java/com/blog4j/user/controller/FansController.java b/blog4j-user/src/main/java/com/blog4j/user/controller/FansController.java index a60f784..869c4ab 100644 --- a/blog4j-user/src/main/java/com/blog4j/user/controller/FansController.java +++ b/blog4j-user/src/main/java/com/blog4j/user/controller/FansController.java @@ -1,6 +1,9 @@ package com.blog4j.user.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.user.service.FansService; import com.blog4j.user.vo.req.FansListReqVo; @@ -36,6 +39,7 @@ public class FansController { * @param reqVo 请求信息 * @return 用户的粉丝信息列表 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "根据用户ID获取用户的粉丝信息列表") @PostMapping("/list") public Result list(@RequestBody @Valid FansListReqVo reqVo) { PageInfo pageInfo = fansService.pageList(reqVo); @@ -49,6 +53,7 @@ public class FansController { * @param userId2 用户2 * @return 是否 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "检查userid2是否是userid1的粉丝") @SaCheckLogin @GetMapping("/checkIsFans") public Result checkIsFans(@RequestParam("userId1") String userId1, @RequestParam("userId2") String userId2) { @@ -62,6 +67,9 @@ public class FansController { * @param reqVo 请求 * @return 结果 */ + @OperationLog(operationType= OperationTypeEnum.EDIT, + module= ModuleTypeEnum.USER, + description = "用户关注或取消关注") @SaCheckLogin @PostMapping("/follow") public Result follow(@RequestBody @Valid FollowReqVo reqVo) { diff --git a/blog4j-user/src/main/java/com/blog4j/user/controller/MessageController.java b/blog4j-user/src/main/java/com/blog4j/user/controller/MessageController.java index c7b24a8..92cd7e0 100644 --- a/blog4j-user/src/main/java/com/blog4j/user/controller/MessageController.java +++ b/blog4j-user/src/main/java/com/blog4j/user/controller/MessageController.java @@ -1,6 +1,9 @@ package com.blog4j.user.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.user.entity.MessageEntity; import com.blog4j.user.service.MessageService; @@ -37,6 +40,7 @@ public class MessageController { * @param userId 用户ID * @return 是否有新消息 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "检查用户是否有新消息") @SaCheckLogin @GetMapping("/userHasNewMessage") public Result userHasNewMessage(@RequestParam("userId") String userId) { @@ -50,6 +54,7 @@ public class MessageController { * @param reqVo 请求信息 * @return 消息列表 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "获取消息列表") @SaCheckLogin @PostMapping("/messageList") public Result messageList(@RequestBody @Valid MessageListReqVo reqVo) { @@ -63,6 +68,9 @@ public class MessageController { * @param reqVo 请求信息 * @return 删除成功 */ + @OperationLog(operationType= OperationTypeEnum.DELETE, + module= ModuleTypeEnum.USER, + description = "删除消息") @SaCheckLogin @PostMapping("/deleteMessage") public Result deleteMessage(@RequestBody @Valid DelMessageReqVo reqVo) { @@ -71,10 +79,13 @@ public class MessageController { } /** - * 全部已读消息 + * 设置全部消息已读 * * @return 成功 */ + @OperationLog(operationType= OperationTypeEnum.EDIT, + module= ModuleTypeEnum.USER, + description = "设置全部消息已读") @SaCheckLogin @GetMapping("/allReadMessage") public Result allReadMessage() { @@ -87,6 +98,9 @@ public class MessageController { * * @return 成功 */ + @OperationLog(operationType= OperationTypeEnum.DELETE, + module= ModuleTypeEnum.USER, + description = "删除全部消息") @SaCheckLogin @GetMapping("/deleteAllMessage") public Result deleteAllMessage() { diff --git a/blog4j-user/src/main/java/com/blog4j/user/controller/OrganizationController.java b/blog4j-user/src/main/java/com/blog4j/user/controller/OrganizationController.java index c3bdc1f..fcf33bf 100644 --- a/blog4j-user/src/main/java/com/blog4j/user/controller/OrganizationController.java +++ b/blog4j-user/src/main/java/com/blog4j/user/controller/OrganizationController.java @@ -4,6 +4,9 @@ import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckRole; import cn.dev33.satoken.annotation.SaMode; +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.user.model.ImportOrganizationExcel; import com.blog4j.user.service.ApplyOrganizationService; @@ -63,6 +66,7 @@ public class OrganizationController { * @param reqVo 查询条件 * @return 组织列表 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "组织列表查询") @SaCheckPermission(value = "ORGANIZATION:LIST") @PostMapping("/list") public Result list(@RequestBody OrganizationListReqVo reqVo) { @@ -76,6 +80,7 @@ public class OrganizationController { * @param reqVo 查询条件 * @return 用户列表 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "查询组织用户列表") @SaCheckPermission(value = "ORGANIZATION:USER:LIST") @PostMapping("/organizationUserList") public Result organizationUserList(@RequestBody @Valid UserListReqVo reqVo) { @@ -89,6 +94,7 @@ public class OrganizationController { * @param organizationId 组织ID * @return 组织信息 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "根据组织ID查询组织信息") @GetMapping("/info/{organizationId}") public Result info(@PathVariable("organizationId") String organizationId) { OrganizationInfoRespVo respVo = organizationService.info(organizationId); @@ -102,6 +108,9 @@ public class OrganizationController { * @param organizationId 组织ID * @return 更新成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "更新组织的状态", + operationType = OperationTypeEnum.EDIT) @SaCheckRole(value = "SUPER_ADMIN") @GetMapping("/updateOrganizationStatus/{status}/{organizationId}") public Result updateOrganizationStatus(@PathVariable("status") Integer status, @@ -116,6 +125,9 @@ public class OrganizationController { * @param reqVo 待删除的组织ID集合 * @return 删除成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "删除组织信息", + operationType = OperationTypeEnum.DELETE) @SaCheckPermission(value = "ORGANIZATION:DELETE") @PostMapping("/delete") public Result delete(@RequestBody @Valid DeleteOrganizationReqVo reqVo) { @@ -129,6 +141,9 @@ public class OrganizationController { * @param reqVo 请求信息 * @return 移除成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "移除组织的用户", + operationType = OperationTypeEnum.EDIT) @SaCheckPermission(value = "ORGANIZATION:USER:DELETE") @PostMapping("/removeOrganizationUser") public Result removeOrganizationUser(@RequestBody @Valid RemoveOrganizationUserReqVo reqVo) { @@ -142,6 +157,9 @@ public class OrganizationController { * @param reqVo 组织信息 * @return 创建成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "创建组织信息", + operationType = OperationTypeEnum.INSERT) @SaCheckPermission(value = "ORGANIZATION:ADD") @PostMapping("/create") public Result create(@RequestBody @Valid CreateOrganizationReqVo reqVo) { @@ -155,6 +173,9 @@ public class OrganizationController { * @param reqVo 审批信息 * @return 审批成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "审批组织", + operationType = OperationTypeEnum.EDIT) @SaCheckRole(value = "SUPER_ADMIN") @PostMapping("/approveOrganization") public Result approveOrganization(@RequestBody @Valid ApproveOrganizationReqVo reqVo) { @@ -168,6 +189,9 @@ public class OrganizationController { * @param exportOrganizationReqVo 组织ID * @param response 响应 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "组织导出", + operationType = OperationTypeEnum.EXPORT) @SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN"}, mode = SaMode.OR) @PostMapping("/exportOrganization") public void exportOrganization(@RequestBody @Valid ExportOrganizationReqVo exportOrganizationReqVo, @@ -181,6 +205,9 @@ public class OrganizationController { * @param reqVo 请求信息 * @return 编辑成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "编辑组织信息", + operationType = OperationTypeEnum.EDIT) @SaCheckPermission(value = "ORGANIZATION:EDIT") @PostMapping("/edit") public Result edit(@RequestBody @Valid EditOrganizationReqVo reqVo) { @@ -194,6 +221,9 @@ public class OrganizationController { * @param file 文件 * @return 导入成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "组织批量导入", + operationType = OperationTypeEnum.IMPORT) @SaCheckPermission(value = "ORGANIZATION:IMPORT") @PostMapping("/importOrganization") public Result importOrganization(@RequestParam("file") MultipartFile file) { @@ -207,6 +237,9 @@ public class OrganizationController { * @param reqVo 组织信息 * @return 创建成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "批量创建组织信息", + operationType = OperationTypeEnum.INSERT) @SaCheckPermission(value = "ORGANIZATION:ADD") @PostMapping("/batchCreate") public Result batchCreate(@RequestBody @Valid BatchCreateOrganizationReqVo reqVo) { @@ -220,6 +253,9 @@ public class OrganizationController { * @param organizationId 组织ID * @return 申请成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "申请加入组织", + operationType = OperationTypeEnum.EDIT) @SaCheckLogin @GetMapping("/applyJoinOrganization") public Result applyJoin(@RequestParam("organizationId") String organizationId) { @@ -233,6 +269,9 @@ public class OrganizationController { * @param organizationId 组织ID * @return 退出成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "退出组织", + operationType = OperationTypeEnum.EDIT) @SaCheckLogin @GetMapping("/exitOrganization") public Result exitOrganization(@RequestParam("organizationId") String organizationId) { @@ -246,6 +285,7 @@ public class OrganizationController { * @param reqVo 请求 * @return 组织的列表 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "获取用户申请加入组织的列表") @SaCheckLogin @PostMapping("/applyJoinOrganizationList") public Result applyJoinOrganizationList(@RequestBody @Valid ApplyJoinOrganizationListReqVo reqVo) { @@ -259,6 +299,9 @@ public class OrganizationController { * @param reqVo 请求信息 * @return 审批成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "审批用户申请加入组织", + operationType = OperationTypeEnum.EDIT) @SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN"}, mode = SaMode.OR) @PostMapping("/approveUserJoinOrganization") public Result approveUserJoinOrganization(@RequestBody @Valid ApproveUserJoinOrganizationReqVo reqVo) { @@ -272,6 +315,9 @@ public class OrganizationController { * @param reqVo 请求 * @return 删除成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "删除用户申请加入组织记录", + operationType = OperationTypeEnum.DELETE) @SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN"}, mode = SaMode.OR) @PostMapping("/deleteApplyJoinOrganization") public Result deleteApplyJoinOrganization(@RequestBody @Valid DeleteApplyJoinOrganizationReqVo reqVo) { @@ -285,6 +331,7 @@ public class OrganizationController { * @param reqVo 请求 * @return 申请创建组织信息的列表 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "获取申请创建组织信息的列表") @SaCheckLogin @PostMapping("/getApplyOrganizationList") public Result getApplyOrganizationList(@RequestBody @Valid ApplyOrganizationListReqVo reqVo) { @@ -298,6 +345,9 @@ public class OrganizationController { * @param reqVo 请求 * @return 删除成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "删除用户申请创建组织记录", + operationType = OperationTypeEnum.DELETE) @SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN"}, mode = SaMode.OR) @PostMapping("/deleteApplyCreateOrganization") public Result deleteApplyCreateOrganization(@RequestBody @Valid DeleteApplyCreateOrganizationReqVo reqVo) { diff --git a/blog4j-user/src/main/java/com/blog4j/user/controller/PermissionController.java b/blog4j-user/src/main/java/com/blog4j/user/controller/PermissionController.java index b20b94a..15de876 100644 --- a/blog4j-user/src/main/java/com/blog4j/user/controller/PermissionController.java +++ b/blog4j-user/src/main/java/com/blog4j/user/controller/PermissionController.java @@ -1,5 +1,8 @@ package com.blog4j.user.controller; +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.user.entity.PermissionEntity; import com.blog4j.user.service.PermissionService; @@ -37,6 +40,7 @@ public class PermissionController { * * @return 权限列表 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "获取树形结构的权限列表") @GetMapping("/getTreePermissions") public Result getTreePermissions() { List list = permissionService.getTreePermissions(); @@ -49,6 +53,7 @@ public class PermissionController { * @param roleId 角色ID * @return 权限信息列表 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "根据角色ID查询权限信息列表") @GetMapping("/getPermissionByRoleId/{roleId}") public Result getPermissionByRoleId(@PathVariable("roleId") String roleId) { List list = permissionService.getPermissionByRoleId(roleId); @@ -61,6 +66,9 @@ public class PermissionController { * @param reqVo 信息 * @return 保存成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "保存角色与权限的关系", + operationType = OperationTypeEnum.INSERT) @PostMapping("/saveRolePermissionRel") public Result saveRolePermissionRel(@RequestBody @Valid SaveRolePermissionRelReqVo reqVo) { permissionService.saveRolePermissionRel(reqVo); @@ -73,6 +81,9 @@ public class PermissionController { * @param reqVo 信息 * @return 删除成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "删除节点", + operationType = OperationTypeEnum.DELETE) @PostMapping("/deletePermissionNode") public Result deletePermissionNode(@RequestBody @Valid DeletePermissionNodeReqVo reqVo) { permissionService.deletePermissionNode(reqVo); @@ -85,6 +96,9 @@ public class PermissionController { * @param reqVo 信息 * @return 新增成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "新增权限", + operationType = OperationTypeEnum.INSERT) @PostMapping("/createNode") public Result createNode(@RequestBody @Valid CreateNodeReqVo reqVo) { permissionService.createNode(reqVo); @@ -97,6 +111,9 @@ public class PermissionController { * @param reqVo 信息 * @return 新增成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "编辑权限", + operationType = OperationTypeEnum.EDIT) @PostMapping("/editNode") public Result editNode(@RequestBody @Valid EditNodeReqVo reqVo) { permissionService.editNode(reqVo); @@ -109,6 +126,7 @@ public class PermissionController { * @param permissionId 权限ID * @return 权限信息 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "根据权限ID获取权限信息") @GetMapping("/getPermissionById/{permissionId}") public Result getPermissionById(@PathVariable("permissionId") Integer permissionId) { PermissionEntity permission = permissionService.getById(permissionId); @@ -121,6 +139,9 @@ public class PermissionController { * @param reqVo 信息 * @return 添加成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "添加父节点", + operationType = OperationTypeEnum.INSERT) @PostMapping("/createParentNode") public Result createParentNode(@RequestBody @Valid CreateParentNodeReqVo reqVo) { permissionService.createParentNode(reqVo); diff --git a/blog4j-user/src/main/java/com/blog4j/user/controller/RoleController.java b/blog4j-user/src/main/java/com/blog4j/user/controller/RoleController.java index 172daab..cb0ecf3 100644 --- a/blog4j-user/src/main/java/com/blog4j/user/controller/RoleController.java +++ b/blog4j-user/src/main/java/com/blog4j/user/controller/RoleController.java @@ -1,6 +1,9 @@ package com.blog4j.user.controller; import cn.dev33.satoken.annotation.SaCheckPermission; +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.user.entity.RoleEntity; import com.blog4j.user.service.RoleService; @@ -37,7 +40,7 @@ public class RoleController { * @param reqVo 查询条件 * @return 角色信息 */ - //@SaCheckPermission(value = "ROLE:LIST") + @OperationLog(module= ModuleTypeEnum.USER, description = "获取所有的角色信息") @PostMapping("/roleList") public Result roleList(@RequestBody RoleListReqVo reqVo) { List list = roleService.roleList(reqVo); @@ -50,6 +53,7 @@ public class RoleController { * @param roleId 角色ID * @return 角色信息 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "根据角色ID获取角色信息") @GetMapping("/getRoleById/{roleId}") public Result getRoleById(@PathVariable("roleId") String roleId) { RoleEntity role = roleService.getById(roleId); @@ -62,6 +66,9 @@ public class RoleController { * @param reqVo 角色信息 * @return 创建成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "创建角色信息", + operationType = OperationTypeEnum.INSERT) @SaCheckPermission(value = "ROLE:ADD") @PostMapping("/create") public Result create(@RequestBody CreateRoleReqVo reqVo) { @@ -75,6 +82,9 @@ public class RoleController { * @param reqVo 角色信息 * @return 创建成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "编辑角色信息", + operationType = OperationTypeEnum.EDIT) @SaCheckPermission(value = "ROLE:EDIT") @PostMapping("/edit") public Result edit(@RequestBody EditRoleReqVo reqVo) { @@ -83,11 +93,14 @@ public class RoleController { } /** - * 删除角色 + * 删除角色信息 * * @param reqVo 角色信息 * @return 删除成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "删除角色信息", + operationType = OperationTypeEnum.DELETE) @SaCheckPermission(value = "ROLE:DELETE") @PostMapping("/delete") public Result delete(@RequestBody DeleteRoleReqVo reqVo) { diff --git a/blog4j-user/src/main/java/com/blog4j/user/controller/UserController.java b/blog4j-user/src/main/java/com/blog4j/user/controller/UserController.java index 9cc2b0f..2e7635e 100644 --- a/blog4j-user/src/main/java/com/blog4j/user/controller/UserController.java +++ b/blog4j-user/src/main/java/com/blog4j/user/controller/UserController.java @@ -5,6 +5,9 @@ import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckRole; import cn.dev33.satoken.annotation.SaMode; import com.blog4j.api.vo.UserInfoVo; +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.user.model.UserExcel; import com.blog4j.user.service.UserService; @@ -53,6 +56,7 @@ public class UserController { * @param userId 用户ID * @return 用户信息 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "根据用户ID获取用户信息") @SaCheckLogin @GetMapping("/info/{userId}") public Result info(@PathVariable("userId") String userId) { @@ -66,6 +70,7 @@ public class UserController { * @param reqVo 查询条件 * @return 用户列表 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "查询用户列表") @SaCheckPermission(value = "USER:LIST") @PostMapping("/list") public Result list(@RequestBody @Valid UserListReqVo reqVo) { @@ -79,6 +84,9 @@ public class UserController { * @param reqVo 用户信息 * @return 创建成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "创建用户信息", + operationType = OperationTypeEnum.INSERT) @SaCheckPermission(value = "USER:ADD") @PostMapping("/create") public Result create(@RequestBody @Valid CreateUserReqVo reqVo) { @@ -92,6 +100,9 @@ public class UserController { * @param reqVo 用户信息 * @return 编辑成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "编辑用户信息", + operationType = OperationTypeEnum.EDIT) @SaCheckPermission(value = "USER:EDIT") @PostMapping("/update") public Result update(@RequestBody EditUserReqVo reqVo) { @@ -105,6 +116,9 @@ public class UserController { * @param reqVo 用户信息 * @return 删除成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "删除用户信息", + operationType = OperationTypeEnum.DELETE) @SaCheckRole(value = "SUPER_ADMIN") @PostMapping("/delete") public Result delete(@RequestBody DeleteUserReqVo reqVo) { @@ -118,6 +132,9 @@ public class UserController { * @param file 文件 * @return 导入成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "用户批量导入", + operationType = OperationTypeEnum.IMPORT) @SaCheckPermission(value = "USER:IMPORT") @PostMapping("/importUser") public Result importUser(@RequestParam("file") MultipartFile file) { @@ -131,6 +148,9 @@ public class UserController { * @param reqVo 用户信息 * @return 创建成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "批量创建用户信息", + operationType = OperationTypeEnum.INSERT) @SaCheckPermission(value = "USER:ADD") @PostMapping("/batchCreate") public Result batchCreate(@RequestBody @Valid BatchCreateUserReqVo reqVo) { @@ -143,6 +163,9 @@ public class UserController { * * @param exportUserReqVo 用户ID */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "用户批量导出", + operationType = OperationTypeEnum.EXPORT) @SaCheckRole(value = {"SUPER_ADMIN", "ORGANIZATION_ADMIN"}, mode = SaMode.OR) @PostMapping("/exportUser") public void exportUser(@RequestBody @Valid ExportUserReqVo exportUserReqVo, @@ -156,6 +179,9 @@ public class UserController { * @param reqVo 请求 * @return 编辑成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "编辑用户基本信息", + operationType = OperationTypeEnum.EDIT) @SaCheckPermission(value = "USER:EDIT") @PostMapping("/editUserBaseInfo") public Result editUserBaseInfo(@RequestBody @Valid EditUserBaseInfoReqVo reqVo) { @@ -169,6 +195,7 @@ public class UserController { * @param reqVo 请求 * @return 验证结果 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "手机号码验证") @SaCheckLogin @PostMapping("/validPhone") public Result validPhone(@RequestBody @Valid ValidPhoneReqVo reqVo) { @@ -182,6 +209,7 @@ public class UserController { * @param reqVo 请求 * @return 验证结果 */ + @OperationLog(module= ModuleTypeEnum.USER, description = "邮箱验证") @SaCheckLogin @PostMapping("/validEmail") public Result validEmail(@RequestBody @Valid ValidEmailReqVo reqVo) { @@ -195,6 +223,9 @@ public class UserController { * @param reqVo 请求信息 * @return 更新成功 */ + @OperationLog(module= ModuleTypeEnum.USER, + description = "更新用户密码", + operationType = OperationTypeEnum.EDIT) @SaCheckLogin @PostMapping("/updateUserPwd") public Result updateUserPwd(@RequestBody @Valid UpdateUserPwdReqVo reqVo) { diff --git a/blog4j-user/src/main/resources/application-dev.yml b/blog4j-user/src/main/resources/application-dev.yml index d41c4b0..1c87285 100644 --- a/blog4j-user/src/main/resources/application-dev.yml +++ b/blog4j-user/src/main/resources/application-dev.yml @@ -1,9 +1,11 @@ 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-user?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true - username: blog4j_user_dev - password: 4897458Hk!@ + url: jdbc:mysql://localhost:3306/blog4j-user?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: 4897458hk cloud: nacos: discovery: diff --git a/blog4j-user/src/main/resources/application.yml b/blog4j-user/src/main/resources/application.yml index 3a4d447..f75fb45 100644 --- a/blog4j-user/src/main/resources/application.yml +++ b/blog4j-user/src/main/resources/application.yml @@ -16,4 +16,9 @@ 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-user/src/main/resources/liquibase/changelog/database_change.xml b/blog4j-user/src/main/resources/liquibase/changelog/database_change.xml new file mode 100644 index 0000000..d4dcbfc --- /dev/null +++ b/blog4j-user/src/main/resources/liquibase/changelog/database_change.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/blog4j-user/src/main/resources/liquibase/master.xml b/blog4j-user/src/main/resources/liquibase/master.xml new file mode 100644 index 0000000..2b9d02d --- /dev/null +++ b/blog4j-user/src/main/resources/liquibase/master.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/blog4j-user/src/main/resources/liquibase/upgrade/20240823/t_user_init_ddl_20240823125256.sql b/blog4j-user/src/main/resources/liquibase/upgrade/20240823/t_user_init_ddl_20240823125256.sql new file mode 100644 index 0000000..c4691b8 --- /dev/null +++ b/blog4j-user/src/main/resources/liquibase/upgrade/20240823/t_user_init_ddl_20240823125256.sql @@ -0,0 +1,231 @@ +/* + 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-user + + Target Server Type : MySQL + Target Server Version : 50736 (5.7.36-txsql-log) + File Encoding : 65001 + + Date: 23/08/2024 12:52:54 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for t_apply_organization +-- ---------------------------- +DROP TABLE IF EXISTS `t_apply_organization`; +CREATE TABLE `t_apply_organization` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `organization_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织ID', + `apply_user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '申请人', + `apply_role` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '申请人角色', + `approve_user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '审批人', + `deleted` int(11) NOT NULL DEFAULT 0 COMMENT '是否已被删除', + `create_time` datetime NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户创建组织申请' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_fans +-- ---------------------------- +DROP TABLE IF EXISTS `t_fans`; +CREATE TABLE `t_fans` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户ID', + `fans_id` varchar(32) 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_fansid`(`user_id`, `fans_id`) USING BTREE, + INDEX `idx_nor_userid`(`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '粉丝信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_message +-- ---------------------------- +DROP TABLE IF EXISTS `t_message`; +CREATE TABLE `t_message` ( + `id` bigint(20) NOT NULL COMMENT '主键ID', + `from_user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '发送方用户ID', + `to_user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '接收方用户ID', + `message_type` int(11) NULL DEFAULT NULL COMMENT '消息类型(1:系统消息 2:提醒审批通知 3::审批完成通知)', + `message_status` int(11) NOT NULL COMMENT '消息状态(1:已读 2:未读)', + `message_title` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '消息标题', + `message_content` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '消息内容', + `deleted` int(11) NOT NULL DEFAULT 0 COMMENT '是否已被删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_nor_from_userid`(`from_user_id`, `deleted`) USING BTREE, + INDEX `idx_nor_to_userid`(`to_user_id`, `deleted`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '消息信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_organization +-- ---------------------------- +DROP TABLE IF EXISTS `t_organization`; +CREATE TABLE `t_organization` ( + `organization_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织ID', + `organization_name` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织名称', + `organization_avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织封面、背景图', + `organization_creater` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织创建者ID', + `organization_creater_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织创建者的名称', + `organization_creater_avatar` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织创建者头像', + `organization_admin` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组织管理员ID', + `organization_admin_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组织管理员名称', + `slogan` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组织口号', + `capacity` int(11) NOT NULL COMMENT '组织最大容纳人数', + `status` int(11) NOT NULL COMMENT '组织状态', + `approve_status` int(11) NOT NULL COMMENT '组织审批状态', + `approve_message` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '审批留言', + `deleted` int(11) NOT NULL DEFAULT 0 COMMENT '是否已被删除', + `approve_time` datetime NULL DEFAULT NULL COMMENT '审批时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`organization_id`) USING BTREE, + UNIQUE INDEX `idx_uni_name`(`organization_name`, `deleted`) USING BTREE COMMENT '组织名称唯一索引' +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '组织信息' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_organization_user_rel +-- ---------------------------- +DROP TABLE IF EXISTS `t_organization_user_rel`; +CREATE TABLE `t_organization_user_rel` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户ID', + `organization_id` varchar(32) 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_organizationId`(`user_id`, `organization_id`) USING BTREE, + INDEX `idx_nor_userId`(`user_id`) USING BTREE, + INDEX `idx_nor_organizationId`(`organization_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 34 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '组织和用户的关系信息' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_permission +-- ---------------------------- +DROP TABLE IF EXISTS `t_permission`; +CREATE TABLE `t_permission` ( + `permission_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限ID', + `parent_id` int(11) NOT NULL COMMENT '父ID', + `permission_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色名', + `permission_code` varchar(32) 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 (`permission_id`) USING BTREE, + UNIQUE INDEX `idx_uni_name`(`permission_name`) USING BTREE COMMENT '用户权限名唯一索引', + UNIQUE INDEX `idx_uni_code`(`permission_code`) USING BTREE COMMENT '用户权限代码描述唯一索引' +) ENGINE = InnoDB AUTO_INCREMENT = 48 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户权限信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_role +-- ---------------------------- +DROP TABLE IF EXISTS `t_role`; +CREATE TABLE `t_role` ( + `role_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色ID', + `role_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色名', + `role_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色代码描述', + `role_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '角色中文描述', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`role_id`) USING BTREE, + UNIQUE INDEX `idx_uni_name`(`role_name`) USING BTREE COMMENT '角色名唯一索引', + UNIQUE INDEX `idx_uni_code`(`role_code`) USING BTREE COMMENT '角色代码描述唯一索引' +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户角色信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_role_permission_rel +-- ---------------------------- +DROP TABLE IF EXISTS `t_role_permission_rel`; +CREATE TABLE `t_role_permission_rel` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `role_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色id', + `permission_id` int(11) NOT NULL COMMENT '权限id', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_uni_roleId_permissionId`(`role_id`, `permission_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 640 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色权限关系表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_user +-- ---------------------------- +DROP TABLE IF EXISTS `t_user`; +CREATE TABLE `t_user` ( + `user_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户ID', + `role_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户角色ID', + `user_name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名', + `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户密码', + `homepage_cover` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '个人主页背景图', + `sign` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '签名', + `sex` int(4) NULL DEFAULT NULL COMMENT '性别(1:男 2:女 3:未知)', + `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户手机号码', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户邮箱地址', + `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户地址', + `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1' COMMENT '用户头像', + `speak_status` int(11) NOT NULL DEFAULT 1 COMMENT '是否可以发言', + `status` int(11) NOT NULL COMMENT '用户状态(1:正常 2:锁定)', + `deleted` int(11) NOT NULL DEFAULT 0 COMMENT '是否已被删除(1:已删除 0:未删除)', + `show_fans_list` int(11) NOT NULL DEFAULT 1 COMMENT '是否展示粉丝列表', + `show_favorite_list` int(11) NOT NULL DEFAULT 1 COMMENT '是否展示收藏列表', + `show_category_list` int(11) NOT NULL DEFAULT 1 COMMENT '是否展示分类列表', + `id` int(11) NULL DEFAULT NULL COMMENT '映射ID', + `last_login_time` datetime NULL DEFAULT NULL COMMENT '最近一次登录时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`user_id`) USING BTREE, + UNIQUE INDEX `idx_uni_username`(`user_name`, `deleted`) USING BTREE COMMENT '未删除的用户的用户名唯一索引', + UNIQUE INDEX `idx_uni_id`(`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户信息' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_user_apply_organization +-- ---------------------------- +DROP TABLE IF EXISTS `t_user_apply_organization`; +CREATE TABLE `t_user_apply_organization` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户ID', + `organization_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织ID', + `approve_user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '审批人', + `approve_user_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '审批人名称', + `approve_time` datetime NULL DEFAULT NULL COMMENT '审批时间', + `approve_message` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '审批留言', + `approve_status` int(11) NULL DEFAULT NULL COMMENT '审批状态', + `deleted` int(11) NOT NULL COMMENT '是否已被删除', + `create_time` datetime NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_uni_userid_organizationid`(`user_id`, `organization_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户加入组织申请信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_user_sensitive +-- ---------------------------- +DROP TABLE IF EXISTS `t_user_sensitive`; +CREATE TABLE `t_user_sensitive` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户ID', + `role_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '角色ID', + `speech_content` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '发言内容', + `deleted` int(11) NOT NULL DEFAULT 0 COMMENT '是否已被删除', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_nor_userid`(`user_id`, `deleted`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户敏感发言记录表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for t_user_updatepwd_times +-- ---------------------------- +DROP TABLE IF EXISTS `t_user_updatepwd_times`; +CREATE TABLE `t_user_updatepwd_times` ( + `id` bigint(20) NOT NULL COMMENT '主键', + `user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户ID', + `times` int(11) NOT NULL COMMENT '次数', + `date` date NOT NULL COMMENT '日期', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户当月修改密码次数' ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/pom.xml b/pom.xml index e4e2efe..680123c 100644 --- a/pom.xml +++ b/pom.xml @@ -180,7 +180,6 @@ pagehelper-spring-boot-starter ${pagehelper-version} -