├── .gitignore ├── LICENSE ├── README.md ├── blog-springboot ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── ican │ │ ├── BlogApplication.java │ │ ├── annotation │ │ ├── AccessLimit.java │ │ ├── CommentType.java │ │ ├── OptLogger.java │ │ └── VisitLogger.java │ │ ├── aspect │ │ ├── ExceptionLogAspect.java │ │ ├── OptLogAspect.java │ │ └── VisitLogAspect.java │ │ ├── config │ │ ├── ElasticsearchConfig.java │ │ ├── Knife4jConfig.java │ │ ├── MyBatisPlusConfig.java │ │ ├── RabbitMqConfig.java │ │ ├── RedisConfig.java │ │ ├── ThreadPoolConfig.java │ │ └── properties │ │ │ ├── CosProperties.java │ │ │ ├── GiteeProperties.java │ │ │ ├── GithubProperties.java │ │ │ ├── OssProperties.java │ │ │ ├── QqProperties.java │ │ │ └── ThreadPoolProperties.java │ │ ├── constant │ │ ├── CommonConstant.java │ │ ├── ElasticConstant.java │ │ ├── MqConstant.java │ │ ├── OptTypeConstant.java │ │ ├── PageConstant.java │ │ ├── RedisConstant.java │ │ ├── ScheduleConstant.java │ │ └── SocialLoginConstant.java │ │ ├── consumer │ │ ├── ArticleConsumer.java │ │ └── EmailConsumer.java │ │ ├── controller │ │ ├── AlbumController.java │ │ ├── ArticleController.java │ │ ├── BlogInfoController.java │ │ ├── CategoryController.java │ │ ├── CommentController.java │ │ ├── FriendController.java │ │ ├── LogController.java │ │ ├── LoginController.java │ │ ├── MenuController.java │ │ ├── MessageController.java │ │ ├── PhotoController.java │ │ ├── RoleController.java │ │ ├── SiteConfigController.java │ │ ├── TagController.java │ │ ├── TalkController.java │ │ ├── TaskController.java │ │ ├── UserController.java │ │ └── UserInfoController.java │ │ ├── entity │ │ ├── Album.java │ │ ├── Article.java │ │ ├── ArticleTag.java │ │ ├── Category.java │ │ ├── Comment.java │ │ ├── ExceptionLog.java │ │ ├── Friend.java │ │ ├── Menu.java │ │ ├── Message.java │ │ ├── OperationLog.java │ │ ├── Photo.java │ │ ├── Role.java │ │ ├── RoleMenu.java │ │ ├── SiteConfig.java │ │ ├── Tag.java │ │ ├── Talk.java │ │ ├── Task.java │ │ ├── TaskLog.java │ │ ├── User.java │ │ ├── UserRole.java │ │ └── VisitLog.java │ │ ├── enums │ │ ├── ArticleStatusEnum.java │ │ ├── CommentTypeEnum.java │ │ ├── FilePathEnum.java │ │ ├── LikeTypeEnum.java │ │ ├── LoginTypeEnum.java │ │ ├── RoleEnum.java │ │ ├── SearchModeEnum.java │ │ ├── StatusCodeEnum.java │ │ ├── TaskStatusEnum.java │ │ ├── UploadModeEnum.java │ │ └── ZoneEnum.java │ │ ├── exception │ │ └── ServiceException.java │ │ ├── handler │ │ ├── GlobalExceptionHandler.java │ │ └── MyMetaObjectHandler.java │ │ ├── interceptor │ │ ├── AccessLimitInterceptor.java │ │ └── PageableInterceptor.java │ │ ├── manager │ │ ├── AsyncManager.java │ │ ├── ShutdownManager.java │ │ └── factory │ │ │ └── AsyncFactory.java │ │ ├── mapper │ │ ├── AlbumMapper.java │ │ ├── ArticleMapper.java │ │ ├── ArticleTagMapper.java │ │ ├── CategoryMapper.java │ │ ├── CommentMapper.java │ │ ├── ExceptionLogMapper.java │ │ ├── FriendMapper.java │ │ ├── MenuMapper.java │ │ ├── MessageMapper.java │ │ ├── OperationLogMapper.java │ │ ├── PhotoMapper.java │ │ ├── RoleMapper.java │ │ ├── RoleMenuMapper.java │ │ ├── SiteConfigMapper.java │ │ ├── TagMapper.java │ │ ├── TalkMapper.java │ │ ├── TaskLogMapper.java │ │ ├── TaskMapper.java │ │ ├── UserMapper.java │ │ ├── UserRoleMapper.java │ │ └── VisitLogMapper.java │ │ ├── model │ │ ├── dto │ │ │ ├── AlbumDTO.java │ │ │ ├── ArticleDTO.java │ │ │ ├── CanalDTO.java │ │ │ ├── CategoryDTO.java │ │ │ ├── CheckDTO.java │ │ │ ├── CommentDTO.java │ │ │ ├── ConditionDTO.java │ │ │ ├── DeleteDTO.java │ │ │ ├── DisableDTO.java │ │ │ ├── EmailDTO.java │ │ │ ├── FriendDTO.java │ │ │ ├── GitDTO.java │ │ │ ├── LoginDTO.java │ │ │ ├── MailDTO.java │ │ │ ├── MenuDTO.java │ │ │ ├── MessageDTO.java │ │ │ ├── PasswordDTO.java │ │ │ ├── PhotoDTO.java │ │ │ ├── PhotoInfoDTO.java │ │ │ ├── RecommendDTO.java │ │ │ ├── RegisterDTO.java │ │ │ ├── RoleDTO.java │ │ │ ├── RoleStatusDTO.java │ │ │ ├── StatusDTO.java │ │ │ ├── TagDTO.java │ │ │ ├── TalkDTO.java │ │ │ ├── TaskDTO.java │ │ │ ├── TaskRunDTO.java │ │ │ ├── TopDTO.java │ │ │ ├── UserDTO.java │ │ │ ├── UserInfoDTO.java │ │ │ └── UserRoleDTO.java │ │ └── vo │ │ │ ├── AlbumBackVO.java │ │ │ ├── AlbumVO.java │ │ │ ├── ArchiveVO.java │ │ │ ├── ArticleBackVO.java │ │ │ ├── ArticleConditionList.java │ │ │ ├── ArticleConditionVO.java │ │ │ ├── ArticleHomeVO.java │ │ │ ├── ArticleInfoVO.java │ │ │ ├── ArticlePaginationVO.java │ │ │ ├── ArticleRankVO.java │ │ │ ├── ArticleRecommendVO.java │ │ │ ├── ArticleSearchVO.java │ │ │ ├── ArticleStatisticsVO.java │ │ │ ├── ArticleVO.java │ │ │ ├── BlogBackInfoVO.java │ │ │ ├── BlogInfoVO.java │ │ │ ├── CategoryBackVO.java │ │ │ ├── CategoryOptionVO.java │ │ │ ├── CategoryVO.java │ │ │ ├── CommentBackVO.java │ │ │ ├── CommentCountVO.java │ │ │ ├── CommentVO.java │ │ │ ├── FriendBackVO.java │ │ │ ├── FriendVO.java │ │ │ ├── GitUserInfoVO.java │ │ │ ├── MenuOption.java │ │ │ ├── MenuTree.java │ │ │ ├── MenuVO.java │ │ │ ├── MessageBackVO.java │ │ │ ├── MessageVO.java │ │ │ ├── MetaVO.java │ │ │ ├── OnlineVO.java │ │ │ ├── OperationLogVO.java │ │ │ ├── PageResult.java │ │ │ ├── PhotoBackVO.java │ │ │ ├── PhotoVO.java │ │ │ ├── RecentCommentVO.java │ │ │ ├── ReplyCountVO.java │ │ │ ├── ReplyVO.java │ │ │ ├── Result.java │ │ │ ├── RoleVO.java │ │ │ ├── RouterVO.java │ │ │ ├── SocialTokenVO.java │ │ │ ├── SocialUserInfoVO.java │ │ │ ├── TagBackVO.java │ │ │ ├── TagOptionVO.java │ │ │ ├── TagVO.java │ │ │ ├── TalkBackInfoVO.java │ │ │ ├── TalkBackVO.java │ │ │ ├── TalkVO.java │ │ │ ├── TaskBackVO.java │ │ │ ├── TaskLogVO.java │ │ │ ├── TokenVO.java │ │ │ ├── UserBackInfoVO.java │ │ │ ├── UserBackVO.java │ │ │ ├── UserInfoVO.java │ │ │ ├── UserMenuVO.java │ │ │ ├── UserRoleVO.java │ │ │ └── UserViewVO.java │ │ ├── quartz │ │ ├── execution │ │ │ ├── AbstractQuartzJob.java │ │ │ ├── QuartzDisallowConcurrentExecution.java │ │ │ └── QuartzJobExecution.java │ │ ├── task │ │ │ └── TimedTask.java │ │ └── utils │ │ │ ├── CronUtils.java │ │ │ ├── ScheduleUtils.java │ │ │ └── TaskInvokeUtils.java │ │ ├── satoken │ │ ├── MySaTokenListener.java │ │ ├── SaTokenConfig.java │ │ └── StpInterfaceImpl.java │ │ ├── service │ │ ├── AlbumService.java │ │ ├── ArticleService.java │ │ ├── BlogInfoService.java │ │ ├── CategoryService.java │ │ ├── CommentService.java │ │ ├── ElasticsearchService.java │ │ ├── EmailService.java │ │ ├── ExceptionLogService.java │ │ ├── FriendService.java │ │ ├── LoginService.java │ │ ├── MenuService.java │ │ ├── MessageService.java │ │ ├── OperationLogService.java │ │ ├── PhotoService.java │ │ ├── RedisService.java │ │ ├── RoleService.java │ │ ├── SiteConfigService.java │ │ ├── TagService.java │ │ ├── TalkService.java │ │ ├── TaskLogService.java │ │ ├── TaskService.java │ │ ├── UserService.java │ │ ├── VisitLogService.java │ │ └── impl │ │ │ ├── AlbumServiceImpl.java │ │ │ ├── ArticleServiceImpl.java │ │ │ ├── BlogInfoServiceImpl.java │ │ │ ├── CategoryServiceImpl.java │ │ │ ├── CommentServiceImpl.java │ │ │ ├── ElasticsearchServiceImpl.java │ │ │ ├── EmailServiceImpl.java │ │ │ ├── ExceptionLogServiceImpl.java │ │ │ ├── FriendServiceImpl.java │ │ │ ├── LoginServiceImpl.java │ │ │ ├── MenuServiceImpl.java │ │ │ ├── MessageServiceImpl.java │ │ │ ├── OperationLogServiceImpl.java │ │ │ ├── PhotoServiceImpl.java │ │ │ ├── RedisServiceImpl.java │ │ │ ├── RoleServiceImpl.java │ │ │ ├── SiteConfigServiceImpl.java │ │ │ ├── TagServiceImpl.java │ │ │ ├── TalkServiceImpl.java │ │ │ ├── TaskLogServiceImpl.java │ │ │ ├── TaskServiceImpl.java │ │ │ ├── UserServiceImpl.java │ │ │ └── VisitLogServiceImpl.java │ │ ├── strategy │ │ ├── LikeStrategy.java │ │ ├── SearchStrategy.java │ │ ├── SocialLoginStrategy.java │ │ ├── UploadStrategy.java │ │ ├── context │ │ │ ├── LikeStrategyContext.java │ │ │ ├── SearchStrategyContext.java │ │ │ ├── SocialLoginStrategyContext.java │ │ │ └── UploadStrategyContext.java │ │ └── impl │ │ │ ├── AbstractLoginStrategyImpl.java │ │ │ ├── AbstractUploadStrategyImpl.java │ │ │ ├── ArticleLikeStrategyImpl.java │ │ │ ├── CommentLikeStrategyImpl.java │ │ │ ├── CosUploadStrategyImpl.java │ │ │ ├── EsSearchStrategyImpl.java │ │ │ ├── GiteeLoginStrategyImpl.java │ │ │ ├── GithubLoginStrategyImpl.java │ │ │ ├── LocalUploadStrategyImpl.java │ │ │ ├── MysqlSearchStrategyImpl.java │ │ │ ├── OssUploadStrategyImpl.java │ │ │ └── TalkLikeStrategyImpl.java │ │ ├── utils │ │ ├── BeanCopyUtils.java │ │ ├── CommonUtils.java │ │ ├── FileUtils.java │ │ ├── HTMLUtils.java │ │ ├── IpUtils.java │ │ ├── MimeTypeUtils.java │ │ ├── PageUtils.java │ │ ├── SecurityUtils.java │ │ ├── SpringUtils.java │ │ ├── ThreadUtils.java │ │ ├── UserAgentUtils.java │ │ └── WebUtils.java │ │ └── validator │ │ ├── CommentProvider.java │ │ ├── CommentTypeValidator.java │ │ └── groups │ │ ├── ArticleTalk.java │ │ ├── Link.java │ │ ├── ParentIdNotNull.java │ │ └── ParentIdNull.java │ └── resources │ ├── application.yml │ ├── ipdb │ └── ip2region.xdb │ ├── mapper │ ├── AlbumMapper.xml │ ├── ArticleMapper.xml │ ├── ArticleTagMapper.xml │ ├── CategoryMapper.xml │ ├── CommentMapper.xml │ ├── ExceptionLogMapper.xml │ ├── FriendMapper.xml │ ├── MenuMapper.xml │ ├── MessageMapper.xml │ ├── OperationLogMapper.xml │ ├── PhotoMapper.xml │ ├── RoleMapper.xml │ ├── RoleMenuMapper.xml │ ├── SiteConfigMapper.xml │ ├── TagMapper.xml │ ├── TalkMapper.xml │ ├── TaskLogMapper.xml │ ├── TaskMapper.xml │ ├── UserMapper.xml │ ├── UserRoleMapper.xml │ └── VisitLogMapper.xml │ └── templates │ ├── author.html │ ├── common.html │ └── user.html ├── blog-vue ├── shoka-admin │ ├── .gitignore │ ├── .vscode │ │ └── extensions.json │ ├── README.md │ ├── auto-imports.d.ts │ ├── components.d.ts │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── App.vue │ │ ├── api │ │ │ ├── album │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── article │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── blog │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── category │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── comment │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── friend │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── log │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── login │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── menu │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── message │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── photo │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── role │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── site │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── tag │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── talk │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── task │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ └── user │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ ├── assets │ │ │ ├── 404_images │ │ │ │ ├── 404.png │ │ │ │ └── 404_cloud.png │ │ │ ├── icons │ │ │ │ ├── 404.svg │ │ │ │ ├── album.svg │ │ │ │ ├── archives.svg │ │ │ │ ├── article.svg │ │ │ │ ├── bug.svg │ │ │ │ ├── build.svg │ │ │ │ ├── button.svg │ │ │ │ ├── cascader.svg │ │ │ │ ├── category.svg │ │ │ │ ├── chart.svg │ │ │ │ ├── checkbox.svg │ │ │ │ ├── clipboard.svg │ │ │ │ ├── close.svg │ │ │ │ ├── code.svg │ │ │ │ ├── color.svg │ │ │ │ ├── comment.svg │ │ │ │ ├── component.svg │ │ │ │ ├── dashboard.svg │ │ │ │ ├── date-range.svg │ │ │ │ ├── date.svg │ │ │ │ ├── dict.svg │ │ │ │ ├── documentation.svg │ │ │ │ ├── download.svg │ │ │ │ ├── drag.svg │ │ │ │ ├── druid.svg │ │ │ │ ├── edit.svg │ │ │ │ ├── education.svg │ │ │ │ ├── email.svg │ │ │ │ ├── emoji.svg │ │ │ │ ├── example.svg │ │ │ │ ├── excel.svg │ │ │ │ ├── exit-fullscreen.svg │ │ │ │ ├── eye-open.svg │ │ │ │ ├── eye.svg │ │ │ │ ├── form.svg │ │ │ │ ├── friend.svg │ │ │ │ ├── fullscreen.svg │ │ │ │ ├── github.svg │ │ │ │ ├── guide.svg │ │ │ │ ├── home.svg │ │ │ │ ├── icon.svg │ │ │ │ ├── input.svg │ │ │ │ ├── international.svg │ │ │ │ ├── job.svg │ │ │ │ ├── language.svg │ │ │ │ ├── link.svg │ │ │ │ ├── list.svg │ │ │ │ ├── lock.svg │ │ │ │ ├── log.svg │ │ │ │ ├── logininfor.svg │ │ │ │ ├── message.svg │ │ │ │ ├── money.svg │ │ │ │ ├── monitor.svg │ │ │ │ ├── nested.svg │ │ │ │ ├── number.svg │ │ │ │ ├── online.svg │ │ │ │ ├── password.svg │ │ │ │ ├── pdf.svg │ │ │ │ ├── people.svg │ │ │ │ ├── peoples.svg │ │ │ │ ├── phone.svg │ │ │ │ ├── photo.svg │ │ │ │ ├── post.svg │ │ │ │ ├── qq.svg │ │ │ │ ├── question.svg │ │ │ │ ├── radio.svg │ │ │ │ ├── rate.svg │ │ │ │ ├── redis-list.svg │ │ │ │ ├── redis.svg │ │ │ │ ├── row.svg │ │ │ │ ├── search.svg │ │ │ │ ├── select.svg │ │ │ │ ├── server.svg │ │ │ │ ├── shopping.svg │ │ │ │ ├── size.svg │ │ │ │ ├── skill.svg │ │ │ │ ├── slider.svg │ │ │ │ ├── star.svg │ │ │ │ ├── swagger.svg │ │ │ │ ├── switch.svg │ │ │ │ ├── system.svg │ │ │ │ ├── tab.svg │ │ │ │ ├── table.svg │ │ │ │ ├── tag.svg │ │ │ │ ├── talk.svg │ │ │ │ ├── textarea.svg │ │ │ │ ├── theme.svg │ │ │ │ ├── time-range.svg │ │ │ │ ├── time.svg │ │ │ │ ├── tool.svg │ │ │ │ ├── top.svg │ │ │ │ ├── tree-table.svg │ │ │ │ ├── tree.svg │ │ │ │ ├── upload.svg │ │ │ │ ├── user.svg │ │ │ │ ├── validCode.svg │ │ │ │ ├── view.svg │ │ │ │ ├── wechat.svg │ │ │ │ └── zip.svg │ │ │ ├── logo.png │ │ │ └── styles │ │ │ │ ├── index.scss │ │ │ │ ├── mixin.scss │ │ │ │ ├── sidebar.scss │ │ │ │ ├── transition.scss │ │ │ │ └── variables.module.scss │ │ ├── components │ │ │ ├── Breadcrumb │ │ │ │ └── index.vue │ │ │ ├── CalendarHeatmap │ │ │ │ ├── Heatmap.ts │ │ │ │ └── index.vue │ │ │ ├── Crontab │ │ │ │ ├── day.vue │ │ │ │ ├── hour.vue │ │ │ │ ├── index.vue │ │ │ │ ├── min.vue │ │ │ │ ├── month.vue │ │ │ │ ├── result.vue │ │ │ │ ├── second.vue │ │ │ │ ├── week.vue │ │ │ │ └── year.vue │ │ │ ├── Echarts │ │ │ │ └── index.vue │ │ │ ├── Editor │ │ │ │ └── index.vue │ │ │ ├── EmojiExtension │ │ │ │ ├── data.ts │ │ │ │ ├── index.vue │ │ │ │ └── staticConfig.ts │ │ │ ├── GithubCorner │ │ │ │ └── index.vue │ │ │ ├── Hamburger │ │ │ │ └── index.vue │ │ │ ├── IconSelect │ │ │ │ └── index.vue │ │ │ ├── Pagination │ │ │ │ └── index.vue │ │ │ ├── ParentView │ │ │ │ └── index.vue │ │ │ ├── Password │ │ │ │ └── index.vue │ │ │ ├── PreviewCode │ │ │ │ └── index.vue │ │ │ ├── RightToolBar │ │ │ │ └── index.vue │ │ │ ├── Screenfull │ │ │ │ └── index.vue │ │ │ ├── Settings │ │ │ │ └── index.vue │ │ │ ├── SizeSelect │ │ │ │ └── index.vue │ │ │ ├── SvgIcon │ │ │ │ └── index.vue │ │ │ ├── TagCloud │ │ │ │ └── index.vue │ │ │ └── TagView │ │ │ │ ├── ScrollPane.vue │ │ │ │ └── index.vue │ │ ├── directive │ │ │ ├── index.ts │ │ │ └── permission │ │ │ │ └── index.ts │ │ ├── layouts │ │ │ ├── components │ │ │ │ ├── AppMain │ │ │ │ │ └── index.vue │ │ │ │ ├── NavBar │ │ │ │ │ └── index.vue │ │ │ │ └── SideBar │ │ │ │ │ ├── Link.vue │ │ │ │ │ ├── Logo.vue │ │ │ │ │ ├── SidebarItem.vue │ │ │ │ │ └── index.vue │ │ │ └── index.vue │ │ ├── main.ts │ │ ├── model │ │ │ └── index.ts │ │ ├── permission.ts │ │ ├── router │ │ │ └── index.ts │ │ ├── settings.ts │ │ ├── store │ │ │ ├── index.ts │ │ │ ├── interface │ │ │ │ └── index.ts │ │ │ └── modules │ │ │ │ ├── app.ts │ │ │ │ ├── permission.ts │ │ │ │ ├── setting.ts │ │ │ │ ├── tag.ts │ │ │ │ └── user.ts │ │ ├── utils │ │ │ ├── date.ts │ │ │ ├── emoji.ts │ │ │ ├── modal.ts │ │ │ ├── request.ts │ │ │ ├── scroll-to.ts │ │ │ └── token.ts │ │ ├── views │ │ │ ├── blog │ │ │ │ ├── article │ │ │ │ │ ├── article.vue │ │ │ │ │ └── index.vue │ │ │ │ ├── category │ │ │ │ │ └── index.vue │ │ │ │ └── tag │ │ │ │ │ └── index.vue │ │ │ ├── error │ │ │ │ └── 404.vue │ │ │ ├── home │ │ │ │ └── index.vue │ │ │ ├── login │ │ │ │ └── index.vue │ │ │ ├── monitor │ │ │ │ ├── online │ │ │ │ │ └── index.vue │ │ │ │ └── task │ │ │ │ │ └── index.vue │ │ │ ├── news │ │ │ │ ├── comment │ │ │ │ │ └── index.vue │ │ │ │ └── message │ │ │ │ │ └── index.vue │ │ │ ├── redirect │ │ │ │ └── index.vue │ │ │ ├── system │ │ │ │ ├── log │ │ │ │ │ ├── exception.vue │ │ │ │ │ ├── operation.vue │ │ │ │ │ ├── task.vue │ │ │ │ │ └── visit.vue │ │ │ │ ├── menu │ │ │ │ │ └── index.vue │ │ │ │ ├── role │ │ │ │ │ └── index.vue │ │ │ │ └── user │ │ │ │ │ └── index.vue │ │ │ └── web │ │ │ │ ├── album │ │ │ │ └── index.vue │ │ │ │ ├── friend │ │ │ │ └── index.vue │ │ │ │ ├── page │ │ │ │ └── index.vue │ │ │ │ ├── photo │ │ │ │ └── index.vue │ │ │ │ ├── site │ │ │ │ └── index.vue │ │ │ │ └── talk │ │ │ │ └── index.vue │ │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts └── shoka-blog │ ├── .gitignore │ ├── .vscode │ └── extensions.json │ ├── README.md │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ └── favicon.svg │ ├── src │ ├── App.vue │ ├── api │ │ ├── album │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── archives │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── article │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── blogInfo │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── category │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── comment │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── friend │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── login │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── message │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── tag │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── talk │ │ │ ├── index.ts │ │ │ └── types.ts │ │ └── user │ │ │ ├── index.ts │ │ │ └── types.ts │ ├── assets │ │ ├── fonts │ │ │ ├── FREDERICKATHEGREAT-REGULAR-2.TTF │ │ │ └── font.css │ │ ├── icons │ │ │ ├── album.svg │ │ │ ├── angle-left.svg │ │ │ ├── angle-right.svg │ │ │ ├── archives.svg │ │ │ ├── arrow-down.svg │ │ │ ├── arrow-up.svg │ │ │ ├── article.svg │ │ │ ├── article_link.svg │ │ │ ├── article_share.svg │ │ │ ├── author.svg │ │ │ ├── badge.svg │ │ │ ├── bilibili.svg │ │ │ ├── calendar.svg │ │ │ ├── category.svg │ │ │ ├── clock.svg │ │ │ ├── comment.svg │ │ │ ├── down.svg │ │ │ ├── edit.svg │ │ │ ├── emoji.svg │ │ │ ├── eye.svg │ │ │ ├── flower.svg │ │ │ ├── friend.svg │ │ │ ├── fun.svg │ │ │ ├── gitee.svg │ │ │ ├── github.svg │ │ │ ├── heart.svg │ │ │ ├── heng.svg │ │ │ ├── history.svg │ │ │ ├── home.svg │ │ │ ├── laba.svg │ │ │ ├── like.svg │ │ │ ├── link.cur │ │ │ ├── logout.svg │ │ │ ├── message.svg │ │ │ ├── moon.svg │ │ │ ├── normal.cur │ │ │ ├── plane.svg │ │ │ ├── qizhi.svg │ │ │ ├── qq.svg │ │ │ ├── qr_code.svg │ │ │ ├── right-arrow.svg │ │ │ ├── search.svg │ │ │ ├── sun.svg │ │ │ ├── tag.svg │ │ │ ├── talk.svg │ │ │ ├── top.svg │ │ │ ├── trumpet.svg │ │ │ ├── up.svg │ │ │ ├── update.svg │ │ │ ├── user.svg │ │ │ ├── web.svg │ │ │ └── zhaoxiang.svg │ │ ├── images │ │ │ ├── 404.gif │ │ │ └── loading.gif │ │ ├── js │ │ │ └── config.ts │ │ └── styles │ │ │ ├── common.scss │ │ │ ├── index.scss │ │ │ ├── markdown.scss │ │ │ ├── mixin.scss │ │ │ ├── theme-shoka.scss │ │ │ └── transition.scss │ ├── components │ │ ├── Catalog │ │ │ └── index.vue │ │ ├── Comment │ │ │ ├── CommentList.vue │ │ │ └── ReplyBox.vue │ │ ├── Dialog │ │ │ ├── Email.vue │ │ │ ├── Forget.vue │ │ │ ├── Login.vue │ │ │ ├── Register.vue │ │ │ └── Search.vue │ │ ├── Echarts │ │ │ └── index.vue │ │ ├── Emoji │ │ │ └── index.vue │ │ ├── Layout │ │ │ ├── Drawer │ │ │ │ └── index.vue │ │ │ ├── Footer │ │ │ │ └── index.vue │ │ │ ├── Header │ │ │ │ ├── NavBar.vue │ │ │ │ ├── Toggle.vue │ │ │ │ └── index.vue │ │ │ └── SideBar │ │ │ │ ├── Author.vue │ │ │ │ ├── Notice.vue │ │ │ │ ├── RecentComment.vue │ │ │ │ ├── WebInfo.vue │ │ │ │ └── index.vue │ │ ├── MusicPlayer │ │ │ └── index.vue │ │ ├── Oauth │ │ │ └── index.vue │ │ ├── Pagination │ │ │ ├── Paging.vue │ │ │ └── index.vue │ │ ├── Provider │ │ │ └── index.vue │ │ ├── SvgIcon │ │ │ └── index.vue │ │ ├── Tool │ │ │ └── index.vue │ │ ├── UserAvatar │ │ │ └── index.vue │ │ └── Waves │ │ │ └── index.vue │ ├── directive │ │ ├── animate │ │ │ └── index.ts │ │ └── index.ts │ ├── main.ts │ ├── model │ │ └── index.ts │ ├── permission.ts │ ├── router │ │ └── index.ts │ ├── store │ │ ├── index.ts │ │ ├── modules │ │ │ ├── app.ts │ │ │ ├── blog.ts │ │ │ └── user.ts │ │ └── types │ │ │ └── index.ts │ ├── types │ │ ├── auto-imports.d.ts │ │ ├── components.d.ts │ │ └── global.d.ts │ ├── utils │ │ ├── date.ts │ │ ├── emoji.ts │ │ ├── request.ts │ │ ├── title.ts │ │ └── token.ts │ ├── views │ │ ├── 404 │ │ │ └── index.vue │ │ ├── About │ │ │ └── index.vue │ │ ├── Album │ │ │ ├── Album.vue │ │ │ └── Photo.vue │ │ ├── Archive │ │ │ └── index.vue │ │ ├── Article │ │ │ ├── Article.vue │ │ │ └── ArticleItem.vue │ │ ├── Category │ │ │ ├── ArticleList.vue │ │ │ └── index.vue │ │ ├── Friend │ │ │ └── index.vue │ │ ├── Home │ │ │ ├── Brand │ │ │ │ └── index.vue │ │ │ ├── Swiper │ │ │ │ ├── Images.vue │ │ │ │ ├── Recommend.vue │ │ │ │ └── TalkSwiper.vue │ │ │ └── index.vue │ │ ├── Message │ │ │ └── index.vue │ │ ├── Tag │ │ │ ├── ArticleList.vue │ │ │ └── index.vue │ │ ├── Talk │ │ │ ├── Talk.vue │ │ │ └── TalkList.vue │ │ └── User │ │ │ └── index.vue │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── blog.sql └── deploy ├── .env ├── Dockerfile ├── blog-start.sh └── docker-compose.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 这是博客2.0版本,代码全部重构了。经过几天的爆肝终于部署上线了,等我出部署文档。。。 2 | 3 | 前台:https://www.ttkwsd.top 4 | 5 | 后台:https://admin.ttkwsd.top 6 | 7 | 测试账号:test@qq.com 密码:123456 8 | 9 | 接口文档:https://www.ttkwsd.top/api/doc.html 10 | 11 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/BlogApplication.java: -------------------------------------------------------------------------------- 1 | package com.ican; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.web.client.RestTemplate; 7 | 8 | /** 9 | * 博客启动类 10 | * 11 | * @author ican 12 | * @date 2022/11/28 18:54 13 | **/ 14 | @SpringBootApplication 15 | public class BlogApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(BlogApplication.class, args); 19 | } 20 | 21 | @Bean 22 | public RestTemplate restTemplate() { 23 | return new RestTemplate(); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/annotation/AccessLimit.java: -------------------------------------------------------------------------------- 1 | package com.ican.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * Redis限流注解 7 | * 8 | * @author ican 9 | */ 10 | @Documented 11 | @Target(ElementType.METHOD) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface AccessLimit { 14 | 15 | /** 16 | * 限制周期(秒) 17 | */ 18 | int seconds(); 19 | 20 | /** 21 | * 规定周期内限制次数 22 | */ 23 | int maxCount(); 24 | 25 | /** 26 | * 触发限制时的消息提示 27 | */ 28 | String msg() default "操作过于频繁请稍后再试"; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/annotation/CommentType.java: -------------------------------------------------------------------------------- 1 | package com.ican.annotation; 2 | 3 | import com.ican.validator.CommentTypeValidator; 4 | 5 | import javax.validation.Constraint; 6 | import javax.validation.Payload; 7 | import java.lang.annotation.*; 8 | 9 | /** 10 | * 评论类型注解 11 | * 12 | * @author ican 13 | **/ 14 | @Documented 15 | @Constraint(validatedBy = {CommentTypeValidator.class}) 16 | @Target(ElementType.FIELD) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | public @interface CommentType { 19 | 20 | String message() default "{javax.validation.constraints.NotBlank.message}"; 21 | 22 | Class[] groups() default {}; 23 | 24 | Class[] payload() default {}; 25 | 26 | /** 27 | * @return 评论类型 28 | */ 29 | int[] values() default {}; 30 | 31 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/annotation/OptLogger.java: -------------------------------------------------------------------------------- 1 | package com.ican.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 操作日志注解 7 | * 8 | * @author ican 9 | */ 10 | @Documented 11 | @Target(ElementType.METHOD) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface OptLogger { 14 | 15 | /** 16 | * @return 操作描述 17 | */ 18 | String value() default ""; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/annotation/VisitLogger.java: -------------------------------------------------------------------------------- 1 | package com.ican.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 访问日志注解 7 | * 8 | * @author ican 9 | */ 10 | @Documented 11 | @Target(ElementType.METHOD) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface VisitLogger { 14 | 15 | /** 16 | * @return 访问页面 17 | */ 18 | String value() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/config/MyBatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.ican.config; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 4 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 5 | import org.mybatis.spring.annotation.MapperScan; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * MybatisPlus配置 11 | * 12 | * @author ican 13 | */ 14 | @Configuration 15 | @MapperScan("com.ican.mapper") 16 | public class MyBatisPlusConfig { 17 | 18 | @Bean 19 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 20 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 21 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 22 | return interceptor; 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/config/properties/CosProperties.java: -------------------------------------------------------------------------------- 1 | package com.ican.config.properties; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * cos配置属性 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @Configuration 14 | @ConfigurationProperties(prefix = "upload.cos") 15 | public class CosProperties { 16 | 17 | /** 18 | * cos域名 19 | */ 20 | private String url; 21 | 22 | /** 23 | * 访问密钥id 24 | */ 25 | private String secretId; 26 | 27 | /** 28 | * 访问密钥密码 29 | */ 30 | private String secretKey; 31 | 32 | /** 33 | * 所属区域 34 | */ 35 | private String region; 36 | 37 | /** 38 | * 存储桶名称 39 | */ 40 | private String bucketName; 41 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/config/properties/GiteeProperties.java: -------------------------------------------------------------------------------- 1 | package com.ican.config.properties; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * Gitee配置属性 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @Configuration 14 | @ConfigurationProperties(prefix = "oauth.gitee") 15 | public class GiteeProperties { 16 | /** 17 | * clientId 18 | */ 19 | private String clientId; 20 | 21 | /** 22 | * clientSecret 23 | */ 24 | private String clientSecret; 25 | 26 | /** 27 | * Gitee登录类型 28 | */ 29 | private String grantType; 30 | 31 | /** 32 | * Gitee回调域名 33 | */ 34 | private String redirectUrl; 35 | 36 | /** 37 | * Gitee访问令牌地址 38 | */ 39 | private String accessTokenUrl; 40 | 41 | /** 42 | * Gitee用户信息地址 43 | */ 44 | private String userInfoUrl; 45 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/config/properties/GithubProperties.java: -------------------------------------------------------------------------------- 1 | package com.ican.config.properties; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * Github配置属性 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @Configuration 14 | @ConfigurationProperties(prefix = "oauth.github") 15 | public class GithubProperties { 16 | 17 | /** 18 | * clientId 19 | */ 20 | private String clientId; 21 | 22 | /** 23 | * clientSecret 24 | */ 25 | private String clientSecret; 26 | 27 | /** 28 | * Github回调域名 29 | */ 30 | private String redirectUrl; 31 | 32 | /** 33 | * Github访问令牌地址 34 | */ 35 | private String accessTokenUrl; 36 | 37 | /** 38 | * Github用户信息地址 39 | */ 40 | private String userInfoUrl; 41 | } 42 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/config/properties/OssProperties.java: -------------------------------------------------------------------------------- 1 | package com.ican.config.properties; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * oss配置属性 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @Configuration 14 | @ConfigurationProperties(prefix = "upload.oss") 15 | public class OssProperties { 16 | 17 | /** 18 | * oss域名 19 | */ 20 | private String url; 21 | 22 | /** 23 | * 终点 24 | */ 25 | private String endpoint; 26 | 27 | /** 28 | * 访问密钥id 29 | */ 30 | private String accessKeyId; 31 | 32 | /** 33 | * 访问密钥密码 34 | */ 35 | private String accessKeySecret; 36 | 37 | /** 38 | * bucket名称 39 | */ 40 | private String bucketName; 41 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/config/properties/QqProperties.java: -------------------------------------------------------------------------------- 1 | package com.ican.config.properties; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * QQ配置属性 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @Configuration 14 | @ConfigurationProperties(prefix = "oauth.qq") 15 | public class QqProperties { 16 | 17 | /** 18 | * QQ appId 19 | */ 20 | private String appId; 21 | 22 | /** 23 | * 校验token地址 24 | */ 25 | private String checkTokenUrl; 26 | 27 | /** 28 | * QQ用户信息地址 29 | */ 30 | private String userInfoUrl; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/config/properties/ThreadPoolProperties.java: -------------------------------------------------------------------------------- 1 | package com.ican.config.properties; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * 线程池参数 9 | * 10 | * @author ican 11 | * @date 2022/12/05 11:33 12 | **/ 13 | @Data 14 | @Configuration 15 | @ConfigurationProperties(prefix = "thread.pool") 16 | public class ThreadPoolProperties { 17 | 18 | /** 19 | * 核心线程池大小 20 | */ 21 | private int corePoolSize; 22 | 23 | /** 24 | * 最大可创建的线程数 25 | */ 26 | private int maxPoolSize; 27 | 28 | /** 29 | * 队列最大长度 30 | */ 31 | private int queueCapacity; 32 | 33 | /** 34 | * 线程池维护线程所允许的空闲时间 35 | */ 36 | private int keepAliveSeconds; 37 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/constant/ElasticConstant.java: -------------------------------------------------------------------------------- 1 | package com.ican.constant; 2 | 3 | /** 4 | * elasticsearch常量 5 | * 6 | * @author ican 7 | **/ 8 | public class ElasticConstant { 9 | 10 | /** 11 | * 文章索引 12 | */ 13 | public static final String ARTICLE_INDEX = "article"; 14 | 15 | /** 16 | * 文章标题 17 | */ 18 | public static final String ARTICLE_TITLE = "articleTitle"; 19 | 20 | /** 21 | * 文章内容 22 | */ 23 | public static final String ARTICLE_CONTENT = "articleContent"; 24 | 25 | /** 26 | * 高亮标签 27 | */ 28 | public static final String PRE_TAG = ""; 29 | 30 | /** 31 | * 高亮标签 32 | */ 33 | public static final String POST_TAG = ""; 34 | 35 | /** 36 | * 插入 37 | */ 38 | public static final String INSERT = "INSERT"; 39 | 40 | /** 41 | * 修改 42 | */ 43 | public static final String UPDATE = "UPDATE"; 44 | 45 | /** 46 | * 删除 47 | */ 48 | public static final String DELETE = "DELETE"; 49 | 50 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/constant/OptTypeConstant.java: -------------------------------------------------------------------------------- 1 | package com.ican.constant; 2 | 3 | /** 4 | * 日志操作类型常量 5 | * 6 | * @author ican 7 | */ 8 | public class OptTypeConstant { 9 | 10 | /** 11 | * 添加 12 | */ 13 | public static final String ADD = "添加"; 14 | 15 | /** 16 | * 删除 17 | */ 18 | public static final String DELETE = "删除"; 19 | 20 | /** 21 | * 修改 22 | */ 23 | public static final String UPDATE = "修改"; 24 | 25 | /** 26 | * 上传 27 | */ 28 | public static final String UPLOAD = "上传"; 29 | 30 | /** 31 | * 下线 32 | */ 33 | public static final String KICK = "下线"; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/constant/PageConstant.java: -------------------------------------------------------------------------------- 1 | package com.ican.constant; 2 | 3 | /** 4 | * 分页常量 5 | * 6 | * @author ican 7 | */ 8 | public class PageConstant { 9 | 10 | /** 11 | * 当前页码 12 | */ 13 | public static final String CURRENT = "current"; 14 | 15 | /** 16 | * 分页条数 17 | */ 18 | public static final String SIZE = "size"; 19 | 20 | /** 21 | * 默认条数 22 | */ 23 | public static final String DEFAULT_SIZE = "10"; 24 | 25 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/constant/ScheduleConstant.java: -------------------------------------------------------------------------------- 1 | package com.ican.constant; 2 | 3 | /** 4 | * 任务调度常量 5 | * 6 | * @author ican 7 | */ 8 | public class ScheduleConstant { 9 | 10 | /** 11 | * 执行类名 12 | */ 13 | public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; 14 | 15 | /** 16 | * 执行目标key 17 | */ 18 | public static final String TASK_PROPERTIES = "TASK_PROPERTIES"; 19 | 20 | /** 21 | * 默认 22 | */ 23 | public static final int MISFIRE_DEFAULT = 0; 24 | 25 | /** 26 | * 立即触发执行 27 | */ 28 | public static final int MISFIRE_IGNORE_MISFIRES = 1; 29 | 30 | /** 31 | * 触发一次执行 32 | */ 33 | public static final int MISFIRE_FIRE_AND_PROCEED = 2; 34 | 35 | /** 36 | * 不触发立即执行 37 | */ 38 | public static final int MISFIRE_DO_NOTHING = 3; 39 | } 40 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/entity/ArticleTag.java: -------------------------------------------------------------------------------- 1 | package com.ican.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * 文章标签 12 | * 13 | * @author ican 14 | * @date 2022/12/04 21:46 15 | **/ 16 | @Data 17 | @Builder 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class ArticleTag { 21 | 22 | /** 23 | * id 24 | */ 25 | @TableId(type = IdType.AUTO) 26 | private Integer id; 27 | 28 | /** 29 | * 文章id 30 | */ 31 | private Integer articleId; 32 | 33 | /** 34 | * 标签id 35 | */ 36 | private Integer tagId; 37 | 38 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/entity/RoleMenu.java: -------------------------------------------------------------------------------- 1 | package com.ican.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * 角色菜单 12 | * 13 | * @author ican 14 | * @date 2022/11/29 22:13 15 | **/ 16 | @Data 17 | @Builder 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class RoleMenu { 21 | 22 | /** 23 | * 主键 24 | */ 25 | @TableId(type = IdType.AUTO) 26 | private Integer id; 27 | 28 | /** 29 | * 角色id 30 | */ 31 | private String roleId; 32 | 33 | /** 34 | * 菜单id 35 | */ 36 | private Integer menuId; 37 | 38 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/entity/UserRole.java: -------------------------------------------------------------------------------- 1 | package com.ican.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * 用户角色 12 | * 13 | * @author ican 14 | * @date 2022/11/29 22:13 15 | **/ 16 | @Data 17 | @Builder 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class UserRole { 21 | 22 | /** 23 | * 主键 24 | */ 25 | @TableId(type = IdType.AUTO) 26 | private Integer id; 27 | 28 | /** 29 | * 用户id 30 | */ 31 | private Integer userId; 32 | 33 | /** 34 | * 角色id 35 | */ 36 | private String roleId; 37 | 38 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/enums/ArticleStatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.ican.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 文章状态枚举 8 | * 9 | * @author ican 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum ArticleStatusEnum { 14 | 15 | /** 16 | * 公开 17 | */ 18 | PUBLIC(1, "公开"), 19 | 20 | /** 21 | * 私密 22 | */ 23 | SECRET(2, "私密"), 24 | 25 | /** 26 | * 草稿 27 | */ 28 | DRAFT(3, "草稿"); 29 | 30 | /** 31 | * 状态 32 | */ 33 | private final Integer status; 34 | 35 | /** 36 | * 描述 37 | */ 38 | private final String description; 39 | } 40 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/enums/FilePathEnum.java: -------------------------------------------------------------------------------- 1 | package com.ican.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 文件路径枚举 8 | * 9 | * @author ican 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum FilePathEnum { 14 | 15 | /** 16 | * 头像路径 17 | */ 18 | AVATAR("avatar/", "头像路径"), 19 | 20 | /** 21 | * 文章图片路径 22 | */ 23 | ARTICLE("article/", "文章图片路径"), 24 | 25 | /** 26 | * 配置图片路径 27 | */ 28 | CONFIG("config/", "配置图片路径"), 29 | 30 | /** 31 | * 说说图片路径 32 | */ 33 | TALK("talk/", "说说图片路径"), 34 | 35 | /** 36 | * 照片路径 37 | */ 38 | PHOTO("photo/", "相册路径"); 39 | 40 | /** 41 | * 路径 42 | */ 43 | private final String path; 44 | 45 | /** 46 | * 描述 47 | */ 48 | private final String description; 49 | } 50 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/enums/LikeTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.ican.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 点赞类型枚举 8 | * 9 | * @author ican 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum LikeTypeEnum { 14 | 15 | /** 16 | * 文章 17 | */ 18 | ARTICLE("文章", "articleLikeStrategyImpl"), 19 | 20 | /** 21 | * 评论 22 | */ 23 | COMMENT("评论", "commentLikeStrategyImpl"), 24 | 25 | /** 26 | * 说说 27 | */ 28 | TALK("说说", "talkLikeStrategyImpl"); 29 | 30 | /** 31 | * 点赞类型 32 | */ 33 | private final String likeType; 34 | 35 | /** 36 | * 策略 37 | */ 38 | private final String strategy; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/enums/LoginTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.ican.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 登录方式枚举 8 | * 9 | * @author ican 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum LoginTypeEnum { 14 | 15 | /** 16 | * 邮箱 17 | */ 18 | EMAIL(1, "邮箱登录", ""), 19 | 20 | /** 21 | * QQ 22 | */ 23 | QQ(2, "QQ登录", "qqLoginStrategyImpl"), 24 | 25 | /** 26 | * Gitee 27 | */ 28 | GITEE(3, "Gitee登录", "giteeLoginStrategyImpl"), 29 | 30 | /** 31 | * Github 32 | */ 33 | GITHUB(4, "Github登录", "githubLoginStrategyImpl"); 34 | 35 | /** 36 | * 登录方式 37 | */ 38 | private final Integer loginType; 39 | 40 | /** 41 | * 描述 42 | */ 43 | private final String description; 44 | 45 | /** 46 | * 策略 47 | */ 48 | private final String strategy; 49 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/enums/RoleEnum.java: -------------------------------------------------------------------------------- 1 | package com.ican.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 角色枚举 8 | * 9 | * @author ican 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum RoleEnum { 14 | /** 15 | * 管理员 16 | */ 17 | ADMIN("1", "admin"), 18 | /** 19 | * 用户 20 | */ 21 | USER("2", "user"), 22 | /** 23 | * 测试账号 24 | */ 25 | TEST("3", "test"); 26 | 27 | /** 28 | * 角色id 29 | */ 30 | private final String roleId; 31 | 32 | /** 33 | * 描述 34 | */ 35 | private final String name; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/enums/SearchModeEnum.java: -------------------------------------------------------------------------------- 1 | package com.ican.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 搜索模式枚举 8 | * 9 | * @author ican 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum SearchModeEnum { 14 | 15 | /** 16 | * mysql 17 | */ 18 | MYSQL("mysql", "mySqlSearchStrategyImpl"), 19 | /** 20 | * elasticsearch 21 | */ 22 | ELASTICSEARCH("elasticsearch", "esSearchStrategyImpl"); 23 | 24 | /** 25 | * 模式 26 | */ 27 | private final String mode; 28 | 29 | /** 30 | * 策略 31 | */ 32 | private final String strategy; 33 | 34 | /** 35 | * 获取策略 36 | * 37 | * @param mode 模式 38 | * @return {@link String} 搜索策略 39 | */ 40 | public static String getStrategy(String mode) { 41 | for (SearchModeEnum value : SearchModeEnum.values()) { 42 | if (value.getMode().equals(mode)) { 43 | return value.getStrategy(); 44 | } 45 | } 46 | return null; 47 | } 48 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/enums/StatusCodeEnum.java: -------------------------------------------------------------------------------- 1 | package com.ican.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 状态码枚举 8 | * 9 | * @author ican 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum StatusCodeEnum { 14 | 15 | /** 16 | * 操作成功 17 | */ 18 | SUCCESS(200, "操作成功"), 19 | 20 | /** 21 | * 参数错误 22 | */ 23 | VALID_ERROR(400, "参数错误"), 24 | 25 | /** 26 | * 未登录 27 | */ 28 | UNAUTHORIZED(402, "未登录"), 29 | 30 | /** 31 | * 系统异常 32 | */ 33 | SYSTEM_ERROR(-1, "系统异常"), 34 | 35 | /** 36 | * 操作失败 37 | */ 38 | FAIL(500, "操作失败"); 39 | 40 | /** 41 | * 状态码 42 | */ 43 | private final Integer code; 44 | 45 | /** 46 | * 返回信息 47 | */ 48 | private final String msg; 49 | 50 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/enums/TaskStatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.ican.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 任务状态枚举 8 | * 9 | * @author ican 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum TaskStatusEnum { 14 | 15 | /** 16 | * 运行 17 | */ 18 | RUNNING(0), 19 | 20 | /** 21 | * 暂停 22 | */ 23 | PAUSE(1); 24 | 25 | /** 26 | * 状态 27 | */ 28 | private final Integer status; 29 | } 30 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/enums/ZoneEnum.java: -------------------------------------------------------------------------------- 1 | package com.ican.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 时区枚举 8 | * 9 | * @author ican 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum ZoneEnum { 14 | 15 | /** 16 | * 上海 17 | */ 18 | SHANGHAI("Asia/Shanghai", "中国上海"); 19 | 20 | /** 21 | * 时区 22 | */ 23 | private final String zone; 24 | 25 | /** 26 | * 描述 27 | */ 28 | private final String description; 29 | 30 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/exception/ServiceException.java: -------------------------------------------------------------------------------- 1 | package com.ican.exception; 2 | 3 | import lombok.Getter; 4 | 5 | import static com.ican.enums.StatusCodeEnum.FAIL; 6 | 7 | /** 8 | * 业务异常 9 | * 10 | * @author ican 11 | * @date 2022/12/02 16:18 12 | **/ 13 | @Getter 14 | public final class ServiceException extends RuntimeException { 15 | 16 | /** 17 | * 返回失败状态码 18 | */ 19 | private Integer code = FAIL.getCode(); 20 | 21 | /** 22 | * 返回信息 23 | */ 24 | private final String message; 25 | 26 | public ServiceException(String message) { 27 | this.message = message; 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/manager/ShutdownManager.java: -------------------------------------------------------------------------------- 1 | package com.ican.manager; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.annotation.PreDestroy; 8 | 9 | /** 10 | * 确保应用退出时能关闭后台线程 11 | * 12 | * @author ican 13 | */ 14 | @Component 15 | public class ShutdownManager { 16 | 17 | private static final Logger logger = LoggerFactory.getLogger(ShutdownManager.class); 18 | 19 | @PreDestroy 20 | public void destroy() { 21 | shutdownAsyncManager(); 22 | } 23 | 24 | /** 25 | * 停止异步执行任务 26 | */ 27 | private void shutdownAsyncManager() { 28 | try { 29 | logger.info("====关闭后台任务任务线程池===="); 30 | AsyncManager.getInstance().shutdown(); 31 | } catch (Exception e) { 32 | logger.error(e.getMessage(), e); 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/mapper/ArticleTagMapper.java: -------------------------------------------------------------------------------- 1 | package com.ican.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ican.entity.ArticleTag; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 文章标签 Mapper 12 | * 13 | * @author ican 14 | */ 15 | @Repository 16 | public interface ArticleTagMapper extends BaseMapper { 17 | 18 | /** 19 | * 批量保存文章标签 20 | * 21 | * @param articleId 文章id 22 | * @param tagIdList 标签id列表 23 | */ 24 | void saveBatchArticleTag(@Param("articleId") Integer articleId, List tagIdList); 25 | } 26 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/mapper/CategoryMapper.java: -------------------------------------------------------------------------------- 1 | package com.ican.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ican.entity.Category; 5 | import com.ican.model.vo.CategoryBackVO; 6 | import com.ican.model.vo.CategoryVO; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * 分类 Mapper 14 | * 15 | * @author ican 16 | * @date 2022/12/02 17:34 17 | **/ 18 | @Repository 19 | public interface CategoryMapper extends BaseMapper { 20 | 21 | /** 22 | * 查询后台分类列表 23 | * 24 | * @param limit 页码 25 | * @param size 大小 26 | * @param keyword 关键字 27 | * @return 后台分类列表 28 | */ 29 | List selectCategoryBackVO(@Param("limit") Long limit, @Param("size") Long size, @Param("keyword") String keyword); 30 | 31 | /** 32 | * 查询分类列表 33 | * 34 | * @return 分类列表 35 | */ 36 | List selectCategoryVO(); 37 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/mapper/ExceptionLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.ican.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ican.entity.ExceptionLog; 5 | import com.ican.model.dto.ConditionDTO; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * 异常日志Mapper 13 | * 14 | * @author ican 15 | */ 16 | @Repository 17 | public interface ExceptionLogMapper extends BaseMapper { 18 | 19 | /** 20 | * 查询异常日志 21 | * 22 | * @param limit 页码 23 | * @param size 大小 24 | * @param condition 条件 25 | * @return 异常日志列表 26 | */ 27 | List selectExceptionLogList(@Param("limit") Long limit, @Param("size") Long size, @Param("condition") ConditionDTO condition); 28 | } 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/mapper/FriendMapper.java: -------------------------------------------------------------------------------- 1 | package com.ican.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ican.entity.Friend; 5 | import com.ican.model.vo.FriendBackVO; 6 | import com.ican.model.vo.FriendVO; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * 友链 Mapper 14 | * 15 | * @author ican 16 | */ 17 | @Repository 18 | public interface FriendMapper extends BaseMapper { 19 | 20 | /** 21 | * 查看友链列表 22 | * 23 | * @return 友链列表 24 | */ 25 | List selectFriendVOList(); 26 | 27 | /** 28 | * 查看友链后台列表 29 | * 30 | * @param limit 页码 31 | * @param size 大小 32 | * @param keyword 条件 33 | * @return 友链后台列表 34 | */ 35 | List selectFriendBackVOList(@Param("limit") Long limit, @Param("size") Long size, @Param("keyword") String keyword); 36 | 37 | } 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/mapper/OperationLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.ican.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ican.entity.OperationLog; 5 | import com.ican.model.dto.ConditionDTO; 6 | import com.ican.model.vo.OperationLogVO; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * 操作日志 Mapper 14 | * 15 | * @author ican 16 | */ 17 | @Repository 18 | public interface OperationLogMapper extends BaseMapper { 19 | 20 | /** 21 | * 查询操作日志 22 | * 23 | * @param limit 页码 24 | * @param size 大小 25 | * @param condition 条件 26 | * @return 操作日志列表 27 | */ 28 | List selectOperationLogVOList(@Param("limit") Long limit, @Param("size") Long size, @Param("condition") ConditionDTO condition); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/mapper/PhotoMapper.java: -------------------------------------------------------------------------------- 1 | package com.ican.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ican.entity.Photo; 5 | import com.ican.model.vo.PhotoBackVO; 6 | import com.ican.model.vo.PhotoVO; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * 照片 Mapper 14 | * 15 | * @author ican 16 | */ 17 | @Repository 18 | public interface PhotoMapper extends BaseMapper { 19 | 20 | /** 21 | * 查询后台照片列表 22 | * 23 | * @param limit 页码 24 | * @param size 大小 25 | * @param albumId 相册id 26 | * @return 后台照片列表 27 | */ 28 | List selectPhotoBackVOList(@Param("limit") Long limit, @Param("size") Long size, @Param("albumId") Integer albumId); 29 | 30 | /** 31 | * 查询照片列表 32 | * 33 | * @param albumId 相册id 34 | * @return 后台照片列表 35 | */ 36 | List selectPhotoVOList(@Param("albumId") Integer albumId); 37 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/mapper/SiteConfigMapper.java: -------------------------------------------------------------------------------- 1 | package com.ican.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ican.entity.SiteConfig; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * 网站配置 Mapper 9 | * 10 | * @author ican 11 | */ 12 | @Repository 13 | public interface SiteConfigMapper extends BaseMapper { 14 | 15 | } 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.ican.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ican.entity.User; 5 | import com.ican.model.dto.ConditionDTO; 6 | import com.ican.model.vo.UserBackVO; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * 用户 Mapper 14 | * 15 | * @author ican 16 | * @date 2022/12/05 15:28 17 | **/ 18 | @Repository 19 | public interface UserMapper extends BaseMapper { 20 | 21 | /** 22 | * 查询用户后台数量 23 | * 24 | * @param condition 条件 25 | * @return 用户数量 26 | */ 27 | Long countUser(@Param("condition") ConditionDTO condition); 28 | 29 | /** 30 | * 查询后台用户列表 31 | * 32 | * @param limit 页码 33 | * @param size 大小 34 | * @param condition 条件 35 | * @return 用户后台列表 36 | */ 37 | List listUserBackVO(@Param("limit") Long limit, @Param("size") Long size, @Param("condition") ConditionDTO condition); 38 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/mapper/UserRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.ican.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.ican.entity.UserRole; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 用户角色 Mapper 12 | * 13 | * @author ican 14 | * @date 2022/12/07 11:09 15 | **/ 16 | @Repository 17 | public interface UserRoleMapper extends BaseMapper { 18 | 19 | /** 20 | * 根据用户id查询角色id 21 | * 22 | * @param userId 用户id 23 | * @return 角色id 24 | */ 25 | List selectRoleIdByUserId(@Param("userId") Integer userId); 26 | 27 | /** 28 | * 添加用户角色 29 | * 30 | * @param userId 用户id 31 | * @param roleIdList 角色id集合 32 | */ 33 | void insertUserRole(@Param("userId") Integer userId, @Param("roleIdList") List roleIdList); 34 | } 35 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/CategoryDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | 9 | /** 10 | * 分类DTO 11 | * 12 | * @author ican 13 | */ 14 | @Data 15 | @ApiModel(description = "分类DTO") 16 | public class CategoryDTO { 17 | 18 | /** 19 | * 分类id 20 | */ 21 | @ApiModelProperty(value = "分类id") 22 | private Integer id; 23 | 24 | /** 25 | * 分类名 26 | */ 27 | @NotBlank(message = "分类名不能为空") 28 | @ApiModelProperty(value = "分类名") 29 | private String categoryName; 30 | 31 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/CheckDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotNull; 8 | import java.util.List; 9 | 10 | /** 11 | * 审核DTO 12 | * 13 | * @author ican 14 | */ 15 | @Data 16 | @ApiModel(description = "审核DTO") 17 | public class CheckDTO { 18 | 19 | /** 20 | * id集合 21 | */ 22 | @NotNull(message = "id不能为空") 23 | @ApiModelProperty(value = "id集合") 24 | private List idList; 25 | 26 | /** 27 | * 是否通过 (0否 1是) 28 | */ 29 | @NotNull(message = "状态值不能为空") 30 | @ApiModelProperty(value = "是否通过 (0否 1是)") 31 | private Integer isCheck; 32 | } 33 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/DeleteDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotNull; 8 | import java.util.List; 9 | 10 | /** 11 | * 逻辑删除 12 | * 13 | * @author ican 14 | */ 15 | @Data 16 | @ApiModel(description = "逻辑删除") 17 | public class DeleteDTO { 18 | 19 | /** 20 | * id列表 21 | */ 22 | @NotNull(message = "id不能为空") 23 | @ApiModelProperty(value = "id列表") 24 | private List idList; 25 | 26 | /** 27 | * 是否删除 (0否 1是) 28 | */ 29 | @NotNull(message = "状态值不能为空") 30 | @ApiModelProperty(value = "是否删除 (0否 1是)") 31 | private Integer isDelete; 32 | } 33 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/DisableDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotNull; 8 | 9 | /** 10 | * 禁用状态 11 | * 12 | * @author ican 13 | **/ 14 | @Data 15 | @ApiModel(description = "禁用状态") 16 | public class DisableDTO { 17 | /** 18 | * id 19 | */ 20 | @NotNull(message = "id不能为空") 21 | @ApiModelProperty(value = "id") 22 | private Integer id; 23 | 24 | /** 25 | * 是否禁用 (0否 1是) 26 | */ 27 | @NotNull(message = "状态不能为空") 28 | @ApiModelProperty(value = "是否禁用 (0否 1是)") 29 | private Integer isDisable; 30 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/EmailDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.Email; 8 | import javax.validation.constraints.NotBlank; 9 | 10 | /** 11 | * 邮箱DTO 12 | * 13 | * @author ican 14 | */ 15 | @Data 16 | @ApiModel(description = "邮箱DTO") 17 | public class EmailDTO { 18 | 19 | /** 20 | * 邮箱 21 | */ 22 | @NotBlank(message = "邮箱不能为空") 23 | @Email(message = "邮箱格式不正确") 24 | @ApiModelProperty(value = "邮箱") 25 | private String email; 26 | 27 | /** 28 | * 验证码 29 | */ 30 | @NotBlank(message = "验证码不能为空") 31 | @ApiModelProperty(value = "验证码") 32 | private String code; 33 | } 34 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/GitDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | 9 | /** 10 | * Git信息 11 | * 12 | * @author ican 13 | **/ 14 | @Data 15 | @ApiModel(description = "Git信息") 16 | public class GitDTO { 17 | 18 | /** 19 | * code 20 | */ 21 | @NotBlank(message = "code不能为空") 22 | @ApiModelProperty(value = "code") 23 | private String code; 24 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/LoginDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | import javax.validation.constraints.Size; 9 | 10 | /** 11 | * 登录信息 12 | * 13 | * @author ican 14 | * @date 2022/12/04 11:17 15 | **/ 16 | @Data 17 | @ApiModel(description = "登录信息") 18 | public class LoginDTO { 19 | 20 | /** 21 | * 用户名 22 | */ 23 | @NotBlank(message = "用户名不能为空") 24 | @ApiModelProperty(value = "用户名") 25 | private String username; 26 | 27 | /** 28 | * 用户密码 29 | */ 30 | @NotBlank(message = "密码不能为空") 31 | @Size(min = 6, message = "密码不能少于6位") 32 | @ApiModelProperty(value = "用户密码") 33 | private String password; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/MessageDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | 9 | /** 10 | * 留言DTO 11 | * 12 | * @author ican 13 | * @date 2022/12/28 19:52 14 | **/ 15 | @Data 16 | @ApiModel(description = "留言DTO") 17 | public class MessageDTO { 18 | 19 | /** 20 | * 昵称 21 | */ 22 | @NotBlank(message = "昵称不能为空") 23 | @ApiModelProperty(value = "昵称") 24 | private String nickname; 25 | 26 | /** 27 | * 头像 28 | */ 29 | @NotBlank(message = "头像不能为空") 30 | @ApiModelProperty(value = "头像") 31 | private String avatar; 32 | 33 | /** 34 | * 留言内容 35 | */ 36 | @NotBlank(message = "留言内容不能为空") 37 | @ApiModelProperty(value = "留言内容") 38 | private String messageContent; 39 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/PasswordDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import javax.validation.constraints.NotBlank; 10 | import javax.validation.constraints.Size; 11 | 12 | /** 13 | * 用户密码 14 | * 15 | * @author ican 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | @ApiModel(description = "用户密码") 21 | public class PasswordDTO { 22 | 23 | /** 24 | * 旧密码 25 | */ 26 | @NotBlank(message = "旧密码不能为空") 27 | @ApiModelProperty(value = "旧密码") 28 | private String oldPassword; 29 | 30 | /** 31 | * 新密码 32 | */ 33 | @Size(min = 6, message = "新密码不能少于6位") 34 | @NotBlank(message = "新密码不能为空") 35 | @ApiModelProperty(value = "新密码") 36 | private String newPassword; 37 | } 38 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/PhotoDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotNull; 8 | import java.util.List; 9 | 10 | /** 11 | * 照片DTO 12 | * 13 | * @author ican 14 | **/ 15 | @Data 16 | @ApiModel(description = "照片DTO") 17 | public class PhotoDTO { 18 | 19 | /** 20 | * 相册id 21 | */ 22 | @NotNull(message = "相册id不能为空") 23 | @ApiModelProperty(value = "相册id") 24 | private Integer albumId; 25 | 26 | /** 27 | * 照片链接 28 | */ 29 | @ApiModelProperty(value = "照片链接") 30 | private List photoUrlList; 31 | 32 | /** 33 | * 照片id 34 | */ 35 | @ApiModelProperty(value = "照片id") 36 | private List photoIdList; 37 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/PhotoInfoDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | import javax.validation.constraints.NotNull; 9 | 10 | /** 11 | * 照片信息DTO 12 | * 13 | * @author ican 14 | **/ 15 | @Data 16 | @ApiModel(description = "照片信息DTO") 17 | public class PhotoInfoDTO { 18 | 19 | /** 20 | * 照片id 21 | */ 22 | @NotNull(message = "照片id不能为空") 23 | @ApiModelProperty(value = "照片id") 24 | private Integer id; 25 | 26 | /** 27 | * 照片名 28 | */ 29 | @NotBlank(message = "照片名不能为空") 30 | @ApiModelProperty(value = "照片名") 31 | private String photoName; 32 | 33 | /** 34 | * 照片描述 35 | */ 36 | @ApiModelProperty(value = "照片描述") 37 | private String photoDesc; 38 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/RecommendDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotNull; 8 | 9 | /** 10 | * 推荐DTO 11 | * 12 | * @author ican 13 | **/ 14 | @Data 15 | @ApiModel(description = "推荐DTO") 16 | public class RecommendDTO { 17 | 18 | /** 19 | * id 20 | */ 21 | @NotNull(message = "id不能为空") 22 | @ApiModelProperty(value = "id") 23 | private Integer id; 24 | 25 | /** 26 | * 是否推荐 (0否 1是) 27 | */ 28 | @NotNull(message = "推荐状态不能为空") 29 | @ApiModelProperty(value = "是否推荐 (0否 1是)") 30 | private Integer isRecommend; 31 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/RegisterDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.Email; 8 | import javax.validation.constraints.NotBlank; 9 | import javax.validation.constraints.Size; 10 | 11 | /** 12 | * 用户注册信息 13 | * 14 | * @author ican 15 | */ 16 | @Data 17 | @ApiModel(description = "用户注册信息") 18 | public class RegisterDTO { 19 | 20 | /** 21 | * 用户名 22 | */ 23 | @NotBlank(message = "邮箱不能为空") 24 | @Email(message = "邮箱格式不正确") 25 | @ApiModelProperty(value = "用户名") 26 | private String username; 27 | 28 | /** 29 | * 密码 30 | */ 31 | @NotBlank(message = "密码不能为空") 32 | @Size(min = 6, message = "密码不能少于6位") 33 | @ApiModelProperty(value = "密码") 34 | private String password; 35 | 36 | /** 37 | * 验证码 38 | */ 39 | @NotBlank(message = "验证码不能为空") 40 | @ApiModelProperty(value = "验证码") 41 | private String code; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/RoleStatusDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotNull; 8 | 9 | /** 10 | * 角色状态 11 | * 12 | * @author ican 13 | * @date 2022/12/19 10:31 14 | **/ 15 | @Data 16 | @ApiModel(description = "角色状态") 17 | public class RoleStatusDTO { 18 | /** 19 | * 角色id 20 | */ 21 | @NotNull(message = "角色id不能为空") 22 | @ApiModelProperty(value = "角色id") 23 | private String id; 24 | 25 | /** 26 | * 是否禁用 (0否 1是) 27 | */ 28 | @NotNull(message = "角色状态不能为空") 29 | @ApiModelProperty(value = "是否禁用 (0否 1是)") 30 | private Integer isDisable; 31 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/StatusDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotNull; 8 | 9 | /** 10 | * 状态DTO 11 | * 12 | * @author ican 13 | */ 14 | @Data 15 | @ApiModel(description = "状态DTO") 16 | public class StatusDTO { 17 | /** 18 | * id 19 | */ 20 | @NotNull(message = "id不能为空") 21 | @ApiModelProperty(value = "id") 22 | private Integer id; 23 | 24 | /** 25 | * 状态 26 | */ 27 | @NotNull(message = "状态不能为空") 28 | @ApiModelProperty(value = "状态") 29 | private Integer status; 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/TagDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | 9 | /** 10 | * 标签DTO 11 | * 12 | * @author ican 13 | */ 14 | @Data 15 | @ApiModel(description = "标签DTO") 16 | public class TagDTO { 17 | 18 | /** 19 | * 标签id 20 | */ 21 | @ApiModelProperty(value = "标签id") 22 | private Integer id; 23 | 24 | /** 25 | * 标签名 26 | */ 27 | @NotBlank(message = "标签名不能为空") 28 | @ApiModelProperty(value = "标签名") 29 | private String tagName; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/TaskRunDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 定时任务运行 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @ApiModel(description = "定时任务运行") 14 | public class TaskRunDTO { 15 | 16 | /** 17 | * 任务id 18 | */ 19 | @ApiModelProperty(value = "任务id") 20 | private Integer id; 21 | 22 | /** 23 | * 任务组别 24 | */ 25 | @ApiModelProperty(value = "任务组别") 26 | private String taskGroup; 27 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/TopDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotNull; 8 | 9 | /** 10 | * 置顶DTO 11 | * 12 | * @author ican 13 | */ 14 | @Data 15 | @ApiModel(description = "置顶DTO") 16 | public class TopDTO { 17 | 18 | /** 19 | * id 20 | */ 21 | @NotNull(message = "id不能为空") 22 | @ApiModelProperty(value = "id") 23 | private Integer id; 24 | 25 | /** 26 | * 是否置顶 (0否 1是) 27 | */ 28 | @NotNull(message = "置顶状态不能为空") 29 | @ApiModelProperty(value = "是否置顶 (0否 1是)") 30 | private Integer isTop; 31 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/UserDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.Email; 8 | import javax.validation.constraints.NotBlank; 9 | import javax.validation.constraints.Size; 10 | 11 | /** 12 | * 用户密码 13 | * 14 | * @author ican 15 | */ 16 | @Data 17 | @ApiModel(description = "用户密码") 18 | public class UserDTO { 19 | /** 20 | * 用户名 21 | */ 22 | @NotBlank(message = "邮箱不能为空") 23 | @Email(message = "邮箱格式不正确") 24 | @ApiModelProperty(value = "用户名") 25 | private String username; 26 | 27 | /** 28 | * 密码 29 | */ 30 | @NotBlank(message = "密码不能为空") 31 | @Size(min = 6, message = "密码不能少于6位") 32 | @ApiModelProperty(value = "密码") 33 | private String password; 34 | 35 | /** 36 | * 验证码 37 | */ 38 | @NotBlank(message = "验证码不能为空") 39 | private String code; 40 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/UserInfoDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | 9 | /** 10 | * 用户信息 11 | * 12 | * @author ican 13 | */ 14 | @Data 15 | @ApiModel(description = "用户信息") 16 | public class UserInfoDTO { 17 | 18 | /** 19 | * 用户昵称 20 | */ 21 | @NotBlank(message = "昵称不能为空") 22 | @ApiModelProperty(value = "用户昵称") 23 | private String nickname; 24 | 25 | /** 26 | * 个人网站 27 | */ 28 | @ApiModelProperty(value = "个人网站") 29 | private String webSite; 30 | 31 | /** 32 | * 个人简介 33 | */ 34 | @ApiModelProperty(value = "个人简介") 35 | private String intro; 36 | } 37 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/dto/UserRoleDTO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | import javax.validation.constraints.NotNull; 9 | import java.util.List; 10 | 11 | /** 12 | * 用户角色DTO 13 | * 14 | * @author ican 15 | **/ 16 | @Data 17 | @ApiModel(description = "用户角色DTO") 18 | public class UserRoleDTO { 19 | 20 | /** 21 | * 用户id 22 | */ 23 | @NotNull(message = "用户id不能为空") 24 | @ApiModelProperty(value = "用户id") 25 | private Integer id; 26 | 27 | /** 28 | * 昵称 29 | */ 30 | @NotBlank(message = "昵称不能为空") 31 | @ApiModelProperty(value = "昵称") 32 | private String nickname; 33 | 34 | /** 35 | * 角色id 36 | */ 37 | @NotNull(message = "角色id不能为空") 38 | @ApiModelProperty(value = "角色id") 39 | private List roleIdList; 40 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/AlbumVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 相册 9 | * 10 | * @author ican 11 | **/ 12 | @Data 13 | @ApiModel(description = "相册") 14 | public class AlbumVO { 15 | /** 16 | * 相册id 17 | */ 18 | @ApiModelProperty(value = "相册id") 19 | private Integer id; 20 | 21 | /** 22 | * 相册名 23 | */ 24 | @ApiModelProperty(value = "相册名") 25 | private String albumName; 26 | 27 | /** 28 | * 相册描述 29 | */ 30 | @ApiModelProperty(value = "相册描述") 31 | private String albumDesc; 32 | 33 | /** 34 | * 相册封面 35 | */ 36 | @ApiModelProperty(value = "相册封面") 37 | private String albumCover; 38 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/ArchiveVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | * 文章归档 11 | * 12 | * @author ican 13 | */ 14 | @Data 15 | @ApiModel(description = "文章归档") 16 | public class ArchiveVO { 17 | 18 | /** 19 | * 文章id 20 | */ 21 | @ApiModelProperty(value = "文章id") 22 | private Integer id; 23 | 24 | /** 25 | * 标题 26 | */ 27 | @ApiModelProperty(value = "标题") 28 | private String articleTitle; 29 | 30 | /** 31 | * 文章缩略图 32 | */ 33 | @ApiModelProperty(value = "文章缩略图") 34 | private String articleCover; 35 | 36 | /** 37 | * 发表时间 38 | */ 39 | @ApiModelProperty(value = "发表时间") 40 | private LocalDateTime createTime; 41 | } 42 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/ArticleConditionList.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 文章条件列表VO 12 | * 13 | * @author ican 14 | **/ 15 | @Data 16 | @Builder 17 | @ApiModel(description = "文章条件列表VO") 18 | public class ArticleConditionList { 19 | 20 | /** 21 | * 文章列表 22 | */ 23 | @ApiModelProperty(value = "文章列表") 24 | private List articleConditionVOList; 25 | 26 | /** 27 | * 条件名 28 | */ 29 | @ApiModelProperty(value = "条件名") 30 | private String name; 31 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/ArticlePaginationVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 文章上下篇 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @ApiModel(description = "文章上下篇") 14 | public class ArticlePaginationVO { 15 | 16 | /** 17 | * 文章id 18 | */ 19 | @ApiModelProperty(value = "文章id") 20 | private Integer id; 21 | 22 | /** 23 | * 文章缩略图 24 | */ 25 | @ApiModelProperty(value = "文章缩略图") 26 | private String articleCover; 27 | 28 | /** 29 | * 文章标题 30 | */ 31 | @ApiModelProperty(value = "文章标题") 32 | private String articleTitle; 33 | } 34 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/ArticleRankVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | /** 9 | * 文章浏览量排行 10 | * 11 | * @author ican 12 | */ 13 | @Data 14 | @Builder 15 | @ApiModel(description = "文章浏览量排行") 16 | public class ArticleRankVO { 17 | 18 | /** 19 | * 标题 20 | */ 21 | @ApiModelProperty(value = "标题") 22 | private String articleTitle; 23 | 24 | /** 25 | * 浏览量 26 | */ 27 | @ApiModelProperty(value = "浏览量") 28 | private Integer viewCount; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/ArticleRecommendVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | * 推荐文章 11 | * 12 | * @author ican 13 | **/ 14 | @Data 15 | @ApiModel(description = "推荐文章") 16 | public class ArticleRecommendVO { 17 | 18 | /** 19 | * 文章id 20 | */ 21 | @ApiModelProperty(value = "文章id") 22 | private Integer id; 23 | 24 | /** 25 | * 文章标题 26 | */ 27 | @ApiModelProperty(value = "文章标题") 28 | private String articleTitle; 29 | 30 | /** 31 | * 文章缩略图 32 | */ 33 | @ApiModelProperty(value = "文章缩略图") 34 | private String articleCover; 35 | 36 | /** 37 | * 发布时间 38 | */ 39 | @ApiModelProperty(value = "发布时间") 40 | private LocalDateTime createTime; 41 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/ArticleStatisticsVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 文章贡献统计 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @ApiModel(description = "文章贡献统计") 14 | public class ArticleStatisticsVO { 15 | 16 | /** 17 | * 日期 18 | */ 19 | @ApiModelProperty(value = "日期") 20 | private String date; 21 | 22 | /** 23 | * 数量 24 | */ 25 | @ApiModelProperty(value = "数量") 26 | private Integer count; 27 | } 28 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/CategoryBackVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | * 分类后台VO 11 | * 12 | * @author ican 13 | * @date 2022/12/03 21:43 14 | **/ 15 | @Data 16 | @ApiModel(description = "分类后台VO") 17 | public class CategoryBackVO { 18 | 19 | /** 20 | * 分类id 21 | */ 22 | @ApiModelProperty(value = "分类id") 23 | private Integer id; 24 | 25 | /** 26 | * 分类名 27 | */ 28 | @ApiModelProperty(value = "分类名") 29 | private String categoryName; 30 | 31 | /** 32 | * 文章数量 33 | */ 34 | @ApiModelProperty(value = "文章数量") 35 | private Integer articleCount; 36 | 37 | /** 38 | * 创建时间 39 | */ 40 | @ApiModelProperty(value = "创建时间") 41 | private LocalDateTime createTime; 42 | 43 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/CategoryOptionVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 分类选项VO 9 | * 10 | * @author ican 11 | **/ 12 | @Data 13 | @ApiModel(description = "分类选项VO") 14 | public class CategoryOptionVO { 15 | 16 | /** 17 | * 分类id 18 | */ 19 | @ApiModelProperty(value = "分类id") 20 | private Integer id; 21 | 22 | /** 23 | * 分类名 24 | */ 25 | @ApiModelProperty(value = "分类名") 26 | private String categoryName; 27 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/CategoryVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 分类列表 9 | * 10 | * @author ican 11 | **/ 12 | @Data 13 | @ApiModel(description = "分类列表") 14 | public class CategoryVO { 15 | 16 | /** 17 | * 分类id 18 | */ 19 | @ApiModelProperty(value = "分类id") 20 | private Integer id; 21 | 22 | /** 23 | * 分类名 24 | */ 25 | @ApiModelProperty(value = "分类名") 26 | private String categoryName; 27 | 28 | /** 29 | * 文章数量 30 | */ 31 | @ApiModelProperty(value = "文章数量") 32 | private Integer articleCount; 33 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/CommentCountVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 评论数量VO 9 | * 10 | * @author ican 11 | **/ 12 | @Data 13 | @ApiModel(description = "评论数量VO") 14 | public class CommentCountVO { 15 | /** 16 | * 类型id 17 | */ 18 | @ApiModelProperty(value = "类型id") 19 | private Integer id; 20 | 21 | /** 22 | * 评论数量 23 | */ 24 | @ApiModelProperty(value = "评论数量") 25 | private Integer commentCount; 26 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/FriendVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 友链VO 9 | * 10 | * @author ican 11 | **/ 12 | @Data 13 | @ApiModel(description = "友链VO") 14 | public class FriendVO { 15 | 16 | /** 17 | * 友链id 18 | */ 19 | @ApiModelProperty(value = "友链id") 20 | private Integer id; 21 | 22 | /** 23 | * 友链颜色 24 | */ 25 | @ApiModelProperty(value = "友链颜色") 26 | private String color; 27 | 28 | /** 29 | * 友链名称 30 | */ 31 | @ApiModelProperty(value = "友链名称") 32 | private String name; 33 | 34 | /** 35 | * 友链头像 36 | */ 37 | @ApiModelProperty(value = "友链头像") 38 | private String avatar; 39 | 40 | /** 41 | * 友链地址 42 | */ 43 | @ApiModelProperty(value = "友链地址") 44 | private String url; 45 | 46 | /** 47 | * 友链介绍 48 | */ 49 | @ApiModelProperty(value = "友链介绍") 50 | private String introduction; 51 | 52 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/GitUserInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * Git用户信息 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @ApiModel(description = "Git用户信息") 14 | public class GitUserInfoVO { 15 | 16 | /** 17 | * 用户id 18 | */ 19 | @ApiModelProperty(value = "用户id") 20 | private String id; 21 | 22 | /** 23 | * 头像 24 | */ 25 | @ApiModelProperty(value = "头像") 26 | private String avatar_url; 27 | 28 | /** 29 | * 昵称 30 | */ 31 | @ApiModelProperty(value = "昵称") 32 | private String name; 33 | 34 | /** 35 | * 登录 36 | */ 37 | @ApiModelProperty(value = "登录") 38 | private String login; 39 | } 40 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/MessageVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 留言VO 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @ApiModel(description = "留言VO") 14 | public class MessageVO { 15 | 16 | /** 17 | * 留言id 18 | */ 19 | @ApiModelProperty(value = "留言id") 20 | private Integer id; 21 | 22 | /** 23 | * 昵称 24 | */ 25 | @ApiModelProperty(value = "昵称") 26 | private String nickname; 27 | 28 | /** 29 | * 头像 30 | */ 31 | @ApiModelProperty(value = "头像") 32 | private String avatar; 33 | 34 | /** 35 | * 留言内容 36 | */ 37 | @ApiModelProperty(value = "留言内容") 38 | private String messageContent; 39 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/MetaVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | /** 9 | * 其他信息 10 | * 11 | * @author ican 12 | * @date 2022/12/11 19:35 13 | **/ 14 | @Data 15 | @Builder 16 | @ApiModel(description = "其他信息") 17 | public class MetaVO { 18 | 19 | /** 20 | * 菜单名称 21 | */ 22 | @ApiModelProperty(value = "菜单名称") 23 | private String title; 24 | 25 | /** 26 | * 菜单图标 27 | */ 28 | @ApiModelProperty(value = "菜单图标") 29 | private String icon; 30 | 31 | /** 32 | * 是否隐藏 33 | */ 34 | @ApiModelProperty(value = "是否隐藏") 35 | private Boolean hidden; 36 | 37 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/PageResult.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * 分页返回类 13 | * 14 | * @author ican 15 | * @date 2022/12/03 21:44 16 | **/ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | @ApiModel(description = "分页返回类") 21 | public class PageResult { 22 | 23 | /** 24 | * 分页结果 25 | */ 26 | @ApiModelProperty(value = "分页结果") 27 | private List recordList; 28 | 29 | /** 30 | * 总数 31 | */ 32 | @ApiModelProperty(value = "总数", dataType = "long") 33 | private Long count; 34 | 35 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/PhotoBackVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 后台照片VO 9 | * 10 | * @author ican 11 | * @date 2022/12/30 20:56 12 | **/ 13 | @Data 14 | @ApiModel(description = "后台照片VO") 15 | public class PhotoBackVO { 16 | 17 | /** 18 | * 照片id 19 | */ 20 | @ApiModelProperty(value = "照片id") 21 | private Integer id; 22 | 23 | /** 24 | * 照片名 25 | */ 26 | @ApiModelProperty(value = "照片名") 27 | private String photoName; 28 | 29 | /** 30 | * 照片描述 31 | */ 32 | @ApiModelProperty(value = "照片描述") 33 | private String photoDesc; 34 | 35 | /** 36 | * 照片地址 37 | */ 38 | @ApiModelProperty(value = "照片地址") 39 | private String photoUrl; 40 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/PhotoVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 照片VO 9 | * 10 | * @author ican 11 | **/ 12 | @Data 13 | @ApiModel(description = "照片VO") 14 | public class PhotoVO { 15 | 16 | /** 17 | * 照片id 18 | */ 19 | @ApiModelProperty(value = "照片id") 20 | private Integer id; 21 | 22 | /** 23 | * 照片链接 24 | */ 25 | @ApiModelProperty(value = "照片链接") 26 | private String photoUrl; 27 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/RecentCommentVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | * 最新评论 11 | * 12 | * @author ican 13 | **/ 14 | @Data 15 | @ApiModel(description = "最新评论") 16 | public class RecentCommentVO { 17 | 18 | /** 19 | * 评论id 20 | */ 21 | @ApiModelProperty(value = "评论id") 22 | private Integer id; 23 | 24 | /** 25 | * 用户昵称 26 | */ 27 | @ApiModelProperty(value = "用户昵称") 28 | private String nickname; 29 | 30 | /** 31 | * 用户头像 32 | */ 33 | @ApiModelProperty(value = "用户昵称") 34 | private String avatar; 35 | 36 | /** 37 | * 评论内容 38 | */ 39 | @ApiModelProperty(value = "评论内容") 40 | private String commentContent; 41 | 42 | /** 43 | * 评论时间 44 | */ 45 | @ApiModelProperty(value = "评论时间") 46 | private LocalDateTime createTime; 47 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/ReplyCountVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | /** 4 | * @author ican 5 | * @date 2023/02/07 11:29 6 | **/ 7 | 8 | import io.swagger.annotations.ApiModel; 9 | import io.swagger.annotations.ApiModelProperty; 10 | import lombok.Data; 11 | 12 | /** 13 | * 回复数VO 14 | * 15 | * @author ican 16 | */ 17 | @Data 18 | @ApiModel(description = "回复数VO") 19 | public class ReplyCountVO { 20 | 21 | /** 22 | * 评论id 23 | */ 24 | @ApiModelProperty(value = "评论id") 25 | private Integer commentId; 26 | 27 | /** 28 | * 回复数 29 | */ 30 | @ApiModelProperty(value = "回复数") 31 | private Integer replyCount; 32 | } 33 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/RoleVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | * 角色VO 11 | * 12 | * @author ican 13 | * @date 2022/12/07 09:50 14 | **/ 15 | @Data 16 | @ApiModel(description = "角色VO") 17 | public class RoleVO { 18 | 19 | /** 20 | * 角色id 21 | */ 22 | @ApiModelProperty(value = "角色id") 23 | private String id; 24 | 25 | /** 26 | * 角色名 27 | */ 28 | @ApiModelProperty(value = "角色名") 29 | private String roleName; 30 | 31 | /** 32 | * 角色描述 33 | */ 34 | @ApiModelProperty(value = "角色描述") 35 | private String roleDesc; 36 | 37 | /** 38 | * 是否禁用 (0否 1是) 39 | */ 40 | @ApiModelProperty(value = "是否禁用 (0否 1是)") 41 | private Integer isDisable; 42 | 43 | /** 44 | * 创建时间 45 | */ 46 | @ApiModelProperty(value = "创建时间") 47 | private LocalDateTime createTime; 48 | 49 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/SocialTokenVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | /** 9 | * 第三方token 10 | * 11 | * @author ican 12 | */ 13 | @Data 14 | @Builder 15 | @ApiModel(description = "第三方token") 16 | public class SocialTokenVO { 17 | 18 | /** 19 | * 开放id 20 | */ 21 | @ApiModelProperty(value = "开放id") 22 | private String openId; 23 | 24 | /** 25 | * 访问令牌 26 | */ 27 | @ApiModelProperty(value = "访问令牌") 28 | private String accessToken; 29 | 30 | /** 31 | * 登录类型 32 | */ 33 | @ApiModelProperty(value = "登录类型") 34 | private Integer loginType; 35 | 36 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/SocialUserInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | /** 9 | * 第三方账号信息 10 | * 11 | * @author ican 12 | */ 13 | @Data 14 | @Builder 15 | @ApiModel(description = "第三方账号信息") 16 | public class SocialUserInfoVO { 17 | 18 | /** 19 | * id 20 | */ 21 | @ApiModelProperty(value = "id") 22 | private String id; 23 | 24 | /** 25 | * 头像 26 | */ 27 | @ApiModelProperty(value = "头像") 28 | private String avatar; 29 | 30 | /** 31 | * 昵称 32 | */ 33 | @ApiModelProperty(value = "昵称") 34 | private String nickname; 35 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/TagBackVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | * 标签后台VO 11 | * 12 | * @author ican 13 | * @date 2022/12/04 22:37 14 | **/ 15 | @Data 16 | @ApiModel(description = "标签后台VO") 17 | public class TagBackVO { 18 | 19 | /** 20 | * 标签id 21 | */ 22 | @ApiModelProperty(value = "标签id") 23 | private Integer id; 24 | 25 | /** 26 | * 标签名 27 | */ 28 | @ApiModelProperty(value = "标签名") 29 | private String tagName; 30 | 31 | /** 32 | * 文章数量 33 | */ 34 | @ApiModelProperty(value = "文章数量") 35 | private Integer articleCount; 36 | 37 | /** 38 | * 创建时间 39 | */ 40 | @ApiModelProperty(value = "创建时间") 41 | private LocalDateTime createTime; 42 | 43 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/TagOptionVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 标签选项VO 9 | * 10 | * @author ican 11 | **/ 12 | @Data 13 | @ApiModel(description = "标签选项VO") 14 | public class TagOptionVO { 15 | 16 | /** 17 | * 标签id 18 | */ 19 | @ApiModelProperty(value = "标签id") 20 | private Integer id; 21 | 22 | /** 23 | * 标签名 24 | */ 25 | @ApiModelProperty(value = "标签名") 26 | private String tagName; 27 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/TagVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 标签VO 9 | * 10 | * @author ican 11 | **/ 12 | @Data 13 | @ApiModel(description = "标签VO") 14 | public class TagVO { 15 | 16 | /** 17 | * 标签id 18 | */ 19 | @ApiModelProperty(value = "标签id") 20 | private Integer id; 21 | 22 | /** 23 | * 标签名 24 | */ 25 | @ApiModelProperty(value = "标签名") 26 | private String tagName; 27 | 28 | /** 29 | * 文章数量 30 | */ 31 | @ApiModelProperty(value = "文章数量") 32 | private Integer articleCount; 33 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/TokenVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * Token 9 | * 10 | * @author ican 11 | */ 12 | @Data 13 | @ApiModel(description = "Token") 14 | public class TokenVO { 15 | 16 | /** 17 | * 访问令牌 18 | */ 19 | @ApiModelProperty(value = "访问令牌") 20 | private String access_token; 21 | } 22 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/UserBackInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 后台登录用户信息 12 | * 13 | * @author ican 14 | * @date 2022/12/05 16:10 15 | **/ 16 | @Data 17 | @Builder 18 | @ApiModel(description = "后台登录用户信息") 19 | public class UserBackInfoVO { 20 | 21 | /** 22 | * 用户id 23 | */ 24 | @ApiModelProperty(value = "用户id") 25 | private Integer id; 26 | 27 | /** 28 | * 头像 29 | */ 30 | @ApiModelProperty(value = "头像") 31 | private String avatar; 32 | 33 | /** 34 | * 角色 35 | */ 36 | @ApiModelProperty(value = "角色") 37 | private List roleList; 38 | 39 | /** 40 | * 权限标识 41 | */ 42 | @ApiModelProperty(value = "权限标识") 43 | private List permissionList; 44 | 45 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/UserRoleVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 用户角色VO 9 | * 10 | * @author ican 11 | **/ 12 | @Data 13 | @ApiModel(description = "用户角色VO") 14 | public class UserRoleVO { 15 | 16 | /** 17 | * 角色id 18 | */ 19 | @ApiModelProperty(value = "角色id") 20 | private String id; 21 | 22 | /** 23 | * 角色名 24 | */ 25 | @ApiModelProperty(value = "角色名") 26 | private String roleName; 27 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/model/vo/UserViewVO.java: -------------------------------------------------------------------------------- 1 | package com.ican.model.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 用户浏览 9 | * 10 | * @author ican 11 | **/ 12 | @Data 13 | @ApiModel(description = "用户浏览") 14 | public class UserViewVO { 15 | 16 | /** 17 | * 日期 18 | */ 19 | @ApiModelProperty(value = "日期") 20 | private String date; 21 | 22 | /** 23 | * pv 24 | */ 25 | @ApiModelProperty(value = "pv") 26 | private Integer pv; 27 | 28 | /** 29 | * uv 30 | */ 31 | @ApiModelProperty(value = "uv") 32 | private Integer uv; 33 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/quartz/execution/QuartzDisallowConcurrentExecution.java: -------------------------------------------------------------------------------- 1 | package com.ican.quartz.execution; 2 | 3 | import com.ican.entity.Task; 4 | import com.ican.quartz.utils.TaskInvokeUtils; 5 | import org.quartz.DisallowConcurrentExecution; 6 | import org.quartz.JobExecutionContext; 7 | 8 | /** 9 | * 定时任务处理(禁止并发执行) 10 | * 11 | * @author ican 12 | */ 13 | @DisallowConcurrentExecution 14 | public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob { 15 | @Override 16 | protected void doExecute(JobExecutionContext context, Task task) throws Exception { 17 | TaskInvokeUtils.invokeMethod(task); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/quartz/execution/QuartzJobExecution.java: -------------------------------------------------------------------------------- 1 | package com.ican.quartz.execution; 2 | 3 | import com.ican.entity.Task; 4 | import com.ican.quartz.utils.TaskInvokeUtils; 5 | import org.quartz.JobExecutionContext; 6 | 7 | /** 8 | * 定时任务处理(允许并发执行) 9 | * 10 | * @author ican 11 | */ 12 | public class QuartzJobExecution extends AbstractQuartzJob { 13 | @Override 14 | protected void doExecute(JobExecutionContext context, Task task) throws Exception { 15 | TaskInvokeUtils.invokeMethod(task); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/quartz/task/TimedTask.java: -------------------------------------------------------------------------------- 1 | package com.ican.quartz.task; 2 | 3 | import com.ican.service.RedisService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.stereotype.Component; 6 | 7 | import static com.ican.constant.RedisConstant.UNIQUE_VISITOR; 8 | 9 | /** 10 | * 执行定时任务 11 | * 12 | * @author ican 13 | */ 14 | @SuppressWarnings(value = "all") 15 | @Component("timedTask") 16 | public class TimedTask { 17 | @Autowired 18 | private RedisService redisService; 19 | 20 | /** 21 | * 清除博客访问记录 22 | */ 23 | public void clear() { 24 | redisService.deleteObject(UNIQUE_VISITOR); 25 | } 26 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/service/BlogInfoService.java: -------------------------------------------------------------------------------- 1 | package com.ican.service; 2 | 3 | import com.ican.model.vo.BlogBackInfoVO; 4 | import com.ican.model.vo.BlogInfoVO; 5 | 6 | /** 7 | * 博客业务接口 8 | * 9 | * @author ican 10 | **/ 11 | public interface BlogInfoService { 12 | /** 13 | * 上传访客信息 14 | */ 15 | void report(); 16 | /** 17 | * 查看博客信息 18 | * 19 | * @return 博客信息 20 | */ 21 | BlogInfoVO getBlogInfo(); 22 | 23 | /** 24 | * 查看博客后台信息 25 | * 26 | * @return 博客后台信息 27 | */ 28 | BlogBackInfoVO getBlogBackInfo(); 29 | 30 | /** 31 | * 查看关于我信息 32 | * 33 | * @return 关于我信息 34 | */ 35 | String getAbout(); 36 | } 37 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/service/ElasticsearchService.java: -------------------------------------------------------------------------------- 1 | package com.ican.service; 2 | 3 | import com.ican.entity.Article; 4 | import com.ican.model.vo.ArticleSearchVO; 5 | 6 | /** 7 | * es文章业务接口 8 | * 9 | * @author ican 10 | */ 11 | public interface ElasticsearchService { 12 | 13 | /** 14 | * 添加文章 15 | * 16 | * @param article 文章 17 | */ 18 | void addArticle(ArticleSearchVO article); 19 | 20 | /** 21 | * 更新文章 22 | * 23 | * @param article 文章 24 | */ 25 | void updateArticle(ArticleSearchVO article); 26 | 27 | /** 28 | * 删除文章 29 | * 30 | * @param id 文章id 31 | */ 32 | void deleteArticle(Integer id); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/service/EmailService.java: -------------------------------------------------------------------------------- 1 | package com.ican.service; 2 | 3 | import com.ican.model.dto.MailDTO; 4 | 5 | /** 6 | * 邮件服务接口 7 | * 8 | * @author ican 9 | **/ 10 | public interface EmailService { 11 | 12 | /** 13 | * 发送简单邮件 14 | * 15 | * @param mailDTO 邮件信息 16 | */ 17 | void sendSimpleMail(MailDTO mailDTO); 18 | 19 | /** 20 | * 发送HTML邮件 21 | * 22 | * @param mailDTO 邮件信息 23 | */ 24 | void sendHtmlMail(MailDTO mailDTO); 25 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/service/ExceptionLogService.java: -------------------------------------------------------------------------------- 1 | package com.ican.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.ican.entity.ExceptionLog; 5 | import com.ican.model.dto.ConditionDTO; 6 | import com.ican.model.vo.PageResult; 7 | 8 | /** 9 | * 异常日志业务接口 10 | * 11 | * @author ican 12 | */ 13 | public interface ExceptionLogService extends IService { 14 | 15 | /** 16 | * 查看异常日志列表 17 | * 18 | * @param condition 条件 19 | * @return 日志列表 20 | */ 21 | PageResult listExceptionLog(ConditionDTO condition); 22 | 23 | /** 24 | * 保存异常日志 25 | * 26 | * @param exceptionLog 异常日志信息 27 | */ 28 | void saveExceptionLog(ExceptionLog exceptionLog); 29 | } 30 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/service/OperationLogService.java: -------------------------------------------------------------------------------- 1 | package com.ican.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.ican.entity.OperationLog; 5 | import com.ican.model.dto.ConditionDTO; 6 | import com.ican.model.vo.OperationLogVO; 7 | import com.ican.model.vo.PageResult; 8 | 9 | /** 10 | * 操作日志业务接口 11 | * 12 | * @author ican 13 | */ 14 | public interface OperationLogService extends IService { 15 | 16 | /** 17 | * 查看操作日志列表 18 | * 19 | * @param condition 条件 20 | * @return 日志列表 21 | */ 22 | PageResult listOperationLogVO(ConditionDTO condition); 23 | 24 | /** 25 | * 保存操作日志 26 | * 27 | * @param operationLog 操作日志信息 28 | */ 29 | void saveOperationLog(OperationLog operationLog); 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/service/SiteConfigService.java: -------------------------------------------------------------------------------- 1 | package com.ican.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.ican.entity.SiteConfig; 5 | 6 | /** 7 | * 网站配置业务接口 8 | * 9 | * @author ican 10 | */ 11 | public interface SiteConfigService extends IService { 12 | 13 | /** 14 | * 获取网站配置 15 | * 16 | * @return 网站配置 17 | */ 18 | SiteConfig getSiteConfig(); 19 | 20 | /** 21 | * 更新网站配置 22 | * 23 | * @param siteConfig 网站配置 24 | */ 25 | void updateSiteConfig(SiteConfig siteConfig); 26 | } 27 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/service/TaskLogService.java: -------------------------------------------------------------------------------- 1 | package com.ican.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.ican.entity.TaskLog; 5 | import com.ican.model.dto.ConditionDTO; 6 | import com.ican.model.vo.PageResult; 7 | import com.ican.model.vo.TaskLogVO; 8 | 9 | /** 10 | * 定时任务日志业务接口 11 | * 12 | * @author ican 13 | */ 14 | public interface TaskLogService extends IService { 15 | 16 | /** 17 | * 查看后台定时任务日志 18 | * 19 | * @param condition 条件 20 | * @return 后台定时任务日志 21 | */ 22 | PageResult listTaskLog(ConditionDTO condition); 23 | 24 | /** 25 | * 清空定时任务日志 26 | */ 27 | void clearTaskLog(); 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/service/VisitLogService.java: -------------------------------------------------------------------------------- 1 | package com.ican.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.ican.entity.VisitLog; 5 | import com.ican.model.dto.ConditionDTO; 6 | import com.ican.model.vo.PageResult; 7 | 8 | /** 9 | * 访问业务接口 10 | * 11 | * @author ican 12 | */ 13 | public interface VisitLogService extends IService { 14 | 15 | /** 16 | * 保存访问日志 17 | * 18 | * @param visitLog 访问日志信息 19 | */ 20 | void saveVisitLog(VisitLog visitLog); 21 | 22 | /** 23 | * 查看访问日志列表 24 | * 25 | * @param condition 条件 26 | * @return 日志列表 27 | */ 28 | PageResult listVisitLog(ConditionDTO condition); 29 | } 30 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/strategy/LikeStrategy.java: -------------------------------------------------------------------------------- 1 | package com.ican.strategy; 2 | 3 | /** 4 | * 点赞策略 5 | * 6 | * @author ican 7 | */ 8 | public interface LikeStrategy { 9 | 10 | /** 11 | * 点赞 12 | * 13 | * @param typeId 类型id 14 | */ 15 | void like(Integer typeId); 16 | } 17 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/strategy/SearchStrategy.java: -------------------------------------------------------------------------------- 1 | package com.ican.strategy; 2 | 3 | import com.ican.model.vo.ArticleSearchVO; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 文章搜索策略 9 | * 10 | * @author ican 11 | */ 12 | public interface SearchStrategy { 13 | 14 | /** 15 | * 搜索文章 16 | * 17 | * @param keyword 关键字 18 | * @return {@link List} 文章列表 19 | */ 20 | List searchArticle(String keyword); 21 | } 22 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/strategy/SocialLoginStrategy.java: -------------------------------------------------------------------------------- 1 | package com.ican.strategy; 2 | 3 | /** 4 | * 第三方登录策略 5 | * 6 | * @author ican 7 | */ 8 | public interface SocialLoginStrategy { 9 | 10 | /** 11 | * 登录 12 | * 13 | * @param data data 14 | * @return {@link String} Token 15 | */ 16 | String login(String data); 17 | } 18 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/strategy/UploadStrategy.java: -------------------------------------------------------------------------------- 1 | package com.ican.strategy; 2 | 3 | import org.springframework.web.multipart.MultipartFile; 4 | 5 | /** 6 | * 上传策略 7 | * 8 | * @author ican 9 | */ 10 | public interface UploadStrategy { 11 | /** 12 | * 上传文件 13 | * 14 | * @param file 文件 15 | * @param path 上传路径 16 | * @return {@link String} 文件地址 17 | */ 18 | String uploadFile(MultipartFile file, String path); 19 | } 20 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/strategy/context/LikeStrategyContext.java: -------------------------------------------------------------------------------- 1 | package com.ican.strategy.context; 2 | 3 | import com.ican.enums.LikeTypeEnum; 4 | import com.ican.strategy.LikeStrategy; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * 点赞策略上下文 12 | * 13 | * @author ican 14 | */ 15 | @Service 16 | public class LikeStrategyContext { 17 | 18 | @Autowired 19 | private Map likeStrategyMap; 20 | 21 | /** 22 | * 点赞 23 | * 24 | * @param likeType 点赞类型 25 | * @param typeId 类型id 26 | */ 27 | public void executeLikeStrategy(LikeTypeEnum likeType, Integer typeId) { 28 | likeStrategyMap.get(likeType.getStrategy()).like(typeId); 29 | } 30 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/strategy/context/SocialLoginStrategyContext.java: -------------------------------------------------------------------------------- 1 | package com.ican.strategy.context; 2 | 3 | import com.ican.enums.LoginTypeEnum; 4 | import com.ican.strategy.SocialLoginStrategy; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * 登录策略上下文 12 | * 13 | * @author ican 14 | */ 15 | @Service 16 | public class SocialLoginStrategyContext { 17 | 18 | @Autowired 19 | private Map socialLoginStrategyMap; 20 | 21 | /** 22 | * 登录 23 | * 24 | * @param data data 25 | * @param loginTypeEnum 登录枚举 26 | * @return {@link String} Token 27 | */ 28 | public String executeLoginStrategy(String data, LoginTypeEnum loginTypeEnum) { 29 | return socialLoginStrategyMap.get(loginTypeEnum.getStrategy()).login(data); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/utils/MimeTypeUtils.java: -------------------------------------------------------------------------------- 1 | package com.ican.utils; 2 | 3 | /** 4 | * 媒体类型工具类 5 | * 6 | * @author ican 7 | */ 8 | public class MimeTypeUtils { 9 | public static final String IMAGE_PNG = "image/png"; 10 | 11 | public static final String IMAGE_JPG = "image/jpg"; 12 | 13 | public static final String IMAGE_JPEG = "image/jpeg"; 14 | 15 | public static final String IMAGE_BMP = "image/bmp"; 16 | 17 | public static final String IMAGE_GIF = "image/gif"; 18 | 19 | public static String getExtension(String prefix) { 20 | switch (prefix) { 21 | case IMAGE_PNG: 22 | return "png"; 23 | case IMAGE_JPG: 24 | return "jpg"; 25 | case IMAGE_JPEG: 26 | return "jpeg"; 27 | case IMAGE_BMP: 28 | return "bmp"; 29 | case IMAGE_GIF: 30 | return "gif"; 31 | default: 32 | return ""; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/utils/SecurityUtils.java: -------------------------------------------------------------------------------- 1 | package com.ican.utils; 2 | 3 | import cn.dev33.satoken.secure.SaSecureUtil; 4 | import org.apache.commons.lang3.StringUtils; 5 | 6 | /** 7 | * 密码加密 8 | * 9 | * @author ican 10 | **/ 11 | public class SecurityUtils { 12 | 13 | /** 14 | * 校验密码 15 | * 16 | * @param target 旧密码 17 | * @param target2 新密码 18 | * @return 是否正确 19 | */ 20 | public static boolean checkPw(String target, String target2) { 21 | String encryptedPassword = sha256Encrypt(target2); 22 | return StringUtils.equals(encryptedPassword, target); 23 | } 24 | 25 | /** 26 | * sha256加密 27 | * 28 | * @param password 密码 29 | * @return 加密后的密码 30 | */ 31 | public static String sha256Encrypt(String password) { 32 | return SaSecureUtil.sha256(password); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/utils/WebUtils.java: -------------------------------------------------------------------------------- 1 | package com.ican.utils; 2 | 3 | import javax.servlet.http.HttpServletResponse; 4 | import java.io.IOException; 5 | import java.io.PrintWriter; 6 | 7 | /** 8 | * 前端返回工具 9 | * 10 | * @author ican 11 | */ 12 | public class WebUtils { 13 | 14 | /** 15 | * 将字符串渲染到客户端 16 | * 17 | * @param response 渲染对象 18 | * @param string 待渲染的字符串 19 | */ 20 | public static void renderString(HttpServletResponse response, String string) { 21 | try { 22 | response.setStatus(200); 23 | response.setContentType("application/json"); 24 | response.setCharacterEncoding("utf-8"); 25 | PrintWriter writer = response.getWriter(); 26 | writer.print(string); 27 | writer.flush(); 28 | writer.close(); 29 | } catch (IOException e) { 30 | e.printStackTrace(); 31 | } 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/validator/groups/ArticleTalk.java: -------------------------------------------------------------------------------- 1 | package com.ican.validator.groups; 2 | 3 | /** 4 | * 文章说说组 5 | * 6 | * @author ican 7 | **/ 8 | public interface ArticleTalk { 9 | } 10 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/validator/groups/Link.java: -------------------------------------------------------------------------------- 1 | package com.ican.validator.groups; 2 | 3 | /** 4 | * 友链组 5 | * 6 | * @author ican 7 | **/ 8 | public interface Link { 9 | } 10 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/validator/groups/ParentIdNotNull.java: -------------------------------------------------------------------------------- 1 | package com.ican.validator.groups; 2 | 3 | /** 4 | * 父评论id不为空 5 | * 6 | * @author ican 7 | **/ 8 | public interface ParentIdNotNull { 9 | } 10 | -------------------------------------------------------------------------------- /blog-springboot/src/main/java/com/ican/validator/groups/ParentIdNull.java: -------------------------------------------------------------------------------- 1 | package com.ican.validator.groups; 2 | 3 | /** 4 | * 父评论id为空 5 | * 6 | * @author ican 7 | **/ 8 | public interface ParentIdNull { 9 | } -------------------------------------------------------------------------------- /blog-springboot/src/main/resources/ipdb/ip2region.xdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-springboot/src/main/resources/ipdb/ip2region.xdb -------------------------------------------------------------------------------- /blog-springboot/src/main/resources/mapper/ArticleTagMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | insert into t_article_tag(article_id,tag_id) values 8 | 9 | (#{articleId},#{tagId}) 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /blog-springboot/src/main/resources/mapper/FriendMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /blog-springboot/src/main/resources/mapper/PhotoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 20 | 21 | -------------------------------------------------------------------------------- /blog-springboot/src/main/resources/mapper/SiteConfigMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /blog-springboot/src/main/resources/mapper/UserRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | insert into t_user_role(user_id,role_id) values 6 | 7 | (#{userId},#{roleId}) 8 | 9 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | admin 13 | dist-ssr 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/auto-imports.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by 'unplugin-auto-import' 2 | export {} 3 | declare global { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 博客后台管理系统 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-vue/shoka-admin/public/favicon.ico -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | 22 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/album/types.ts: -------------------------------------------------------------------------------- 1 | import { PageQuery } from "@/model"; 2 | 3 | /** 4 | * 相册 5 | */ 6 | export interface Album { 7 | /** 8 | * 相册id 9 | */ 10 | id: number; 11 | /** 12 | * 相册名 13 | */ 14 | albumName: string; 15 | /** 16 | * 相册封面 17 | */ 18 | albumCover: string; 19 | /** 20 | * 相册描述 21 | */ 22 | albumDesc: string; 23 | /** 24 | * 照片数量 25 | */ 26 | photoCount: number; 27 | /** 28 | * 状态 (1公开 2私密) 29 | */ 30 | status: number; 31 | } 32 | 33 | /** 34 | * 相册查询参数 35 | */ 36 | export interface AlbumQuery extends PageQuery { 37 | /** 38 | * 关键词 39 | */ 40 | keyword?: string; 41 | } 42 | 43 | /** 44 | * 相册 45 | */ 46 | export interface AlbumForm { 47 | /** 48 | * 相册id 49 | */ 50 | id?: number; 51 | /** 52 | * 相册名 53 | */ 54 | albumName: string; 55 | /** 56 | * 相册封面 57 | */ 58 | albumCover: string; 59 | /** 60 | * 相册描述 61 | */ 62 | albumDesc: string; 63 | /** 64 | * 状态 (1公开 2私密) 65 | */ 66 | status: number; 67 | } 68 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/blog/index.ts: -------------------------------------------------------------------------------- 1 | import { Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { BlogInfo } from "./types"; 5 | 6 | /** 7 | * 获取博客后台信息 8 | * @returns 博客后台信息 9 | */ 10 | export function getBlogInfo(): AxiosPromise> { 11 | return request({ 12 | url: "/admin", 13 | method: "get", 14 | }); 15 | } 16 | 17 | /** 18 | * 上传访客信息 19 | */ 20 | export function report(): AxiosPromise> { 21 | return request({ 22 | url: "/report", 23 | method: "post", 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/category/types.ts: -------------------------------------------------------------------------------- 1 | import { PageQuery } from "@/model"; 2 | 3 | /** 4 | * 分类 5 | */ 6 | export interface Category { 7 | /** 8 | * 分类id 9 | */ 10 | id: number; 11 | /** 12 | * 分类名 13 | */ 14 | categoryName: string; 15 | /** 16 | * 文章数量 17 | */ 18 | articleCount: number; 19 | /** 20 | * 创建时间 21 | */ 22 | createTime: string; 23 | } 24 | 25 | /** 26 | * 分类查询参数 27 | */ 28 | export interface CategoryQuery extends PageQuery { 29 | /** 30 | * 关键词 31 | */ 32 | keyword?: string; 33 | } 34 | 35 | /** 36 | * 分类表单 37 | */ 38 | export interface CategoryForm { 39 | /** 40 | * 分类id 41 | */ 42 | id?: number; 43 | /** 44 | * 分类名 45 | */ 46 | categoryName: string; 47 | } 48 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/comment/index.ts: -------------------------------------------------------------------------------- 1 | import { CheckDTO, PageResult, Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { Comment, CommentQuery } from "./types"; 5 | 6 | /** 7 | * 查看评论列表 8 | * @param params 查询条件 9 | * @returns 评论列表 10 | */ 11 | export function getCommentList(params: CommentQuery): AxiosPromise>> { 12 | return request({ 13 | url: "/admin/comment/list", 14 | method: "get", 15 | params, 16 | }); 17 | } 18 | 19 | /** 20 | * 删除评论 21 | * @param data 评论id集合 22 | */ 23 | export function deleteComment(data: number[]): AxiosPromise> { 24 | return request({ 25 | url: "/admin/comment/delete", 26 | method: "delete", 27 | data, 28 | }); 29 | } 30 | 31 | /** 32 | * 审核评论 33 | * @param data 审核信息 34 | */ 35 | export function updateCommentCheck(data: CheckDTO): AxiosPromise> { 36 | return request({ 37 | url: "/admin/comment/pass", 38 | method: "put", 39 | data, 40 | }); 41 | } 42 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/comment/types.ts: -------------------------------------------------------------------------------- 1 | import { PageQuery } from "@/model"; 2 | 3 | /** 4 | * 评论 5 | */ 6 | export interface Comment { 7 | /** 8 | * 评论id 9 | */ 10 | id: number; 11 | /** 12 | * 头像 13 | */ 14 | avatar: string; 15 | /** 16 | * 评论用户昵称 17 | */ 18 | fromNickname: string; 19 | /** 20 | * 被回复用户昵称 21 | */ 22 | toNickname: string; 23 | /** 24 | * 文章标题 25 | */ 26 | articleTitle: string; 27 | /** 28 | * 评论内容 29 | */ 30 | commentContent: string; 31 | /** 32 | * 评论类型 33 | */ 34 | commentType: number; 35 | /** 36 | * 是否通过 (0否 1是) 37 | */ 38 | isCheck: number; 39 | /** 40 | * 发表时间 41 | */ 42 | createTime: string; 43 | } 44 | 45 | /** 46 | * 评论查询参数 47 | */ 48 | export interface CommentQuery extends PageQuery { 49 | /** 50 | * 关键词 51 | */ 52 | keyword?: string; 53 | /** 54 | * 评论类型 55 | */ 56 | commentType: number; 57 | /** 58 | * 是否通过 (0否 1是) 59 | */ 60 | isCheck: number; 61 | } 62 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/login/index.ts: -------------------------------------------------------------------------------- 1 | import { Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { LoginForm } from "./types"; 5 | 6 | /** 7 | * 用户登录 8 | * @param data 登录信息 9 | * @returns Token 10 | */ 11 | export function login(data: LoginForm): AxiosPromise> { 12 | return request({ 13 | url: "/login", 14 | method: "post", 15 | data, 16 | }); 17 | } 18 | 19 | /** 20 | * 用户退出 21 | */ 22 | export function logout(): AxiosPromise> { 23 | return request({ 24 | url: "/logout", 25 | method: "get", 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/login/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 登录信息 3 | */ 4 | export interface LoginForm { 5 | /** 6 | * 用户名 7 | */ 8 | username: string; 9 | /** 10 | * 密码 11 | */ 12 | password: string; 13 | } 14 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/message/index.ts: -------------------------------------------------------------------------------- 1 | import { CheckDTO, PageResult, Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { Message, MessageQuery } from "./types"; 5 | 6 | /** 7 | * 查看留言列表 8 | * @param params 查询条件 9 | * @returns 留言列表 10 | */ 11 | export function getMessageList(params: MessageQuery): AxiosPromise>> { 12 | return request({ 13 | url: "/admin/message/list", 14 | method: "get", 15 | params, 16 | }); 17 | } 18 | 19 | /** 20 | * 删除留言 21 | * @param data 留言id集合 22 | */ 23 | export function deleteMessage(data: number[]): AxiosPromise> { 24 | return request({ 25 | url: "/admin/message/delete", 26 | method: "delete", 27 | data, 28 | }); 29 | } 30 | 31 | /** 32 | * 审核留言 33 | * @param data 审核信息 34 | */ 35 | export function updateMessageCheck(data: CheckDTO): AxiosPromise> { 36 | return request({ 37 | url: "/admin/message/pass", 38 | method: "put", 39 | data, 40 | }); 41 | } 42 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/message/types.ts: -------------------------------------------------------------------------------- 1 | import { PageQuery } from "@/model"; 2 | 3 | export interface Message { 4 | /** 5 | * 留言id 6 | */ 7 | id: number; 8 | /** 9 | * 昵称 10 | */ 11 | nickname: string; 12 | /** 13 | * 头像 14 | */ 15 | avatar: string; 16 | /** 17 | * 留言内容 18 | */ 19 | messageContent: string; 20 | /** 21 | * 用户ip 22 | */ 23 | ipAddress: string; 24 | /** 25 | * 用户地址 26 | */ 27 | ipSource: string; 28 | /** 29 | * 是否通过 (0否 1是) 30 | */ 31 | isCheck: number; 32 | /** 33 | * 留言时间 34 | */ 35 | createTime: string; 36 | } 37 | 38 | /** 39 | * 留言查询参数 40 | */ 41 | export interface MessageQuery extends PageQuery { 42 | /** 43 | * 关键词 44 | */ 45 | keyword?: string; 46 | /** 47 | * 是否通过 (0否 1是) 48 | */ 49 | isCheck?: number; 50 | } 51 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/site/index.ts: -------------------------------------------------------------------------------- 1 | import { Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { SiteConfig } from "./types"; 5 | 6 | /** 7 | * 查看网站配置 8 | * @returns 网站配置 9 | */ 10 | export function getSiteConfig(): AxiosPromise> { 11 | return request({ 12 | url: "/admin/site/list", 13 | method: "get", 14 | }); 15 | } 16 | 17 | /** 18 | * 更新网站配置 19 | * @param data 网站配置 20 | */ 21 | export function updateSiteConfig(data: SiteConfig): AxiosPromise> { 22 | return request({ 23 | url: "/admin/site/update", 24 | method: "put", 25 | data, 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/api/tag/types.ts: -------------------------------------------------------------------------------- 1 | import { PageQuery } from "@/model"; 2 | 3 | /** 4 | * 标签 5 | */ 6 | export interface Tag { 7 | /** 8 | * 标签id 9 | */ 10 | id: number; 11 | /** 12 | * 标签名 13 | */ 14 | tagName: string; 15 | /** 16 | * 文章数量 17 | */ 18 | articleCount: number; 19 | /** 20 | * 创建时间 21 | */ 22 | createTime: string; 23 | } 24 | 25 | /** 26 | * 标签查询参数 27 | */ 28 | export interface TagQuery extends PageQuery { 29 | /** 30 | * 关键词 31 | */ 32 | keyword?: string; 33 | } 34 | 35 | /** 36 | * 标签表单 37 | */ 38 | export interface TagForm { 39 | /** 40 | * 标签id 41 | */ 42 | id?: number; 43 | /** 44 | * 标签名 45 | */ 46 | tagName: string; 47 | } 48 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/404_images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-vue/shoka-admin/src/assets/404_images/404.png -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/404_images/404_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-vue/shoka-admin/src/assets/404_images/404_cloud.png -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/build.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/chart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/clipboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/code.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/comment.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/documentation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/download.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/drag.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/druid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/education.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/email.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/example.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/excel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/eye.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/friend.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/fullscreen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/guide.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/home.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/input.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/list.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/lock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/money.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/monitor.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/nested.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/peoples.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/row.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/server.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/size.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/slider.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/star.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/switch.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/talk.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/textarea.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/theme.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/time.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/top.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/tree-table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/icons/view.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-vue/shoka-admin/src/assets/logo.png -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/styles/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix { 2 | &:after { 3 | content: ""; 4 | display: table; 5 | clear: both; 6 | } 7 | } 8 | 9 | @mixin relative { 10 | position: relative; 11 | width: 100%; 12 | height: 100%; 13 | } 14 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/styles/transition.scss: -------------------------------------------------------------------------------- 1 | // global transition css 2 | 3 | /* fade */ 4 | .fade-enter-active, 5 | .fade-leave-active { 6 | transition: opacity 0.28s; 7 | } 8 | 9 | .fade-enter, 10 | .fade-leave-active { 11 | opacity: 0; 12 | } 13 | 14 | /* fade-transform */ 15 | .fade-transform-leave-active, 16 | .fade-transform-enter-active { 17 | transition: all 0.5s; 18 | } 19 | 20 | .fade-transform-enter { 21 | opacity: 0; 22 | transform: translateX(-30px); 23 | } 24 | 25 | .fade-transform-leave-to { 26 | opacity: 0; 27 | transform: translateX(30px); 28 | } 29 | 30 | /* breadcrumb transition */ 31 | .breadcrumb-enter-active, 32 | .breadcrumb-leave-active { 33 | transition: all 0.5s ease; 34 | } 35 | 36 | .breadcrumb-enter-from, 37 | .breadcrumb-leave-active { 38 | opacity: 0; 39 | transform: translateX(20px); 40 | } 41 | 42 | .breadcrumb-leave-active { 43 | position: absolute; 44 | z-index: -1; 45 | } -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/assets/styles/variables.module.scss: -------------------------------------------------------------------------------- 1 | // base color 2 | $blue:#324157; 3 | $light-blue:#3A71A8; 4 | $red:#C03639; 5 | $pink: #E65D6E; 6 | $green: #30B08F; 7 | $tiffany: #4AB7BD; 8 | $yellow:#FEC171; 9 | $panGreen: #30B08F; 10 | 11 | // sidebar 12 | $menuText:#bfcbd9; 13 | $menuActiveText:#409EFF; 14 | $subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951 15 | 16 | $menuBg:#304156; 17 | $menuHover:#263445; 18 | 19 | $subMenuBg:#1f2d3d; 20 | $subMenuHover:#001528; 21 | 22 | $sideBarWidth: 200px; 23 | 24 | // the :export directive is the magic sauce for webpack 25 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 26 | :export { 27 | menuText: $menuText; 28 | menuActiveText: $menuActiveText; 29 | subMenuActiveText: $subMenuActiveText; 30 | menuBg: $menuBg; 31 | menuHover: $menuHover; 32 | subMenuBg: $subMenuBg; 33 | subMenuHover: $subMenuHover; 34 | sideBarWidth: $sideBarWidth; 35 | } 36 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/components/EmojiExtension/data.ts: -------------------------------------------------------------------------------- 1 | export const emojis = [ 2 | "😀", 3 | "😃", 4 | "😄", 5 | "😁", 6 | "😆", 7 | "😅", 8 | "😂", 9 | "🤣", 10 | "🥲", 11 | "🤔", 12 | "😊", 13 | "😇", 14 | "🙂", 15 | "🙃", 16 | "😉", 17 | "😌", 18 | "😍", 19 | "🥰", 20 | "😘", 21 | "😗", 22 | "😙", 23 | "😚", 24 | "😋", 25 | "😛", 26 | "😝", 27 | "😜", 28 | "🤪", 29 | "🤨", 30 | "🧐", 31 | "🤓", 32 | "😎", 33 | "🥸", 34 | "🤩", 35 | "🥳", 36 | "😏", 37 | "😒", 38 | "😞", 39 | "😔", 40 | "😟", 41 | "😕", 42 | "🙁", 43 | "👻", 44 | "😣", 45 | "😖", 46 | "😫", 47 | "😩", 48 | "🥺", 49 | "😢", 50 | "😭", 51 | "😤", 52 | "😠", 53 | "😡", 54 | "🤬", 55 | "🤯", 56 | "😳", 57 | "💖", 58 | "🍀", 59 | "🚀", 60 | "🎉", 61 | "🔧", 62 | ]; 63 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/components/EmojiExtension/staticConfig.ts: -------------------------------------------------------------------------------- 1 | export const toolbars = [ 2 | 'bold', 3 | 'underline', 4 | 'italic', 5 | 'strikeThrough', 6 | '-', 7 | 'title', 8 | 'sub', 9 | 'sup', 10 | 'quote', 11 | 'unorderedList', 12 | 'orderedList', 13 | 'task', 14 | '-', 15 | 'codeRow', 16 | 'code', 17 | 'link', 18 | 'image', 19 | 'table', 20 | 'mermaid', 21 | 'katex', 22 | 0, 23 | '-', 24 | 'revoke', 25 | 'next', 26 | 'save', 27 | '=', 28 | 'prettier', 29 | 'pageFullscreen', 30 | 'fullscreen', 31 | 'preview', 32 | 'htmlPreview', 33 | 'catalog', 34 | ]; 35 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/components/ParentView/index.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/components/PreviewCode/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 32 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/components/Screenfull/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 34 | 35 | 42 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/components/TagView/ScrollPane.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 10 | 26 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/directive/index.ts: -------------------------------------------------------------------------------- 1 | export { hasPerm, hasRole } from "./permission"; 2 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/layouts/components/SideBar/Link.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 25 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/model/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 分页返回接口 3 | */ 4 | export interface PageResult { 5 | /** 6 | * 分页结果 7 | */ 8 | recordList: T; 9 | /** 10 | * 总数 11 | */ 12 | count: number; 13 | } 14 | /** 15 | * 结果返回接口 16 | */ 17 | export interface Result { 18 | /** 19 | * 返回状态 20 | */ 21 | flag: boolean; 22 | /** 23 | * 状态码 24 | */ 25 | code: number; 26 | /** 27 | * 返回信息 28 | */ 29 | msg: string; 30 | /** 31 | * 返回数据 32 | */ 33 | data: T; 34 | } 35 | 36 | /** 37 | * 分页参数 38 | */ 39 | export interface PageQuery { 40 | /** 41 | * 当前页 42 | */ 43 | current: number; 44 | /** 45 | * 每页大小 46 | */ 47 | size: number; 48 | } 49 | 50 | /** 51 | * 上传图片 52 | */ 53 | export interface Picture { 54 | /** 55 | * 链接 56 | */ 57 | url: string; 58 | } 59 | 60 | /** 61 | * 审核DTO 62 | */ 63 | export interface CheckDTO { 64 | /** 65 | * id集合 66 | */ 67 | idList: number[]; 68 | /** 69 | * 是否通过 (0否 1是) 70 | */ 71 | isCheck: number; 72 | } -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/settings.ts: -------------------------------------------------------------------------------- 1 | interface DefaultSettings { 2 | /** 3 | * 是否显示 tagView 4 | */ 5 | tagView: boolean; 6 | /** 7 | * 是否固定头部 8 | */ 9 | fixedHeader: boolean; 10 | /** 11 | * 是否显示Logo 12 | */ 13 | sidebarLogo: boolean; 14 | } 15 | 16 | const defaultSettings: DefaultSettings = { 17 | tagView: true, 18 | fixedHeader: true, 19 | sidebarLogo: true, 20 | }; 21 | 22 | export default defaultSettings; 23 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import useAppStore from "./modules/app"; 2 | import useTagStore from "./modules/tag"; 3 | import useSettingStore from "./modules/setting"; 4 | import usePermissionStore from "./modules/permission"; 5 | import useUserStore from "./modules/user"; 6 | 7 | const useStore = () => ({ 8 | tag: useTagStore(), 9 | app: useAppStore(), 10 | setting: useSettingStore(), 11 | user: useUserStore(), 12 | permission: usePermissionStore(), 13 | }); 14 | 15 | export default useStore; 16 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/store/modules/app.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | import { AppState } from "../interface"; 3 | 4 | const useAppStore = defineStore("useAppStore", { 5 | state: (): AppState => ({ 6 | isCollapse: false, 7 | device: "desktop", 8 | size: "default", 9 | }), 10 | actions: { 11 | toggle() { 12 | this.isCollapse = !this.isCollapse; 13 | }, 14 | changeCollapse(isCollapse: boolean) { 15 | this.isCollapse = isCollapse; 16 | }, 17 | toggleDevice(device: string) { 18 | this.device = device; 19 | }, 20 | setSize(size: string) { 21 | this.size = size; 22 | }, 23 | }, 24 | getters: {}, 25 | persist: { 26 | storage: localStorage, 27 | }, 28 | }); 29 | 30 | export default useAppStore; 31 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/store/modules/setting.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | import defaultSettings from "../../settings"; 3 | import { SettingState } from "../interface"; 4 | const { tagView, fixedHeader, sidebarLogo } = defaultSettings; 5 | 6 | const useSettingStore = defineStore("useSettingStore", { 7 | state: (): SettingState => ({ 8 | tagView: tagView, 9 | fixedHeader: fixedHeader, 10 | sidebarLogo: sidebarLogo, 11 | }), 12 | actions: { 13 | async changeSetting(data: { key: string; value: any }) { 14 | const { key, value } = data; 15 | switch (key) { 16 | case "tagView": 17 | this.tagView = value; 18 | break; 19 | case "fixedHeader": 20 | this.fixedHeader = value; 21 | break; 22 | case "sidebarLogo": 23 | this.sidebarLogo = value; 24 | break; 25 | default: 26 | break; 27 | } 28 | }, 29 | }, 30 | getters: {}, 31 | persist: { 32 | storage: localStorage, 33 | }, 34 | }); 35 | 36 | export default useSettingStore; 37 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/utils/date.ts: -------------------------------------------------------------------------------- 1 | import dayjs from "dayjs"; 2 | 3 | export function formatDate(date: string | Date | null, format = "YYYY-MM-DD"): string { 4 | if (date == null) { 5 | return ""; 6 | } 7 | return dayjs(date).format(format); 8 | } 9 | 10 | export function formatDateTime(date: string | Date, format = "YYYY-MM-DD HH:mm:ss"): string { 11 | return formatDate(date, format); 12 | } 13 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/utils/modal.ts: -------------------------------------------------------------------------------- 1 | import { ElMessageBox, ElNotification } from "element-plus"; 2 | 3 | export function notifySuccess(message: string) { 4 | ElNotification({ 5 | title: "成功", 6 | message, 7 | type: "success", 8 | }); 9 | } 10 | 11 | export function messageConfirm(content: string) { 12 | return ElMessageBox.confirm(content, "系统提示", { 13 | confirmButtonText: "确定", 14 | cancelButtonText: "取消", 15 | center: true, 16 | type: "warning", 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/utils/token.ts: -------------------------------------------------------------------------------- 1 | import Cookies from "js-cookie"; 2 | 3 | const TokenKey: string = "Token"; 4 | 5 | const domain: string = ".ttkwsd.top"; 6 | 7 | // token前缀 8 | export let token_prefix = "Bearer "; 9 | 10 | export function getToken() { 11 | return Cookies.get(TokenKey); 12 | } 13 | 14 | // 拉取下来记得删除domain 15 | export function setToken(token: string) { 16 | return Cookies.set(TokenKey, token, { domain: domain }); 17 | } 18 | 19 | export function removeToken() { 20 | return Cookies.remove(TokenKey, { domain: domain }); 21 | } 22 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/views/redirect/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 16 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/views/web/page/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module "*.vue" { 4 | import type { DefineComponent } from "vue"; 5 | const component: DefineComponent<{}, {}, any>; 6 | export default component; 7 | } 8 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "moduleResolution": "Node", 7 | "strict": true, 8 | "jsx": "preserve", 9 | "resolveJsonModule": true, 10 | "isolatedModules": true, 11 | "esModuleInterop": true, 12 | "lib": ["ESNext", "DOM"], 13 | "skipLibCheck": true, 14 | "allowSyntheticDefaultImports": true, 15 | "noEmit": true, 16 | "baseUrl": ".", 17 | "allowJs": true, 18 | "paths": { 19 | "@/*": ["src/*"] 20 | }, 21 | }, 22 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/components/CountTo/requestAnimationFrame.js"], 23 | "references": [{ "path": "./tsconfig.node.json" }] 24 | } 25 | -------------------------------------------------------------------------------- /blog-vue/shoka-admin/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | blog 13 | dist-ssr 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/public/favicon.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-vue/shoka-blog/public/favicon.svg -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/album/index.ts: -------------------------------------------------------------------------------- 1 | import { Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { Album, PhotoInfo } from "./types"; 5 | 6 | /** 7 | * 查看相册列表 8 | * @returns 相册列表 9 | */ 10 | export function getAlbumList(): AxiosPromise> { 11 | return request({ 12 | url: "/album/list", 13 | method: "get", 14 | }); 15 | } 16 | 17 | /** 18 | * 查看照片列表 19 | * @param albumId 相册id 20 | * @returns 照片列表 21 | */ 22 | export function getPhotoList(albumId: number): AxiosPromise> { 23 | return request({ 24 | url: "/photo/list", 25 | method: "get", 26 | params: { 27 | albumId, 28 | }, 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/album/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 相册 3 | */ 4 | export interface Album { 5 | /** 6 | * 相册id 7 | */ 8 | id: number; 9 | /** 10 | * 相册名 11 | */ 12 | albumName: string; 13 | /** 14 | * 相册封面 15 | */ 16 | albumCover: string; 17 | /** 18 | * 相册描述 19 | */ 20 | albumDesc: string; 21 | } 22 | 23 | /** 24 | * 照片信息 25 | */ 26 | export interface PhotoInfo { 27 | /** 28 | * 相册名 29 | */ 30 | albumName: string; 31 | /** 32 | * 照片列表 33 | */ 34 | photoVOList: Photo[]; 35 | } 36 | 37 | /** 38 | * 照片 39 | */ 40 | export interface Photo { 41 | /** 42 | * 照片id 43 | */ 44 | id: number; 45 | /** 46 | * 照片链接 47 | */ 48 | photoUrl: string; 49 | } 50 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/archives/index.ts: -------------------------------------------------------------------------------- 1 | import { PageQuery, PageResult, Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { Archives } from "./types"; 5 | 6 | /** 7 | * 查看文章归档 8 | * @param params 查询条件 9 | * @returns 文章归档 10 | */ 11 | export function getArchivesList(params: PageQuery): AxiosPromise>> { 12 | return request({ 13 | url: "/archives/list", 14 | method: "get", 15 | params, 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/archives/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 归档 3 | */ 4 | export interface Archives { 5 | /** 6 | * 文章id 7 | */ 8 | id: number; 9 | /** 10 | * 文章标题 11 | */ 12 | articleTitle: string; 13 | /** 14 | * 文章缩略图 15 | */ 16 | articleCover: string; 17 | /** 18 | * 发布时间 19 | */ 20 | createTime: string; 21 | } 22 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/blogInfo/index.ts: -------------------------------------------------------------------------------- 1 | import { Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { BlogInfo } from "./types"; 5 | 6 | /** 7 | * 获取博客信息 8 | * @returns 博客信息 9 | */ 10 | export function getBlogInfo(): AxiosPromise> { 11 | return request({ 12 | url: "/", 13 | method: "get", 14 | }); 15 | } 16 | 17 | /** 18 | * 上传访客信息 19 | */ 20 | export function report(): AxiosPromise> { 21 | return request({ 22 | url: "/report", 23 | method: "post", 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/category/index.ts: -------------------------------------------------------------------------------- 1 | import { Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { ArticleConditionList, ArticleQuery } from "../article/types"; 5 | import { Category } from "./types"; 6 | 7 | /** 8 | * 查看文章分类 9 | * @returns 文章分类 10 | */ 11 | export function getCategoryList(): AxiosPromise> { 12 | return request({ 13 | url: "/category/list", 14 | method: "get", 15 | }); 16 | } 17 | 18 | /** 19 | * 查看分类文章 20 | * @returns 文章分类 21 | */ 22 | export function getCategoryArticleList( 23 | params: ArticleQuery 24 | ): AxiosPromise> { 25 | return request({ 26 | url: "/category/article", 27 | method: "get", 28 | params, 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/category/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 分类 3 | */ 4 | export interface Category { 5 | /** 6 | * 分类id 7 | */ 8 | id: number; 9 | /** 10 | * 分类名 11 | */ 12 | categoryName: string; 13 | /** 14 | * 文章数量 15 | */ 16 | articleCount: number; 17 | } 18 | 19 | /** 20 | * 分类VO 21 | */ 22 | export interface CategoryVO { 23 | /** 24 | * 分类id 25 | */ 26 | id: number; 27 | /** 28 | * 分类名 29 | */ 30 | categoryName: string; 31 | } 32 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/friend/index.ts: -------------------------------------------------------------------------------- 1 | import { Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { Friend } from "./types"; 5 | 6 | /** 7 | * 查看友链列表 8 | * @returns 文章分类 9 | */ 10 | export function getFriendList(): AxiosPromise> { 11 | return request({ 12 | url: "/friend/list", 13 | method: "get", 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/friend/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 友链 3 | */ 4 | export interface Friend { 5 | /** 6 | * 友链id 7 | */ 8 | id:number; 9 | /** 10 | * 友链颜色 11 | */ 12 | color: string; 13 | /** 14 | * 友链名称 15 | */ 16 | name: string; 17 | /** 18 | *友链头像 19 | */ 20 | avatar: string; 21 | /** 22 | * 友链地址 23 | */ 24 | url: string; 25 | /** 26 | * 友链介绍 27 | */ 28 | introduction: string; 29 | } 30 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/message/index.ts: -------------------------------------------------------------------------------- 1 | import { Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { Message, MessageForm } from "./types"; 5 | 6 | /** 7 | * 查看留言列表 8 | * @returns 文章分类 9 | */ 10 | export function getMessageList(): AxiosPromise> { 11 | return request({ 12 | url: "/message/list", 13 | method: "get", 14 | }); 15 | } 16 | 17 | /** 18 | * 添加留言 19 | * @param data 留言 20 | */ 21 | export function addMessage(data: MessageForm): AxiosPromise> { 22 | return request({ 23 | url: "/message/add", 24 | method: "post", 25 | data, 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/message/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 留言 3 | */ 4 | export interface Message { 5 | /** 6 | * 留言id 7 | */ 8 | id: number; 9 | /** 10 | * 昵称 11 | */ 12 | nickname: string; 13 | /** 14 | * 头像 15 | */ 16 | avatar: string; 17 | /** 18 | * 留言内容 19 | */ 20 | messageContent: string; 21 | } 22 | 23 | /** 24 | * 留言表单 25 | */ 26 | export interface MessageForm { 27 | /** 28 | * 昵称 29 | */ 30 | nickname: string; 31 | /** 32 | * 头像 33 | */ 34 | avatar: string; 35 | /** 36 | * 留言内容 37 | */ 38 | messageContent: string; 39 | } 40 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/tag/index.ts: -------------------------------------------------------------------------------- 1 | import { Result } from "@/model"; 2 | import request from "@/utils/request"; 3 | import { AxiosPromise } from "axios"; 4 | import { ArticleConditionList, ArticleQuery } from "../article/types"; 5 | import { Tag } from "./types"; 6 | 7 | /** 8 | * 查看文章标签 9 | * @returns 文章标签 10 | */ 11 | export function getTagList(): AxiosPromise> { 12 | return request({ 13 | url: "/tag/list", 14 | method: "get", 15 | }); 16 | } 17 | 18 | /** 19 | * 查看标签文章 20 | * @returns 文章分类 21 | */ 22 | export function getTagArticleList( 23 | params: ArticleQuery 24 | ): AxiosPromise> { 25 | return request({ 26 | url: "/tag/article", 27 | method: "get", 28 | params, 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/tag/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 标签 3 | */ 4 | export interface Tag { 5 | /** 6 | * 标签id 7 | */ 8 | id: number; 9 | /** 10 | * 标签名 11 | */ 12 | tagName: string; 13 | /** 14 | * 文章数量 15 | */ 16 | articleCount: number; 17 | } 18 | 19 | /** 20 | * 标签VO 21 | */ 22 | export interface TagVO { 23 | /** 24 | * 标签id 25 | */ 26 | id: number; 27 | /** 28 | * 标签名 29 | */ 30 | tagName: string; 31 | } 32 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/talk/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 说说 3 | */ 4 | export interface Talk { 5 | /** 6 | * 说说id 7 | */ 8 | id: number; 9 | /** 10 | * 昵称 11 | */ 12 | nickname: string; 13 | /** 14 | * 头像 15 | */ 16 | avatar: string; 17 | /** 18 | * 说说内容 19 | */ 20 | talkContent: string; 21 | /** 22 | * 图片列表 23 | */ 24 | imgList: string[]; 25 | /** 26 | * 是否置顶 (0否 1是) 27 | */ 28 | isTop: number; 29 | /** 30 | * 点赞量 31 | */ 32 | likeCount: number; 33 | /** 34 | * 评论量 35 | */ 36 | commentCount: number; 37 | /** 38 | * 创建时间 39 | */ 40 | createTime: string; 41 | } 42 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/api/user/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 邮箱 3 | */ 4 | export interface EmailForm { 5 | /** 6 | * 邮箱号 7 | */ 8 | email: string; 9 | /** 10 | * 验证码 11 | */ 12 | code: string; 13 | } 14 | 15 | /** 16 | * 用户信息 17 | */ 18 | export interface UserInfo { 19 | /** 20 | * 昵称 21 | */ 22 | nickname: string; 23 | /** 24 | * 个人网站 25 | */ 26 | webSite: string; 27 | /** 28 | * 个人简介 29 | */ 30 | intro: string; 31 | } 32 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/fonts/FREDERICKATHEGREAT-REGULAR-2.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-vue/shoka-blog/src/assets/fonts/FREDERICKATHEGREAT-REGULAR-2.TTF -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/fonts/font.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Fredericka the Great"; 3 | src: url("FREDERICKATHEGREAT-REGULAR-2.TTF") format('truetype'); 4 | font-weight: normal; 5 | font-style: normal; 6 | } -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/album.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/angle-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/angle-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/arrow-down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/arrow-up.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/clock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/eye.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/friend.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/gitee.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/heng.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/history.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/home.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/link.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-vue/shoka-blog/src/assets/icons/link.cur -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/normal.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-vue/shoka-blog/src/assets/icons/normal.cur -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/plane.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/qizhi.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/sun.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/talk.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/top.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/trumpet.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/up.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/update.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/web.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/icons/zhaoxiang.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/images/404.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-vue/shoka-blog/src/assets/images/404.gif -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duqicauc/JavaaduBlog/b037783cd0bd3ed172102e792f1db6a396cae81e/blog-vue/shoka-blog/src/assets/images/loading.gif -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/js/config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | // gitee的client-id 3 | GITEE_APP_ID: "***************************", 4 | // gitee回调地址 5 | GITEE_REDIRECT_URI: "***************************", 6 | // github的client-id 7 | GITHUB_APP_ID: "***************************", 8 | // github回调地址 9 | GITHUB_REDIRECT_URL: "***************************", 10 | }; 11 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/assets/styles/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin flex { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | } 6 | 7 | @mixin absolute { 8 | position: absolute; 9 | top: 0; 10 | left: 0; 11 | } -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/components/Layout/SideBar/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 12 | 13 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/components/MusicPlayer/index.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/components/Pagination/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 31 | 32 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/components/Provider/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 31 | 34 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 29 | 30 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/directive/animate/index.ts: -------------------------------------------------------------------------------- 1 | import { useIntersectionObserver } from "@vueuse/core"; 2 | import { Directive, DirectiveBinding } from "vue"; 3 | 4 | /** 5 | * v-animate 元素显示动画 6 | */ 7 | export const animate: Directive = { 8 | mounted(el: HTMLElement, binding: DirectiveBinding) { 9 | const { value } = binding; 10 | const { stop } = useIntersectionObserver(el, ([{ isIntersecting }]) => { 11 | // 元素进入可视区 12 | if (isIntersecting) { 13 | stop(); 14 | const { top } = el.getBoundingClientRect(); 15 | const h = document.documentElement.clientHeight || document.body.clientHeight; 16 | if (top < h) { 17 | el.style.visibility = "visible"; 18 | el.style.animationName = value; 19 | } 20 | } 21 | }); 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/directive/index.ts: -------------------------------------------------------------------------------- 1 | export { animate } from "./animate"; 2 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/model/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 分页返回接口 3 | */ 4 | export interface PageResult { 5 | /** 6 | * 分页结果 7 | */ 8 | recordList: T; 9 | /** 10 | * 总数 11 | */ 12 | count: number; 13 | } 14 | /** 15 | * 结果返回接口 16 | */ 17 | export interface Result { 18 | /** 19 | * 返回状态 20 | */ 21 | flag: boolean; 22 | /** 23 | * 状态码 24 | */ 25 | code: number; 26 | /** 27 | * 返回信息 28 | */ 29 | msg: string; 30 | /** 31 | * 返回数据 32 | */ 33 | data: T; 34 | } 35 | 36 | /** 37 | * 分页参数 38 | */ 39 | export interface PageQuery { 40 | /** 41 | * 当前页 42 | */ 43 | current: number; 44 | /** 45 | * 每页大小 46 | */ 47 | size: number; 48 | } 49 | 50 | /** 51 | * 用户信息 52 | */ 53 | export interface UserForm { 54 | /** 55 | * 用户名 56 | */ 57 | username: string; 58 | /** 59 | * 密码 60 | */ 61 | password: string; 62 | /** 63 | * 验证码 64 | */ 65 | code:string; 66 | } 67 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/permission.ts: -------------------------------------------------------------------------------- 1 | import router from "@/router"; 2 | import useStore from "@/store"; 3 | import { getToken } from "@/utils/token"; 4 | import NProgress from "nprogress"; 5 | 6 | NProgress.configure({ 7 | easing: "ease", 8 | speed: 500, 9 | showSpinner: false, 10 | trickleSpeed: 200, 11 | minimum: 0.3, 12 | }); 13 | 14 | router.beforeEach((to, from, next) => { 15 | NProgress.start(); 16 | const { user } = useStore(); 17 | if (to.meta.title) { 18 | document.title = to.meta.title as string; 19 | } 20 | if (getToken()) { 21 | if (user.id === undefined) { 22 | user 23 | .GetUserInfo() 24 | .then(() => next()) 25 | .catch(() => { 26 | user.LogOut().then(() => { 27 | window.$message?.warning("凭证失效,请重新登录"); 28 | next(); 29 | }); 30 | }); 31 | } else { 32 | next(); 33 | } 34 | } else { 35 | next(); 36 | } 37 | }); 38 | router.afterEach(() => { 39 | NProgress.done(); 40 | }); 41 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import useAppStore from "./modules/app"; 2 | import useBlogStore from "./modules/blog"; 3 | import useUserStore from "./modules/user"; 4 | 5 | const useStore = () => ({ 6 | app: useAppStore(), 7 | blog: useBlogStore(), 8 | user: useUserStore(), 9 | }); 10 | 11 | export default useStore; 12 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/store/modules/app.ts: -------------------------------------------------------------------------------- 1 | import { AppState } from "../types"; 2 | 3 | const useAppStore = defineStore("useAppStore", { 4 | state: (): AppState => ({ 5 | isCollapse: false, 6 | searchFlag: false, 7 | loginFlag: false, 8 | registerFlag: false, 9 | forgetFlag: false, 10 | emailFlag: false, 11 | sideFlag: false, 12 | }), 13 | actions: { 14 | setCollapse(flag: boolean) { 15 | this.isCollapse = flag; 16 | }, 17 | setLoginFlag(flag: boolean) { 18 | this.loginFlag = flag; 19 | }, 20 | setRegisterFlag(flag: boolean) { 21 | this.registerFlag = flag; 22 | }, 23 | setForgetFlag(flag: boolean) { 24 | this.forgetFlag = flag; 25 | }, 26 | }, 27 | getters: {}, 28 | persist: { 29 | key: "app", 30 | storage: sessionStorage, 31 | }, 32 | }); 33 | 34 | export default useAppStore; 35 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/store/modules/blog.ts: -------------------------------------------------------------------------------- 1 | import { BlogInfo, SiteConfig } from "@/api/blogInfo/types"; 2 | 3 | const useBlogStore = defineStore("useBlogStore", { 4 | state: (): BlogInfo => ({ 5 | articleCount: 0, 6 | categoryCount: 0, 7 | tagCount: 0, 8 | viewCount: 0, 9 | siteConfig: {} as SiteConfig, 10 | }), 11 | actions: { 12 | setBlogInfo(blogInfo: BlogInfo) { 13 | this.articleCount = blogInfo.articleCount; 14 | this.categoryCount = blogInfo.categoryCount; 15 | this.tagCount = blogInfo.tagCount; 16 | this.viewCount = blogInfo.viewCount; 17 | this.siteConfig = blogInfo.siteConfig; 18 | }, 19 | }, 20 | getters: {}, 21 | persist: { 22 | key:"blog", 23 | storage: sessionStorage, 24 | }, 25 | }); 26 | 27 | export default useBlogStore; 28 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/types/global.d.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | $dialog?: import("naive-ui").DialogProviderInst; 3 | $message?: import("naive-ui").MessageProviderInst; 4 | $notification?: import("naive-ui").NotificationProviderInst; 5 | } 6 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/utils/date.ts: -------------------------------------------------------------------------------- 1 | import dayjs from "dayjs"; 2 | 3 | export function formatDate(date: string | Date, format = "YYYY-MM-DD") { 4 | return dayjs(date).format(format); 5 | } 6 | 7 | export function formatDateTime(date: string | Date, format = "YYYY-MM-DD HH:mm:ss") { 8 | return formatDate(date, format); 9 | } 10 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/utils/title.ts: -------------------------------------------------------------------------------- 1 | import { useEventListener } from "@vueuse/core"; 2 | 3 | export function titleChange() { 4 | // 动态标题 5 | let OriginTitile: string = document.title; 6 | let titleTime: NodeJS.Timeout; 7 | useEventListener(document, "visibilitychange", () => { 8 | if (document.hidden) { 9 | //离开当前页面时标签显示内容 10 | document.title = "w(゚Д゚)w 不要走!再看看嘛!"; 11 | clearTimeout(titleTime); 12 | } else { 13 | //返回当前页面时标签显示内容 14 | document.title = "♪(^∇^*)欢迎回来!"; 15 | //两秒后变回正常标题 16 | titleTime = setTimeout(() => { 17 | document.title = OriginTitile; 18 | }, 2000); 19 | } 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/utils/token.ts: -------------------------------------------------------------------------------- 1 | import Cookies from "js-cookie"; 2 | 3 | const TokenKey: string = "Token"; 4 | 5 | const domain: string = ".ttkwsd.top"; 6 | 7 | // token前缀 8 | export let token_prefix = "Bearer "; 9 | 10 | export function getToken() { 11 | return Cookies.get(TokenKey); 12 | } 13 | 14 | // 拉取下来记得删除domain 15 | export function setToken(token: string) { 16 | return Cookies.set(TokenKey, token, { domain: domain }); 17 | } 18 | 19 | export function removeToken() { 20 | return Cookies.remove(TokenKey, { domain: domain }); 21 | } 22 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/views/404/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 17 | 18 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/views/About/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module "*.vue" { 4 | import type { DefineComponent } from "vue"; 5 | const component: DefineComponent<{}, {}, any>; 6 | export default component; 7 | } 8 | declare module "@kangc/v-md-editor"; 9 | declare module "@kangc/v-md-editor/lib/preview"; 10 | declare module "@kangc/v-md-editor/lib/plugins/katex/cdn"; 11 | declare module "@kangc/v-md-editor/lib/theme/vuepress.js"; 12 | declare module "@kangc/v-md-editor/lib/theme/vuepress-parser.js"; 13 | declare module "@kangc/v-md-editor/lib/plugins/todo-list/index"; -------------------------------------------------------------------------------- /blog-vue/shoka-blog/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "suppressImplicitAnyIndexErrors": true, 5 | "useDefineForClassFields": true, 6 | "module": "ESNext", 7 | "moduleResolution": "Node", 8 | "strict": true, 9 | "jsx": "preserve", 10 | "resolveJsonModule": true, 11 | "isolatedModules": true, 12 | "esModuleInterop": true, 13 | "lib": ["ESNext", "DOM"], 14 | "skipLibCheck": true, 15 | "noEmit": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": [ "src/*" ], 19 | } 20 | }, 21 | "include": ["src/**/*.ts", "src/**/*.d.ts", "**/*.d.ts","src/**/*.tsx", "src/**/*.vue"], 22 | "references": [{ "path": "./tsconfig.node.json" }] 23 | } 24 | -------------------------------------------------------------------------------- /blog-vue/shoka-blog/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /deploy/.env: -------------------------------------------------------------------------------- 1 | #################### MySQL ##################### 2 | MYSQL_VERSION=8.0.27 3 | MYSQL_ROOT_PASSWORD=12345 4 | 5 | 6 | 7 | #################### Redis ##################### 8 | REDIS_VERSION=6.2.6 9 | REDIS_PASSWORD=12345 10 | 11 | 12 | 13 | #################### RabbitMQ ##################### 14 | RABBITMQ_VERSION=management 15 | RABBITMQ_USER=guest 16 | RABBITMQ_PASSWORD=guest 17 | 18 | 19 | 20 | #################### ElasticSearch ##################### 21 | ELASTICSEARCH_VERSION=7.17.3 22 | ELASTICSEARCH_PASSWORD=12345 23 | 24 | 25 | 26 | #################### Canal ##################### 27 | ELASTICSEARCH_VERSION=7.17.3 28 | ELASTICSEARCH_PASSWORD=12345 29 | 30 | -------------------------------------------------------------------------------- /deploy/Dockerfile: -------------------------------------------------------------------------------- 1 | # 基于openjdk11镜像 2 | FROM openjdk:11 3 | # 在主机 /var/lib/docker 目录下创建了一个临时文件并链接到容器的/tmp 4 | VOLUME /tmp 5 | # 将当前目录下的jar包复制到docker容器的目录下 6 | ADD blog-springboot-2.0.jar blog.jar 7 | # 运行jar并加快随机数产生过程 8 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/blog.jar"] 9 | # 定义时区参数 10 | ENV TZ=Asia/Shanghai 11 | # 设置时区 12 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -------------------------------------------------------------------------------- /deploy/blog-start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 源jar路径 3 | SOURCE_PATH=/usr/local/docker 4 | # docker 镜像/容器名字或者jar名字 这里都命名为这个 5 | SERVER_NAME=blog-springboot-2.0.jar 6 | TAG=latest 7 | SERVER_PORT=8080 8 | # 容器id 9 | CID=$(docker ps | grep "$SERVER_NAME" | awk '{print $1}') 10 | # 镜像id 11 | IID=$(docker images | grep "$SERVER_NAME:$TAG" | awk '{print $3}') 12 | if [ -n "$CID" ]; then 13 | echo "存在容器$SERVER_NAME, CID-$CID" 14 | docker stop $CID 15 | docker rm $CID 16 | fi 17 | # 构建docker镜像 18 | if [ -n "$IID" ]; then 19 | echo "存在$SERVER_NAME:$TAG镜像,IID=$IID" 20 | docker rmi $IID 21 | else 22 | echo "不存在$SERVER_NAME:$TAG镜像,开始构建镜像" 23 | cd $SOURCE_PATH 24 | docker build -t $SERVER_NAME:$TAG . 25 | fi 26 | # 运行docker容器 27 | docker run --name $SERVER_NAME -v /usr/local/upload:/usr/local/upload -d -p $SERVER_PORT:$SERVER_PORT $SERVER_NAME:$TAG 28 | echo "$SERVER_NAME容器创建完成" 29 | --------------------------------------------------------------------------------