├── .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 extends Payload>[] 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 |
2 |
3 |
4 |
5 |
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 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/blog-vue/shoka-admin/src/components/PreviewCode/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
32 |
--------------------------------------------------------------------------------
/blog-vue/shoka-admin/src/components/Screenfull/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/blog-vue/shoka-admin/src/components/SvgIcon/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
34 |
35 |
42 |
--------------------------------------------------------------------------------
/blog-vue/shoka-admin/src/components/TagView/ScrollPane.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 |
2 |
3 |
4 |
5 |
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 |
2 |
3 |
4 |
5 |
16 |
--------------------------------------------------------------------------------
/blog-vue/shoka-admin/src/views/web/page/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 |
2 |
8 |
9 |
10 |
12 |
13 |
--------------------------------------------------------------------------------
/blog-vue/shoka-blog/src/components/MusicPlayer/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/blog-vue/shoka-blog/src/components/Pagination/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
31 |
32 |
--------------------------------------------------------------------------------
/blog-vue/shoka-blog/src/components/Provider/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
31 |
34 |
--------------------------------------------------------------------------------
/blog-vue/shoka-blog/src/components/SvgIcon/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
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 |
2 |
8 |
9 |
10 |
Σ( ° △ °|||)︴404!何も見えない
11 |
12 |
13 |
14 |
15 |
17 |
18 |
--------------------------------------------------------------------------------
/blog-vue/shoka-blog/src/views/About/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
![]()
13 |
14 |
15 |
16 |
17 |
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 |
--------------------------------------------------------------------------------