├── LICENSE ├── README.md ├── blog-springboot ├── .gitignore ├── blog-api │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── apecode │ │ ├── WebApplication.java │ │ ├── aspect │ │ ├── ApiOptLogAspect.java │ │ └── OptLogAspect.java │ │ └── controller │ │ ├── ArticleController.java │ │ ├── ArticleTagController.java │ │ ├── CategoryController.java │ │ ├── CommentController.java │ │ ├── DailyVisitController.java │ │ ├── FriendLinkController.java │ │ ├── LoginLogController.java │ │ ├── LoginQqController.java │ │ ├── MailLogController.java │ │ ├── MenuController.java │ │ ├── MessageController.java │ │ ├── NoticeController.java │ │ ├── OperationLogController.java │ │ ├── PhotoAlbumController.java │ │ ├── PictureController.java │ │ ├── ResourceController.java │ │ ├── RoleController.java │ │ ├── RoleMenuController.java │ │ ├── RoleResourceController.java │ │ ├── TagController.java │ │ ├── TalkController.java │ │ ├── TalkPictureVideoController.java │ │ ├── UserAuthController.java │ │ ├── UserInfoController.java │ │ ├── UserRoleController.java │ │ └── WebsiteController.java ├── blog-auth │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── apecode │ │ └── auth │ │ ├── filter │ │ └── JwtAuthenticationTokenFilter.java │ │ └── handler │ │ ├── AccessDecisionManagerImpl.java │ │ ├── AccessDeniedHandlerImpl.java │ │ ├── AuthenticationEntryPointImpl.java │ │ ├── AuthenticationFailHandlerImpl.java │ │ ├── AuthenticationSuccessHandlerImpl.java │ │ ├── LogoutSuccessHandlerImpl.java │ │ └── UserAuthenticationProviderImpl.java ├── blog-common │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── cn │ │ │ └── apecode │ │ │ └── common │ │ │ ├── annotation │ │ │ ├── AccessLimit.java │ │ │ └── OptLog.java │ │ │ ├── constant │ │ │ ├── CommonConst.java │ │ │ ├── OptTypeConst.java │ │ │ ├── RabbitMQPrefixConst.java │ │ │ ├── RedisPrefixConst.java │ │ │ └── SocialLoginConst.java │ │ │ ├── dto │ │ │ ├── IpSourceDto.java │ │ │ └── UserDetailsDto.java │ │ │ ├── enums │ │ │ ├── ArticleStatusEnum.java │ │ │ ├── ArticleTypeEnum.java │ │ │ ├── CommentTypeEnum.java │ │ │ ├── EmailTypeEnum.java │ │ │ ├── FilePathEnum.java │ │ │ ├── LoginTypeEnum.java │ │ │ ├── RoleEnum.java │ │ │ ├── StatusCodeEnum.java │ │ │ ├── UploadModeEnum.java │ │ │ └── ZoneEnum.java │ │ │ ├── exception │ │ │ ├── BizException.java │ │ │ └── GlobalException.java │ │ │ └── utils │ │ │ ├── BeanCopyUtils.java │ │ │ ├── CommonUtils.java │ │ │ ├── FileUtils.java │ │ │ ├── HTMLUtils.java │ │ │ ├── IpUtils.java │ │ │ ├── JwtUtils.java │ │ │ ├── RandomUtils.java │ │ │ ├── ResponseCode.java │ │ │ ├── SecurityUtils.java │ │ │ └── UserUtils.java │ │ └── resources │ │ ├── dict.txt │ │ └── sensitive_word_allow.txt ├── blog-config │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── cn │ │ │ └── apecode │ │ │ ├── config │ │ │ ├── ConnectorConfig.java │ │ │ ├── Knife4jConfig.java │ │ │ ├── MyBatisPlusConfig.java │ │ │ ├── RabbitMQConfig.java │ │ │ ├── RedisConfig.java │ │ │ ├── SecurityConfig.java │ │ │ └── WebMvcConfig.java │ │ │ └── handler │ │ │ ├── MetaObjectHandlerImpl.java │ │ │ ├── PageableHandlerInterceptor.java │ │ │ └── RequestAccessLimit.java │ │ └── resources │ │ ├── META-INF │ │ └── services │ │ │ └── com.anji.captcha.service.CaptchaCacheService │ │ ├── application-dev.yml │ │ ├── application-pro.yml │ │ ├── application.yml │ │ ├── images │ │ └── jigsaw │ │ │ ├── original │ │ │ ├── bg1.png │ │ │ ├── bg2.png │ │ │ ├── bg3.png │ │ │ ├── bg4.png │ │ │ ├── bg5.png │ │ │ ├── bg6.png │ │ │ ├── bg7.png │ │ │ ├── bg8.png │ │ │ └── bg9.png │ │ │ └── slidingBlock │ │ │ ├── 11 │ │ │ ├── 10.png │ │ │ ├── 11.png │ │ │ ├── 12.png │ │ │ ├── 13.png │ │ │ ├── 14.png │ │ │ ├── 15.png │ │ │ ├── 16.png │ │ │ ├── 17.png │ │ │ ├── 18.png │ │ │ ├── 19.png │ │ │ ├── 8.png │ │ │ ├── 9.png │ │ │ ├── xin替换.zip │ │ │ └── xin替换 │ │ │ │ ├── 1.png │ │ │ │ ├── 2.png │ │ │ │ ├── 3.png │ │ │ │ ├── 4.png │ │ │ │ ├── 5.png │ │ │ │ ├── 6.png │ │ │ │ └── 7.png │ │ │ ├── 1.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ └── 4.png │ │ ├── log4j2.component.properties │ │ └── log4j2.yml ├── blog-crypto │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── apecode │ │ └── crypto │ │ ├── annotation │ │ ├── Decrypt.java │ │ └── Encrypt.java │ │ ├── config │ │ └── CryptoConfig.java │ │ ├── handler │ │ ├── AESKey.java │ │ ├── DecryptHttpInputMessage.java │ │ ├── DecryptRequest.java │ │ ├── EncryptResponse.java │ │ ├── RequestDataExtend.java │ │ └── RespDataExtend.java │ │ └── utils │ │ ├── AESUtil.java │ │ └── RSAUtil.java ├── blog-mail │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── apecode │ │ └── mail │ │ └── consumer │ │ ├── ConsumerCommon.java │ │ └── EmailConsumer.java ├── blog-pojo │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── apecode │ │ ├── dto │ │ ├── ArchiveDto.java │ │ ├── ArchiveMonthDto.java │ │ ├── ArticleBackDto.java │ │ ├── ArticleBackPreviewDto.java │ │ ├── ArticleDto.java │ │ ├── ArticleHomeDto.java │ │ ├── ArticleLikeRankDto.java │ │ ├── ArticlePaginationDto.java │ │ ├── ArticleRankDto.java │ │ ├── ArticleRecommendDto.java │ │ ├── ArticleSearchDto.java │ │ ├── ArticleStatisticsDto.java │ │ ├── BlogBackInfoDto.java │ │ ├── BlogHomeInfoDto.java │ │ ├── CategoryArticleCountDto.java │ │ ├── CategoryBackDto.java │ │ ├── CategoryFrontDto.java │ │ ├── CategoryOptionDto.java │ │ ├── CategorySearchDto.java │ │ ├── CommentBackDto.java │ │ ├── CommentFrontDto.java │ │ ├── ConditionSearchArticleDto.java │ │ ├── DiskInfoDto.java │ │ ├── EmailDto.java │ │ ├── FriendLinkBackDto.java │ │ ├── FriendLinkFrontDto.java │ │ ├── LabelOptionDto.java │ │ ├── LoginLogBackDto.java │ │ ├── MailLogBackDto.java │ │ ├── MemoryInfoDto.java │ │ ├── MessageBackDto.java │ │ ├── MessageFrontDto.java │ │ ├── NewCommentDto.java │ │ ├── NoticeBackDto.java │ │ ├── NoticeFrontDto.java │ │ ├── OperationLogBackDto.java │ │ ├── PhotoAlbumBackDto.java │ │ ├── PhotoAlbumFrontDto.java │ │ ├── PhotoAlbumInfoDto.java │ │ ├── PhotoAlbumPictureCountDto.java │ │ ├── PictureBackDto.java │ │ ├── PictureFrontDto.java │ │ ├── QQTokenDto.java │ │ ├── QQUserInfoDto.java │ │ ├── ReplyCountDto.java │ │ ├── ReplyDto.java │ │ ├── ResourceDto.java │ │ ├── RoleDto.java │ │ ├── RoleResourceDto.java │ │ ├── SearchDto.java │ │ ├── SimpleUserInfoDto.java │ │ ├── SocialTokenDto.java │ │ ├── SocialUserInfoDto.java │ │ ├── TagBackDto.java │ │ ├── TagDto.java │ │ ├── TagFrontDto.java │ │ ├── TagSearchDto.java │ │ ├── TagWithArticleCountDto.java │ │ ├── TalkBackDto.java │ │ ├── TalkBackOnlyDto.java │ │ ├── TalkFrontDto.java │ │ ├── TalkPictureVideoDto.java │ │ ├── UploadFileInfoDto.java │ │ ├── UserCacheDto.java │ │ ├── UserInfoBackDto.java │ │ ├── UserInfoDto.java │ │ ├── UserInfoFrontDto.java │ │ ├── UserMenuDto.java │ │ ├── UserRoleDto.java │ │ ├── UserVisitAreaStatisticsDto.java │ │ └── VisitStatisticsDto.java │ │ ├── entity │ │ ├── Article.java │ │ ├── ArticleTag.java │ │ ├── Category.java │ │ ├── Comment.java │ │ ├── DailyVisit.java │ │ ├── FriendLink.java │ │ ├── LoginLog.java │ │ ├── LoginQq.java │ │ ├── MailLog.java │ │ ├── Menu.java │ │ ├── Message.java │ │ ├── Notice.java │ │ ├── OperationLog.java │ │ ├── PhotoAlbum.java │ │ ├── Picture.java │ │ ├── Resource.java │ │ ├── Role.java │ │ ├── RoleMenu.java │ │ ├── RoleResource.java │ │ ├── Tag.java │ │ ├── Talk.java │ │ ├── TalkPictureVideo.java │ │ ├── UserAuth.java │ │ ├── UserInfo.java │ │ ├── UserRole.java │ │ └── Website.java │ │ └── vo │ │ ├── ArticleVo.java │ │ ├── CategoryVo.java │ │ ├── CommentVo.java │ │ ├── ConditionVo.java │ │ ├── DeleteVo.java │ │ ├── FindPasswordVo.java │ │ ├── FriendLinkUserVo.java │ │ ├── FriendLinkVo.java │ │ ├── LoginParamVo.java │ │ ├── MenuVo.java │ │ ├── MessageVo.java │ │ ├── NoticeVo.java │ │ ├── PageResult.java │ │ ├── PageResultWithObject.java │ │ ├── PasswordVo.java │ │ ├── PhotoAlbumVo.java │ │ ├── PictureInfoVo.java │ │ ├── PictureVo.java │ │ ├── QQLoginVo.java │ │ ├── RegisterVo.java │ │ ├── ResourceVo.java │ │ ├── ReviewVo.java │ │ ├── RoleVo.java │ │ ├── SaveOrUnbindEmailVo.java │ │ ├── TagVo.java │ │ ├── TalkVo.java │ │ ├── TopVo.java │ │ ├── UserEnableVo.java │ │ ├── UserInfoVo.java │ │ ├── UserRoleVo.java │ │ └── WebsiteConfigVo.java ├── blog-service │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── cn │ │ │ └── apecode │ │ │ ├── handler │ │ │ └── FilterInvocationSecurityMetadataSourceImpl.java │ │ │ ├── mapper │ │ │ ├── ArticleMapper.java │ │ │ ├── ArticleTagMapper.java │ │ │ ├── CategoryMapper.java │ │ │ ├── CommentMapper.java │ │ │ ├── DailyVisitMapper.java │ │ │ ├── FriendLinkMapper.java │ │ │ ├── LoginLogMapper.java │ │ │ ├── LoginQqMapper.java │ │ │ ├── MailLogMapper.java │ │ │ ├── MenuMapper.java │ │ │ ├── MessageMapper.java │ │ │ ├── NoticeMapper.java │ │ │ ├── OperationLogMapper.java │ │ │ ├── PhotoAlbumMapper.java │ │ │ ├── PictureMapper.java │ │ │ ├── ResourceMapper.java │ │ │ ├── RoleMapper.java │ │ │ ├── RoleMenuMapper.java │ │ │ ├── RoleResourceMapper.java │ │ │ ├── TagMapper.java │ │ │ ├── TalkMapper.java │ │ │ ├── TalkPictureVideoMapper.java │ │ │ ├── UserAuthMapper.java │ │ │ ├── UserInfoMapper.java │ │ │ ├── UserRoleMapper.java │ │ │ └── WebsiteMapper.java │ │ │ ├── schedule │ │ │ └── Schedule.java │ │ │ ├── service │ │ │ ├── ArticleService.java │ │ │ ├── ArticleTagService.java │ │ │ ├── CategoryService.java │ │ │ ├── CommentService.java │ │ │ ├── DailyVisitService.java │ │ │ ├── FriendLinkService.java │ │ │ ├── LoginLogService.java │ │ │ ├── LoginQqService.java │ │ │ ├── MailLogService.java │ │ │ ├── MenuService.java │ │ │ ├── MessageService.java │ │ │ ├── NoticeService.java │ │ │ ├── OperationLogService.java │ │ │ ├── PhotoAlbumService.java │ │ │ ├── PictureService.java │ │ │ ├── RedisService.java │ │ │ ├── ResourceService.java │ │ │ ├── RoleMenuService.java │ │ │ ├── RoleResourceService.java │ │ │ ├── RoleService.java │ │ │ ├── TagService.java │ │ │ ├── TalkPictureVideoService.java │ │ │ ├── TalkService.java │ │ │ ├── UserAuthService.java │ │ │ ├── UserInfoService.java │ │ │ ├── UserRoleService.java │ │ │ ├── WebsiteService.java │ │ │ └── impl │ │ │ │ ├── ArticleServiceImpl.java │ │ │ │ ├── ArticleTagServiceImpl.java │ │ │ │ ├── CaptchaCacheServiceRedisImpl.java │ │ │ │ ├── CategoryServiceImpl.java │ │ │ │ ├── CommentServiceImpl.java │ │ │ │ ├── DailyVisitServiceImpl.java │ │ │ │ ├── FriendLinkServiceImpl.java │ │ │ │ ├── LoginLogServiceImpl.java │ │ │ │ ├── LoginQqServiceImpl.java │ │ │ │ ├── MailLogServiceImpl.java │ │ │ │ ├── MenuServiceImpl.java │ │ │ │ ├── MessageServiceImpl.java │ │ │ │ ├── NoticeServiceImpl.java │ │ │ │ ├── OperationLogServiceImpl.java │ │ │ │ ├── PhotoAlbumServiceImpl.java │ │ │ │ ├── PictureServiceImpl.java │ │ │ │ ├── RedisServiceImpl.java │ │ │ │ ├── ResourceServiceImpl.java │ │ │ │ ├── RoleMenuServiceImpl.java │ │ │ │ ├── RoleResourceServiceImpl.java │ │ │ │ ├── RoleServiceImpl.java │ │ │ │ ├── TagServiceImpl.java │ │ │ │ ├── TalkPictureVideoServiceImpl.java │ │ │ │ ├── TalkServiceImpl.java │ │ │ │ ├── UserAuthServiceImpl.java │ │ │ │ ├── UserDetailsServiceImpl.java │ │ │ │ ├── UserInfoServiceImpl.java │ │ │ │ ├── UserRoleServiceImpl.java │ │ │ │ └── WebsiteServiceImpl.java │ │ │ ├── strategy │ │ │ ├── SocialLoginStrategy.java │ │ │ ├── UploadFileStrategy.java │ │ │ ├── context │ │ │ │ ├── SocialLoginStrategyContext.java │ │ │ │ └── UploadFileStrategyContext.java │ │ │ └── impl │ │ │ │ ├── AbstractSocialLoginStrategyImpl.java │ │ │ │ ├── AbstractUploadFileStrategyImpl.java │ │ │ │ ├── LocalUploadFileStrategyImpl.java │ │ │ │ ├── OssUploadFileStrategyImpl.java │ │ │ │ └── QQLoginStrategyImpl.java │ │ │ └── utils │ │ │ ├── AnjiCaptchaUtils.java │ │ │ ├── OSSConfigYml.java │ │ │ ├── PageUtils.java │ │ │ ├── QQConfigYml.java │ │ │ ├── QQTokenUtils.java │ │ │ └── SystemInfoUtils.java │ │ └── resources │ │ └── mapper │ │ ├── ArticleMapper.xml │ │ ├── ArticleTagMapper.xml │ │ ├── CategoryMapper.xml │ │ ├── CommentMapper.xml │ │ ├── DailyVisitMapper.xml │ │ ├── FriendLinkMapper.xml │ │ ├── LoginLogMapper.xml │ │ ├── LoginQqMapper.xml │ │ ├── MailLogMapper.xml │ │ ├── MenuMapper.xml │ │ ├── MessageMapper.xml │ │ ├── NoticeMapper.xml │ │ ├── OperationLogMapper.xml │ │ ├── PhotoAlbumMapper.xml │ │ ├── PictureMapper.xml │ │ ├── ResourceMapper.xml │ │ ├── RoleMapper.xml │ │ ├── RoleMenuMapper.xml │ │ ├── RoleResourceMapper.xml │ │ ├── TagMapper.xml │ │ ├── TalkMapper.xml │ │ ├── TalkPictureVideoMapper.xml │ │ ├── UserAuthMapper.xml │ │ ├── UserInfoMapper.xml │ │ ├── UserRoleMapper.xml │ │ └── WebsiteMapper.xml ├── blog-websocket │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── cn │ │ └── apecode │ │ └── websocket │ │ ├── config │ │ ├── WebSocketConfig.java │ │ ├── WebSocketHandshakeHandler.java │ │ └── WebSocketHandshakeInterceptor.java │ │ ├── controller │ │ ├── ChatMessageController.java │ │ └── SystemInfoController.java │ │ ├── enums │ │ └── ChatMessageTypeEnum.java │ │ ├── handler │ │ ├── ConnectListener.java │ │ └── DisconnectListener.java │ │ ├── pojo │ │ ├── ChatMessage.java │ │ ├── OnlineUser.java │ │ └── VisitorUser.java │ │ ├── service │ │ ├── ChatMessageService.java │ │ ├── SystemInfoService.java │ │ └── impl │ │ │ ├── ChatMessageServiceImpl.java │ │ │ └── SystemInfoServiceImpl.java │ │ └── utils │ │ └── VisitorUtils.java └── pom.xml ├── blog.sql ├── blog_admin ├── .env.development ├── .env.production ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── public │ └── sleaves.svg ├── src │ ├── App.vue │ ├── api │ │ ├── config.ts │ │ ├── enum │ │ │ └── statusCode.ts │ │ ├── model │ │ │ ├── AlbumModel.ts │ │ │ ├── ArticleModel.ts │ │ │ ├── CategoryModel.ts │ │ │ ├── CommentModel.ts │ │ │ ├── FriendLinkModel.ts │ │ │ ├── LogsModel.ts │ │ │ ├── MenuModel.ts │ │ │ ├── MessageModel.ts │ │ │ ├── NoticeModel.ts │ │ │ ├── PictureModel.ts │ │ │ ├── ResourceModel.ts │ │ │ ├── ResultObject.ts │ │ │ ├── RoleModel.ts │ │ │ ├── TagModel.ts │ │ │ ├── TalkModel.ts │ │ │ ├── UserInfoModel.ts │ │ │ ├── UserModel.ts │ │ │ └── WebsiteModel.ts │ │ ├── params │ │ │ ├── ArticleParams.ts │ │ │ ├── CategoryParams.ts │ │ │ ├── ConditionParams.ts │ │ │ ├── FriendLinkParams.ts │ │ │ ├── MenuParams.ts │ │ │ ├── NoticeParams.ts │ │ │ ├── PhotoAlbumParams.ts │ │ │ ├── PictureParams.ts │ │ │ ├── ResourceParams.ts │ │ │ ├── ReviewParams.ts │ │ │ ├── TagParams.ts │ │ │ ├── TalkParams.ts │ │ │ ├── UserParams.ts │ │ │ └── roleParams.ts │ │ ├── requests │ │ │ ├── About.ts │ │ │ ├── Album.ts │ │ │ ├── Article.ts │ │ │ ├── Category.ts │ │ │ ├── Comment.ts │ │ │ ├── FriendLink.ts │ │ │ ├── Logs.ts │ │ │ ├── Menu.ts │ │ │ ├── Message.ts │ │ │ ├── Notice.ts │ │ │ ├── Picture.ts │ │ │ ├── Resource.ts │ │ │ ├── Role.ts │ │ │ ├── Tag.ts │ │ │ ├── Talk.ts │ │ │ ├── UserAuth.ts │ │ │ ├── UserInfo.ts │ │ │ └── Website.ts │ │ └── service.ts │ ├── assets │ │ ├── fonts │ │ │ └── ZhuZiAWan.woff2 │ │ ├── imgs │ │ │ └── local.png │ │ └── json │ │ │ └── china.json │ ├── components │ │ ├── DescSetting.vue │ │ ├── EmojiExtension │ │ │ ├── index.vue │ │ │ └── staticConfig.ts │ │ ├── GlobalDraw.vue │ │ ├── GlobalProvider.vue │ │ ├── TagCloud.vue │ │ ├── comment │ │ │ └── CommentComp.vue │ │ ├── common │ │ │ ├── constant.ts │ │ │ └── dataTable │ │ │ │ ├── DataTableSetting.vue │ │ │ │ └── index.ts │ │ ├── layouts │ │ │ ├── AppMain.vue │ │ │ ├── BaseHeader.vue │ │ │ ├── BaseLogo.vue │ │ │ ├── BaseSider.vue │ │ │ ├── Breadcrumb.vue │ │ │ ├── Menu.vue │ │ │ ├── TriggerCollapse.vue │ │ │ └── tagsView │ │ │ │ ├── TagsView.vue │ │ │ │ ├── useDropdown.ts │ │ │ │ └── useTagsView.ts │ │ └── verifition │ │ │ ├── Verify.vue │ │ │ ├── Verify │ │ │ ├── VerifyPoints.vue │ │ │ └── VerifySlide.vue │ │ │ ├── api │ │ │ └── index.js │ │ │ └── utils │ │ │ ├── ase.js │ │ │ ├── axios.js │ │ │ └── util.js │ ├── constant.ts │ ├── echarts │ │ ├── echart.d.ts │ │ └── index.ts │ ├── env.d.ts │ ├── layout │ │ └── PageLayout.vue │ ├── main.ts │ ├── router │ │ ├── index.ts │ │ └── routes.ts │ ├── settings.ts │ ├── shims.d.ts │ ├── store │ │ ├── index.ts │ │ ├── modules │ │ │ ├── global.ts │ │ │ ├── menu.ts │ │ │ ├── setting.ts │ │ │ ├── store-name.ts │ │ │ ├── tagsView.ts │ │ │ ├── userInfo.ts │ │ │ └── website.ts │ │ └── types │ │ │ └── index.d.ts │ ├── style │ │ └── base.css │ ├── utils │ │ ├── Msp.ts │ │ ├── aes.ts │ │ ├── dynamicEmojis.ts │ │ ├── emojis.ts │ │ ├── icons.ts │ │ ├── index.ts │ │ ├── rsa.ts │ │ └── utils.ts │ ├── views │ │ ├── about │ │ │ ├── About.vue │ │ │ └── data │ │ │ │ └── useAbout.ts │ │ ├── album │ │ │ ├── Album.vue │ │ │ ├── Delete.vue │ │ │ ├── Picture.vue │ │ │ └── data │ │ │ │ ├── useAlbum.ts │ │ │ │ ├── useDelete.ts │ │ │ │ └── usePicture.ts │ │ ├── article │ │ │ ├── Article.vue │ │ │ ├── ArticleList.vue │ │ │ └── data │ │ │ │ ├── useArticle.ts │ │ │ │ ├── useArticleList.ts │ │ │ │ ├── useCategory.ts │ │ │ │ └── useUpload.ts │ │ ├── category │ │ │ ├── Category.vue │ │ │ └── data │ │ │ │ └── useCategory.ts │ │ ├── comment │ │ │ ├── Comment.vue │ │ │ └── data │ │ │ │ └── useComment.ts │ │ ├── error │ │ │ └── PageNotFound.vue │ │ ├── friendLink │ │ │ ├── FriendLink.vue │ │ │ └── data │ │ │ │ └── useFriendLink.ts │ │ ├── home │ │ │ ├── Home.vue │ │ │ └── data │ │ │ │ ├── area.ts │ │ │ │ ├── articleLikeRank.ts │ │ │ │ ├── articleRank.ts │ │ │ │ ├── articleStatistics.ts │ │ │ │ ├── category.ts │ │ │ │ ├── systemDiskInfo.ts │ │ │ │ ├── systemMemory.ts │ │ │ │ ├── useHome.ts │ │ │ │ └── visitStatistics.ts │ │ ├── log │ │ │ ├── Login.vue │ │ │ ├── Mail.vue │ │ │ ├── Operation.vue │ │ │ └── data │ │ │ │ ├── useLoginLog.ts │ │ │ │ ├── useMailLog.ts │ │ │ │ └── useOperationLog.ts │ │ ├── login │ │ │ ├── Login.vue │ │ │ └── data │ │ │ │ ├── monsterImg.ts │ │ │ │ └── useUserLogin.ts │ │ ├── menu │ │ │ ├── Menu.vue │ │ │ └── data │ │ │ │ └── useMenu.ts │ │ ├── message │ │ │ ├── Message.vue │ │ │ └── data │ │ │ │ └── useMessage.ts │ │ ├── personal │ │ │ ├── Personal.vue │ │ │ └── data │ │ │ │ ├── usePassword.ts │ │ │ │ └── usePersonal.ts │ │ ├── resource │ │ │ ├── Resource.vue │ │ │ └── data │ │ │ │ └── useResource.ts │ │ ├── role │ │ │ ├── Role.vue │ │ │ └── data │ │ │ │ └── useRole.ts │ │ ├── tag │ │ │ ├── Tag.vue │ │ │ └── data │ │ │ │ └── useTag.ts │ │ ├── talk │ │ │ ├── Talk.vue │ │ │ ├── TalkList.vue │ │ │ └── data │ │ │ │ ├── useTalk.ts │ │ │ │ └── useTalkList.ts │ │ ├── users │ │ │ ├── Users.vue │ │ │ └── data │ │ │ │ └── useUsers.ts │ │ └── website │ │ │ ├── Website.vue │ │ │ └── data │ │ │ ├── useAvatar.ts │ │ │ └── useWebsite.ts │ └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── blog_start.sh └── blog_vue ├── .env.development ├── .env.production ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── public └── sleaves.svg ├── src ├── App.vue ├── api │ ├── config.ts │ ├── entity │ │ ├── AlbumEntity.ts │ │ ├── ArticleEntity.ts │ │ ├── CategoryEntity.ts │ │ ├── ChatRoomEntity.ts │ │ ├── CommentEntity.ts │ │ ├── FriendLinkEntity.ts │ │ ├── MessageEntity.ts │ │ ├── NoticeEntity.ts │ │ ├── PictureEntity.ts │ │ ├── ResultObject.ts │ │ ├── TagEntity.ts │ │ ├── TalkEntity.ts │ │ ├── UserEntity.ts │ │ ├── WebSocketMessage.ts │ │ ├── WebsiteInfoEntity.ts │ │ └── YiYanEntity.ts │ ├── enum │ │ ├── StatusCode.ts │ │ └── WebSocketEnum.ts │ ├── params │ │ ├── CommentParams.ts │ │ ├── ConditionParams.ts │ │ ├── FriendLinkParams.ts │ │ └── UserParams.ts │ ├── requests │ │ ├── Album.ts │ │ ├── Article.ts │ │ ├── Category.ts │ │ ├── ChatRoom.ts │ │ ├── Comment.ts │ │ ├── FriendLink.ts │ │ ├── Message.ts │ │ ├── Notice.ts │ │ ├── Picture.ts │ │ ├── SystemInfo.ts │ │ ├── Tag.ts │ │ ├── Talk.ts │ │ ├── User.ts │ │ ├── WebsiteInfo.ts │ │ └── YiYan.ts │ └── services.ts ├── assets │ ├── css │ │ ├── base.css │ │ ├── dark.css │ │ ├── header │ │ │ └── website.css │ │ └── light.css │ ├── fonts │ │ └── ZhuZiAWan.woff2 │ └── imgs │ │ ├── heart.png │ │ ├── public_security_record.png │ │ └── qq_login.png ├── components │ ├── AppMain.vue │ ├── BoxComponent.vue │ ├── Mask.vue │ ├── OauthLogin.vue │ ├── comment │ │ ├── Comment.vue │ │ ├── CommentHooks.ts │ │ ├── CommentItem.vue │ │ ├── CommentList.vue │ │ └── Reply.vue │ ├── layout │ │ ├── ConfigProvider.vue │ │ ├── footer │ │ │ └── Footer.vue │ │ └── header │ │ │ ├── Header.vue │ │ │ ├── NavPc.vue │ │ │ ├── NavSmall.vue │ │ │ ├── Navigation.vue │ │ │ ├── headerHooks.ts │ │ │ └── website │ │ │ ├── ChatRoomBtn.vue │ │ │ ├── WebSite.vue │ │ │ └── WebSiteSide.vue │ ├── loading │ │ └── Loading.vue │ ├── modal │ │ ├── ArticleThemeModal.vue │ │ ├── BindOrUnbindEmailModal.vue │ │ ├── ForgetPasswordModal.vue │ │ ├── FriendLinkHooks.ts │ │ ├── FriendLinkModal.vue │ │ ├── LoginModal.vue │ │ ├── Modal.vue │ │ ├── RegisterModal.vue │ │ └── SearchModal.vue │ ├── pagination │ │ └── Pagination.vue │ ├── preview │ │ └── PreviewPicture.vue │ ├── rightMenu │ │ ├── RightMenu.vue │ │ └── rightMenuHooks.ts │ ├── scroll │ │ └── ScrollLoad.vue │ ├── skeleton │ │ └── Skeleton.vue │ └── verifition │ │ ├── Verify.vue │ │ ├── Verify │ │ ├── VerifyPoints.vue │ │ └── VerifySlide.vue │ │ ├── api │ │ └── index.js │ │ └── utils │ │ ├── ase.js │ │ ├── axios.js │ │ └── util.js ├── config.ts ├── constant.ts ├── directives │ ├── Lazy.ts │ └── index.ts ├── env.d.ts ├── layout │ ├── LRLayout.vue │ └── PageLayout.vue ├── main.ts ├── router │ ├── index.ts │ └── routers.ts ├── settings.ts ├── store │ ├── index.ts │ └── modules │ │ ├── global.ts │ │ ├── setting.ts │ │ ├── store-name.ts │ │ ├── userInfo.ts │ │ ├── websiteInfo.ts │ │ └── websocket.ts ├── utils │ ├── WebSocketUtils.ts │ ├── aes.ts │ ├── emojis.ts │ ├── rsa.ts │ ├── sendEmailUtils.ts │ ├── socialLoginUtils.ts │ └── utils.ts ├── views │ ├── about │ │ ├── About.vue │ │ └── AboutHooks.ts │ ├── album │ │ ├── Album.vue │ │ └── AlbumHooks.ts │ ├── archive │ │ ├── Archive.vue │ │ └── ArchiveHooks.ts │ ├── article │ │ ├── Article.vue │ │ └── articleHooks.ts │ ├── category │ │ ├── ArticleList.vue │ │ └── Category.vue │ ├── chatroom │ │ ├── Chat.vue │ │ ├── ChatRoom.vue │ │ ├── OnlineUsers.vue │ │ └── chatRoom.ts │ ├── comm │ │ ├── ArticleList.vue │ │ ├── CommentUser.vue │ │ ├── NewsArticle.vue │ │ └── NewsComment.vue │ ├── error │ │ └── PageNotFound.vue │ ├── friendLink │ │ ├── FriendLink.vue │ │ └── FriendLinkHooks.ts │ ├── home │ │ ├── ArticleList.vue │ │ ├── BlogInfo.vue │ │ └── Home.vue │ ├── message │ │ ├── Message.vue │ │ ├── MessageHooks.ts │ │ └── PreviewMessage.vue │ ├── picture │ │ ├── Picture.vue │ │ └── PictureHooks.ts │ ├── profile │ │ ├── Profile.vue │ │ ├── ProfileHooks.ts │ │ └── children │ │ │ ├── FriendLink.vue │ │ │ ├── FriendLinkHooks.ts │ │ │ ├── Notice.vue │ │ │ ├── NoticeHooks.ts │ │ │ ├── Password.vue │ │ │ ├── PasswordHooks.ts │ │ │ ├── UserInfo.vue │ │ │ └── UserInfoHooks.ts │ ├── tag │ │ ├── ArticleList.vue │ │ └── Tag.vue │ └── talk │ │ ├── Talk.vue │ │ ├── TalkHooks.ts │ │ ├── TalkList.vue │ │ └── TalkListHooks.ts └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json ├── vite.base.config.ts ├── vite.config.ts ├── vite.dev.config.ts ├── vite.prod.config.ts └── windi.config.ts /blog-springboot/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /blog-springboot/blog-api/src/main/java/cn/apecode/WebApplication.java: -------------------------------------------------------------------------------- 1 | package cn.apecode; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class WebApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(WebApplication.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /blog-springboot/blog-api/src/main/java/cn/apecode/controller/ArticleTagController.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | *

8 | * 文章所属标签 前端控制器 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | @RestController 15 | @RequestMapping("/blog/articleTag") 16 | public class ArticleTagController { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-api/src/main/java/cn/apecode/controller/DailyVisitController.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | *

8 | * 日均访问量 前端控制器 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | @RestController 15 | @RequestMapping("/blog/dailyVisit") 16 | public class DailyVisitController { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-api/src/main/java/cn/apecode/controller/LoginLogController.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | *

8 | * 登录日志 前端控制器 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | @RestController 15 | @RequestMapping("/blog/loginLog") 16 | public class LoginLogController { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-api/src/main/java/cn/apecode/controller/LoginQqController.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | *

8 | * QQ登录 前端控制器 9 | *

10 | * 11 | * @author apecode 12 | * @since 2023-01-05 13 | */ 14 | @RestController 15 | @RequestMapping("/blog/loginQq") 16 | public class LoginQqController { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-api/src/main/java/cn/apecode/controller/MailLogController.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | *

8 | * 邮件发送记录 前端控制器 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | @RestController 15 | @RequestMapping("/blog/mailLog") 16 | public class MailLogController { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-api/src/main/java/cn/apecode/controller/RoleMenuController.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | *

8 | * 菜单角色权限 前端控制器 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | @RestController 15 | @RequestMapping("/blog/roleMenu") 16 | public class RoleMenuController { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-api/src/main/java/cn/apecode/controller/RoleResourceController.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | *

8 | * 资源角色权限 前端控制器 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | @RestController 15 | @RequestMapping("/blog/roleResource") 16 | public class RoleResourceController { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-api/src/main/java/cn/apecode/controller/TalkPictureVideoController.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | *

8 | * 说说的图片和视频 前端控制器 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-07-06 13 | */ 14 | @RestController 15 | @RequestMapping("/blog/talkPictureVideo") 16 | public class TalkPictureVideoController { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-api/src/main/java/cn/apecode/controller/UserRoleController.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.controller; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | *

8 | * 用户权限 前端控制器 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | @RestController 15 | @RequestMapping("/blog/userRole") 16 | public class UserRoleController { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/annotation/AccessLimit.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @description: 接口限流 7 | * @author: apecode 8 | * @date: 2022-12-24 20:49 9 | **/ 10 | @Target(ElementType.METHOD) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Documented 13 | public @interface AccessLimit { 14 | 15 | /** 16 | * 访问时间(秒) 17 | * @return 18 | */ 19 | long seconds(); 20 | 21 | /** 22 | * 最大请求次数 23 | * @return 24 | */ 25 | int maxCount(); 26 | } 27 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/annotation/OptLog.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @description: 操作日志注解 7 | * @author: apecode 8 | * @date: 2022-07-09 12:13 9 | **/ 10 | @Target(ElementType.METHOD) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Documented 13 | public @interface OptLog { 14 | 15 | /** 16 | * 17 | * @description: 操作类型 18 | * 19 | * @return String 20 | * @auther apecode 21 | * @date 2022-07-09 12:15 22 | */ 23 | String optType() default ""; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/constant/OptTypeConst.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.constant; 2 | 3 | /** 4 | * @description: 操作日志类型常量 5 | * @author: apecode 6 | * @date: 2022-07-09 23:09 7 | **/ 8 | public class OptTypeConst { 9 | 10 | public static final String SAVE_OR_UPDATE = "新增或修改"; 11 | 12 | public static final String SAVE = "新增"; 13 | 14 | public static final String UPDATE = "修改"; 15 | 16 | public static final String REMOVE = "删除"; 17 | 18 | public static final String COMMENT = "评论"; 19 | } 20 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/constant/RabbitMQPrefixConst.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.constant; 2 | 3 | /** 4 | * @description: RabbitMQ前缀常量 5 | * @author: apecode 6 | * @date: 2022-06-09 19:10 7 | **/ 8 | public class RabbitMQPrefixConst { 9 | /** 10 | * Email交换机 11 | */ 12 | public static final String EMAIL_EXCHANGE_NAME = "email.exchange"; 13 | 14 | /** 15 | * Email队列 16 | */ 17 | public static final String EMAIL_QUEUE_NAME = "email.queue"; 18 | 19 | /** 20 | * 路由键 21 | */ 22 | public static final String EMAIL_ROUTING_KEY_NAME = "email.routing.key"; 23 | } 24 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/constant/SocialLoginConst.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.constant; 2 | 3 | /** 4 | * @description: 第三方登录参数常量 5 | * @author: apecode 6 | * @date: 2023-01-05 12:36 7 | **/ 8 | public class SocialLoginConst { 9 | 10 | // oauth2登录方式 11 | public static final String GRANT_TYPE = "grant_type"; 12 | 13 | // oauth2客户端id 14 | public static final String CLIENT_ID = "client_id"; 15 | 16 | // oauth2客户端密码 17 | public static final String CLIENT_SECRET = "client_secret"; 18 | 19 | // CODE 20 | public static final String CODE = "code"; 21 | 22 | // oauth2回调域名 23 | public static final String REDIRECT_URI = "redirect_uri"; 24 | 25 | // QQ openId 26 | public static final String QQ_OPEN_ID = "openid"; 27 | 28 | // 访问令牌 29 | public static final String ACCESS_TOKEN = "access_token"; 30 | 31 | // QQ AppId 32 | public static final String OAUTH_CONSUMER_KEY = "oauth_consumer_key"; 33 | } 34 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/dto/IpSourceDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: IP地址信息 12 | * @author: apecode 13 | * @date: 2022-06-10 17:26 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "IP地址信息", description = "用户IP地址信息") 20 | public class IpSourceDto { 21 | 22 | @ApiModelProperty(value = "国家") 23 | private String country; 24 | @ApiModelProperty(value = "省份") 25 | private String province; 26 | @ApiModelProperty(value = "城市") 27 | private String city; 28 | @ApiModelProperty(value = "区域") 29 | private String district; 30 | @ApiModelProperty(value = "经纬度") 31 | private String location; 32 | } 33 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/enums/ArticleStatusEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @description: 文章状态枚举 8 | * @author: apecode 9 | * @date: 2022-06-28 17:26 10 | **/ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum ArticleStatusEnum { 14 | 15 | PUBLIC(1, "公开"), 16 | 17 | PRIVATE(2, "私密"), 18 | 19 | DRAFT(3, "草稿"); 20 | 21 | private final Integer status; 22 | private final String desc; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/enums/ArticleTypeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @description: 文章类型枚举 8 | * @author: apecode 9 | * @date: 2022-06-28 17:31 10 | **/ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum ArticleTypeEnum { 14 | 15 | ORIGINAL(1, "原创"), 16 | 17 | REPRINT(2, "转载"), 18 | 19 | TRANSLATE(3, "翻译"); 20 | 21 | private final Integer type; 22 | private final String desc; 23 | 24 | public static ArticleTypeEnum getArticleTypeEnum(Integer type) { 25 | for (ArticleTypeEnum value : ArticleTypeEnum.values()) { 26 | if (value.getType().equals(type)) { 27 | return value; 28 | } 29 | } 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/enums/CommentTypeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @description: 评论类型枚举 8 | * @author: apecode 9 | * @date: 2022-07-07 21:31 10 | **/ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum CommentTypeEnum { 14 | 15 | ARTICLE(1, "文章", "/article/"), 16 | TALK(2, "说说", "/talk/"); 17 | 18 | // 类型 19 | private final Integer type; 20 | // 描述 21 | private final String desc; 22 | // 路径 23 | private final String path; 24 | 25 | public static CommentTypeEnum getCommentEnum(Integer type) { 26 | for (CommentTypeEnum value : CommentTypeEnum.values()) { 27 | if (value.getType().equals(type)) { 28 | return value; 29 | } 30 | } 31 | return null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/enums/EmailTypeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @description: 邮件类型枚举 8 | * @author: apecode 9 | * @date: 2022-07-13 17:46 10 | **/ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum EmailTypeEnum { 14 | 15 | CODE(1, "验证码"), 16 | COMMENT(2, "评论"), 17 | NOTICE(3, "通知"), 18 | MESSAGE(4, "留言"); 19 | 20 | private final Integer type; 21 | private final String desc; 22 | 23 | public static EmailTypeEnum getMailTypeEnum(Integer type) { 24 | for (EmailTypeEnum value : EmailTypeEnum.values()) { 25 | if (value.getType().equals(type)) { 26 | return value; 27 | } 28 | } 29 | return null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/enums/FilePathEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @description: 文件路径枚举 8 | * @author: apecode 9 | * @date: 2022-06-23 16:41 10 | **/ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum FilePathEnum { 14 | 15 | AVATAR("avatar/", "头像路径"), 16 | ARTICLE("article/", "文章图片路径"), 17 | VOICE("voice/", "音频路径"), 18 | CONFIG("config/", "网站配置路径"), 19 | ALBUM("albums/","相册路径"), 20 | PICTURE_VIDEO("picture_video/", "说说图片视频路径"); 21 | 22 | private final String path; 23 | private final String desc; 24 | } 25 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/enums/LoginTypeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @description: 登录方式枚举 8 | * @author: apecode 9 | * @date: 2022-05-29 20:24 10 | **/ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum LoginTypeEnum { 14 | /** 15 | * 邮箱登录 16 | */ 17 | EMAIL(0, "邮箱登录", ""), 18 | QQ(1, "QQ登录", "qqLoginStrategyImpl"); 19 | 20 | // 登录方式 21 | private final Integer type; 22 | 23 | // 描述 24 | private final String desc; 25 | 26 | // 策略 27 | private final String strategy; 28 | 29 | 30 | public static LoginTypeEnum getLoginTypeEnum(Integer type) { 31 | for (LoginTypeEnum value : LoginTypeEnum.values()) { 32 | if (value.getType().equals(type)) { 33 | return value; 34 | } 35 | } 36 | return null; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/enums/RoleEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @description: 角色枚举 8 | * @author: apecode 9 | * @date: 2022-06-09 23:40 10 | **/ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum RoleEnum { 14 | 15 | /** 16 | * 管理员 17 | */ 18 | ADMIN(1, "管理员", "admin"), 19 | /** 20 | * 普通用户 21 | */ 22 | USER(2, "用户", "user"), 23 | /** 24 | * 测试账号 25 | */ 26 | TEST(3, "测试", "test"); 27 | 28 | /** 29 | * 角色id 30 | */ 31 | private final Integer roleId; 32 | 33 | /** 34 | * 描述 35 | */ 36 | private final String roleDesc; 37 | 38 | /** 39 | * 权限标签 40 | */ 41 | private final String roleAuth; 42 | } 43 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/enums/StatusCodeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @description: 状态码 8 | * @author: apecode 9 | * @date: 2022-05-27 00:25 10 | **/ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum StatusCodeEnum { 14 | 15 | SUCCESS(1000, "成功"), 16 | UNAUTHORIZED(1001, "请登录"), 17 | USERNAME_PASSWORD_ERROR(1002, "用户名或密码错误"), 18 | AUTHORIZED(1003, "无权限"), 19 | EXPIRATION(1004, "登录状态过期,请重新登录"), 20 | EMAIL_EXIST(1005, "此邮箱已被注册"), 21 | EMAIL_NO_EXIST(1006, "此邮箱不存在"), 22 | NICKNAME_EXIST(1007, "昵称已存在"), 23 | DISABLE(1008, "账号被禁用"), 24 | FAIL(1009, "失败"), 25 | VALID_ERROR(1010, "参数不正确"), 26 | ACCESS_LIMIT(1011, "请求过于频繁,请稍后再试"), 27 | QQ_LOGIN_ERROR(1012, "QQ登录错误"), 28 | PAGE_NOT_FOUND(404, "页面不存在"), 29 | SERVER_ERROR(500, "服务器错误"), 30 | BAD_REQUEST(400, "请求错误"); 31 | 32 | /* 33 | * 状态码 34 | * */ 35 | private final Integer code; 36 | /* 37 | * 状态描述 38 | * */ 39 | private final String desc; 40 | } 41 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/enums/UploadModeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @description: 上传模式枚举 8 | * @author: apecode 9 | * @date: 2022-06-23 16:35 10 | **/ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum UploadModeEnum { 14 | 15 | OSS("oss", "ossUploadFileStrategyImpl"), 16 | LOCAL("local", "localUploadFileStrategyImpl"); 17 | private final String mode; 18 | private final String strategy; 19 | 20 | /** 21 | * @description: 获取策略 22 | * @param mode 23 | * @return {@link String} 24 | * @auther apecode 25 | * @date 2022/6/23 16:36 26 | */ 27 | public static String getStrategy(String mode) { 28 | return valueOf(mode.toUpperCase()).getStrategy(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/enums/ZoneEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public enum ZoneEnum { 9 | 10 | SHANGHAI("Asia/Shanghai", "中国上海"); 11 | 12 | /** 13 | * 时区 14 | */ 15 | private final String zone; 16 | 17 | /** 18 | * 描述 19 | */ 20 | private final String desc; 21 | } 22 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/exception/BizException.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.exception; 2 | 3 | import cn.apecode.common.enums.StatusCodeEnum; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | 8 | import static cn.apecode.common.enums.StatusCodeEnum.FAIL; 9 | 10 | /** 11 | * @description: 自定义异常 12 | * @author: apecode 13 | * @date: 2022-05-27 01:08 14 | **/ 15 | @EqualsAndHashCode(callSuper = true) 16 | @Data 17 | @AllArgsConstructor 18 | public class BizException extends RuntimeException { 19 | 20 | /* 21 | * 错误码 22 | * */ 23 | private Integer code = FAIL.getCode(); 24 | 25 | /** 26 | * 错误信息 27 | */ 28 | private String message; 29 | 30 | public BizException(String message) { 31 | this.message = message; 32 | } 33 | 34 | public BizException(StatusCodeEnum statusCodeEnum) { 35 | this.code = statusCodeEnum.getCode(); 36 | this.message = statusCodeEnum.getDesc(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/java/cn/apecode/common/utils/UserUtils.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.common.utils; 2 | 3 | import cn.apecode.common.dto.UserDetailsDto; 4 | import org.springframework.security.core.context.SecurityContextHolder; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * @description: 用户工具类 9 | * @author: apecode 10 | * @date: 2022-05-28 16:08 11 | **/ 12 | @Component 13 | public class UserUtils { 14 | 15 | /** 16 | * @description: 获取当前登录用户 17 | * @param 18 | * @return {@link UserDetailsDto} 19 | * @auther apecode 20 | * @date 2022/5/28 16:08 21 | */ 22 | public static UserDetailsDto getLoginUser() { 23 | return (UserDetailsDto) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /blog-springboot/blog-common/src/main/resources/sensitive_word_allow.txt: -------------------------------------------------------------------------------- 1 | 爆炸 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 | 骚 -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/java/cn/apecode/config/MyBatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.config; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * @description: MyBatis Plus插件配置 11 | * @author: apecode 12 | * @date: 2022-05-26 23:32 13 | **/ 14 | @Configuration 15 | public class MyBatisPlusConfig { 16 | 17 | @Bean 18 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 19 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 20 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MARIADB)); 21 | return interceptor; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/java/cn/apecode/handler/MetaObjectHandlerImpl.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.handler; 2 | 3 | import cn.apecode.common.utils.CommonUtils; 4 | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 5 | import org.apache.ibatis.reflection.MetaObject; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | * @description: mybatis-plus自动填充 12 | * @auther apecode 13 | * @date 2022/5/28 16:53 14 | */ 15 | @Component 16 | public class MetaObjectHandlerImpl implements MetaObjectHandler { 17 | @Override 18 | public void insertFill(MetaObject metaObject) { 19 | this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, CommonUtils.getLocalDateTime()); 20 | } 21 | 22 | @Override 23 | public void updateFill(MetaObject metaObject) { 24 | this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, CommonUtils.getLocalDateTime()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/META-INF/services/com.anji.captcha.service.CaptchaCacheService: -------------------------------------------------------------------------------- 1 | cn.apecode.service.impl.CaptchaCacheServiceRedisImpl -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | profiles: 3 | active: dev -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg1.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg2.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg3.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg4.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg5.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg6.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg7.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg8.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/original/bg9.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/1.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/10.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/11.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/12.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/13.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/14.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/15.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/16.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/17.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/18.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/19.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/8.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/9.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换.zip -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/1.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/2.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/3.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/4.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/5.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/6.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/7.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/2.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/3.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog-springboot/blog-config/src/main/resources/images/jigsaw/slidingBlock/4.png -------------------------------------------------------------------------------- /blog-springboot/blog-config/src/main/resources/log4j2.component.properties: -------------------------------------------------------------------------------- 1 | Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -------------------------------------------------------------------------------- /blog-springboot/blog-crypto/src/main/java/cn/apecode/crypto/annotation/Decrypt.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.crypto.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author apecode. 7 | * @description: 解密注解 8 | * @date 2024/1/18 22:56 9 | */ 10 | @Documented 11 | @Inherited 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.METHOD, ElementType.PARAMETER}) 14 | public @interface Decrypt { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blog-springboot/blog-crypto/src/main/java/cn/apecode/crypto/annotation/Encrypt.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.crypto.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author apecode. 7 | * @description: 解密注解 8 | * @date 2024/1/18 22:56 9 | */ 10 | @Documented 11 | @Inherited 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.METHOD, ElementType.PARAMETER}) 14 | public @interface Encrypt { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blog-springboot/blog-crypto/src/main/java/cn/apecode/crypto/handler/AESKey.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.crypto.handler; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author apecode. 10 | * @description: AES密钥 11 | * @date 2024/1/19 0:10 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Builder 17 | public class AESKey { 18 | 19 | private String key; 20 | private String keyIV; 21 | } 22 | -------------------------------------------------------------------------------- /blog-springboot/blog-crypto/src/main/java/cn/apecode/crypto/handler/RequestDataExtend.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.crypto.handler; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author apecode. 10 | * @description: 请求内容扩展 11 | * @date 2024/1/19 11:38 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Builder 17 | public class RequestDataExtend { 18 | 19 | // 请求体密文 20 | private String data; 21 | 22 | // RSA私钥加密后的AES密文 23 | private String sym; 24 | } 25 | -------------------------------------------------------------------------------- /blog-springboot/blog-crypto/src/main/java/cn/apecode/crypto/handler/RespDataExtend.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.crypto.handler; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author apecode. 10 | * @description: 响应体内容扩展 11 | * @date 2024/1/19 0:04 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Builder 17 | public class RespDataExtend { 18 | 19 | // 响应体密文 20 | private Object body; 21 | 22 | // RSA私钥加密后的AES密文 23 | private String sym; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/ArchiveDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import io.swagger.annotations.ApiModel; 5 | import io.swagger.annotations.ApiModelProperty; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | * @description: 文章归档 15 | * @author: apecode 16 | * @date: 2022-06-28 16:08 17 | **/ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Builder 22 | @ApiModel(value = "文章归档", description = "文章归档") 23 | public class ArchiveDto { 24 | 25 | @ApiModelProperty(value = "文章id", name = "id", dataType = "String") 26 | private String id; 27 | 28 | @ApiModelProperty(value = "文章标题", name = "articleTitle", dataType = "String") 29 | private String articleTitle; 30 | 31 | @ApiModelProperty(value = "创建时间", name = "createTime", dataType = "LocalDateTime") 32 | @JsonFormat(pattern = "YYYY-MM-dd HH:mm:ss") 33 | private LocalDateTime createTime; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/ArchiveMonthDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @description: 文章归档 14 | * @author: apecode 15 | * @date: 2022-11-10 15:08 16 | **/ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Builder 21 | @ApiModel(value = "文章按月归档", description = "文章按月归档") 22 | public class ArchiveMonthDto { 23 | 24 | @ApiModelProperty(value = "月份", name = "month", dataType = "String") 25 | private String month; 26 | 27 | @ApiModelProperty(value = "文章列表", name = "articles", dataType = "List") 28 | private List articles; 29 | } 30 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/ArticleLikeRankDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 文章点赞排行 12 | * @author: apecode 13 | * @date: 2022-07-13 23:26 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "文章点赞排行", description = "文章点赞排行") 20 | public class ArticleLikeRankDto { 21 | 22 | @ApiModelProperty(value = "标题", name = "articleTitle", dataType = "String") 23 | private String articleTitle; 24 | 25 | @ApiModelProperty(value = "点赞量", name = "likeCount", dataType = "Integer") 26 | private Integer likeCount; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/ArticlePaginationDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 文章上下篇 12 | * @author: apecode 13 | * @date: 2022-07-04 23:13 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "文章上下篇", description = "文章上下篇") 20 | public class ArticlePaginationDto { 21 | 22 | @ApiModelProperty(value = "文章id", name = "id", dataType = "String") 23 | private String id; 24 | 25 | @ApiModelProperty(value = "文章标题", name = "articleTitle", dataType = "String") 26 | private String articleTitle; 27 | 28 | @ApiModelProperty(value = "文章缩略图", name = "articleCover", dataType = "String") 29 | private String articleCover; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/ArticleRankDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 文章浏览量排行 12 | * @author: apecode 13 | * @date: 2022-07-13 23:24 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "文章浏览量排行", description = "文章浏览量排行") 20 | public class ArticleRankDto { 21 | 22 | @ApiModelProperty(value = "标题", name = "articleTitle", dataType = "String") 23 | private String articleTitle; 24 | 25 | @ApiModelProperty(value = "浏览量", name = "viewsCount", dataType = "Integer") 26 | private Integer viewsCount; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/ArticleSearchDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 搜索文章 12 | * @author: apecode 13 | * @date: 2022-07-05 16:58 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "搜索文章", description = "搜索文章") 20 | public class ArticleSearchDto { 21 | 22 | @ApiModelProperty(value = "文章id", name = "id", dataType = "String") 23 | private String id; 24 | 25 | @ApiModelProperty(value = "文章标题", name = "articleTitle", dataType = "String") 26 | private String articleTitle; 27 | 28 | @ApiModelProperty(value = "文章内容", name = "articleContent", dataType = "String") 29 | private String articleContent; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/ArticleStatisticsDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 文章贡献统计 12 | * @author: apecode 13 | * @date: 2022-07-13 23:19 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "文章贡献统计", description = "文章贡献统计") 20 | public class ArticleStatisticsDto { 21 | 22 | @ApiModelProperty(value = "日期", name = "date", dataType = "String") 23 | private String date; 24 | 25 | @ApiModelProperty(value = "数量", name = "count", dataType = "Integer") 26 | private Integer count; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/CategoryArticleCountDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | @Builder 14 | @ApiModel(value = "分类文章数量", description = "分类文章数量") 15 | public class CategoryArticleCountDto { 16 | 17 | @ApiModelProperty(value = "id", name = "id", dataType = "String") 18 | private String id; 19 | 20 | @ApiModelProperty(value = "分类名称", name = "name", dataType = "String") 21 | private String name; 22 | 23 | @ApiModelProperty(value = "文章数量", name = "articleCount", dataType = "Integer") 24 | private Integer articleCount; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/CategoryOptionDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 12 | * @author: apecode 13 | * @date: 2022-06-26 19:03 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "分类选项", description = "分类选项") 20 | public class CategoryOptionDto { 21 | 22 | @ApiModelProperty(value = "分类id", name = "id", dataType = "String") 23 | private String id; 24 | 25 | @ApiModelProperty(value = "分类名称", name = "name", dataType = "String") 26 | private String name; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/CategorySearchDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 分类搜索结果 12 | * @author: apecode 13 | * @date: 2022-07-05 17:01 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "分类搜索结果", description = "分类搜索结果") 20 | public class CategorySearchDto { 21 | 22 | @ApiModelProperty(value = "分类id", name = "id", dataType = "String") 23 | private String id; 24 | 25 | @ApiModelProperty(value = "分类名称", name = "name", dataType = "String") 26 | private String name; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/DiskInfoDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 硬盘信息 12 | * @author: apecode 13 | * @date: 2022-08-24 01:57 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "硬盘信息", description = "硬盘信息") 20 | public class DiskInfoDto { 21 | 22 | @ApiModelProperty(value = "路径", name = "path") 23 | private String path; 24 | @ApiModelProperty(value = "空闲空间", name = "free") 25 | private String free; 26 | @ApiModelProperty(value = "可用空间", name = "use") 27 | private String use; 28 | @ApiModelProperty(value = "总空间", name = "total") 29 | private String total; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/LabelOptionDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @description: 标签选项 14 | * @author: apecode 15 | * @date: 2022-06-17 23:18 16 | **/ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | @Builder 21 | @ApiModel(value = "标签选项", description = "返回前端下拉选项") 22 | public class LabelOptionDto { 23 | 24 | @ApiModelProperty(value = "选项id", name = "id", dataType = "String") 25 | private String id; 26 | 27 | @ApiModelProperty(value = "选项名", name = "label", dataType = "String") 28 | private String label; 29 | 30 | @ApiModelProperty(value = "子选项", name = "children", dataType = "List") 31 | private List children; 32 | } 33 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/MemoryInfoDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 系统内存 12 | * @author: apecode 13 | * @date: 2022-08-24 01:27 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "系统内存", description = "系统内存") 20 | public class MemoryInfoDto { 21 | 22 | @ApiModelProperty(value = "总内存", name = "total") 23 | private String total; 24 | @ApiModelProperty(value = "可用内存", name = "available") 25 | private String available; 26 | @ApiModelProperty(value = "已用内存", name = "used") 27 | private String used; 28 | @ApiModelProperty(value = "内存使用率", name = "ute") 29 | private String ute; 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/PhotoAlbumPictureCountDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 相册图片的数量 12 | * @author: apecode 13 | * @date: 2023-07-22 18:05 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "相册图片的数量", description = "相册图片的数量") 20 | public class PhotoAlbumPictureCountDto { 21 | 22 | @ApiModelProperty(value = "相册id", name = "albumId", dataType = "Integer") 23 | private Integer albumId; 24 | @ApiModelProperty(value = "图片数量", name = "count", dataType = "Integer") 25 | private Integer count; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/QQTokenDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModelProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | /** 10 | * @description: qq token信息 11 | * @author: apecode 12 | * @date: 2023-01-05 13:34 13 | **/ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder 18 | public class QQTokenDto { 19 | 20 | @ApiModelProperty(value = "openId", name = "openid", dataType = "String") 21 | private String openid; 22 | 23 | @ApiModelProperty(value = "clientId", name = "client_id", dataType = "String") 24 | private String client_id; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/QQUserInfoDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModelProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | /** 10 | * @description: QQ用户信息 11 | * @author: apecode 12 | * @date: 2023-01-05 14:22 13 | **/ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder 18 | public class QQUserInfoDto { 19 | 20 | @ApiModelProperty(value = "用户昵称", name = "nickname", dataType = "String") 21 | private String nickname; 22 | 23 | @ApiModelProperty(value = "用户QQ头像", name = "figureurl_qq_1", dataType = "String") 24 | private String figureurl_qq_2; 25 | } 26 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/ReplyCountDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 回复数量 12 | * @author: apecode 13 | * @date: 2022-07-09 00:38 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "回复数量", description = "回复数量") 20 | public class ReplyCountDto { 21 | 22 | @ApiModelProperty(value = "评论id", name = "commentId", dataType = "String") 23 | private String commentId; 24 | 25 | @ApiModelProperty(value = "回复数量", name = "replyCount", dataType = "Integer") 26 | private Integer replyCount; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/RoleResourceDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @description: 14 | * @author: apecode 15 | * @date: 2022-05-28 19:32 16 | **/ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Builder 21 | @ApiModel(value = "角色资源", description = "角色对应的资源") 22 | public class RoleResourceDto { 23 | 24 | @ApiModelProperty(value = "资源id", dataType = "String") 25 | private Integer id; 26 | 27 | @ApiModelProperty(value = "路径", dataType = "String") 28 | private String url; 29 | 30 | @ApiModelProperty(value = "请求方式", dataType = "String") 31 | private String requestMethod; 32 | 33 | @ApiModelProperty(value = "角色名", dataType = "List") 34 | private List roleList; 35 | } 36 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/SocialTokenDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModelProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | /** 10 | * @description: 社交登录Token 11 | * @author: apecode 12 | * @date: 2023-01-04 22:38 13 | **/ 14 | 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | public class SocialTokenDto { 20 | 21 | @ApiModelProperty(value = "开放id", name = "openId", dataType = "String") 22 | private String openId; 23 | 24 | @ApiModelProperty(value = "访问令牌", name = "accessToken", dataType = "String") 25 | private String accessToken; 26 | 27 | @ApiModelProperty(value = "登录类型", name = "loginType", dataType = "Integer") 28 | private Integer loginType; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/SocialUserInfoDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModelProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | /** 10 | * @description: 社交账号信息 11 | * @author: apecode 12 | * @date: 2023-01-05 11:06 13 | **/ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder 18 | public class SocialUserInfoDto { 19 | 20 | @ApiModelProperty(value = "用户昵称", name = "nickname", dataType = "String") 21 | private String nickname; 22 | 23 | @ApiModelProperty(value = "用户头像", name = "avatar", dataType = "String") 24 | private String avatar; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/TagDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 标签 12 | * @author: apecode 13 | * @date: 2022-06-25 17:40 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "标签", description = "标签") 20 | public class TagDto { 21 | 22 | @ApiModelProperty(value = "标签id", name = "id", dataType = "String") 23 | private String id; 24 | 25 | @ApiModelProperty(value = "标签名称", name = "name", dataType = "String") 26 | private String name; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/TagFrontDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @description: 前台标签 14 | * @author: apecode 15 | * @date: 2022-07-04 18:06 16 | **/ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Builder 21 | @ApiModel(value = "前台标签", description = "前台标签展示") 22 | public class TagFrontDto { 23 | 24 | @ApiModelProperty(value = "标签列表 ", name = "tags", dataType = "List") 25 | private List tags; 26 | 27 | @ApiModelProperty(value = "最新文章列表", name = "newsArticleList", dataType = "List") 28 | private List newsArticleList; 29 | 30 | @ApiModelProperty(value = "最新评论列表", name = "newsCommentList", dataType = "List") 31 | private List newsCommentList; 32 | } 33 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/TagSearchDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 标签搜索结果 12 | * @author: apecode 13 | * @date: 2022-07-05 17:11 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "标签搜索结果", description = "标签搜索结果") 20 | public class TagSearchDto { 21 | 22 | @ApiModelProperty(value = "标签id", name = "id", dataType = "String") 23 | private String id; 24 | 25 | @ApiModelProperty(value = "标签名称", name = "name", dataType = "String") 26 | private String name; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/TagWithArticleCountDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 标签 12 | * @author: apecode 13 | * @date: 2023-03-20 13:53 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "带有文章数量的标签", description = "带有文章数量的标签") 20 | public class TagWithArticleCountDto { 21 | 22 | @ApiModelProperty(value = "标签id", name = "id", dataType = "String") 23 | private String id; 24 | 25 | @ApiModelProperty(value = "标签名称", name = "name", dataType = "String") 26 | private String name; 27 | 28 | @ApiModelProperty(value = "文章数量", name = "articleCount", dataType = "Integer") 29 | private Integer articleCount; 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/TalkPictureVideoDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | @Builder 14 | @ApiModel(value = "后台说说配图", description = "后台说说配图") 15 | public class TalkPictureVideoDto { 16 | 17 | @ApiModelProperty(value = "配图id", name = "id", dataType = "String") 18 | private String id; 19 | 20 | @ApiModelProperty(value = "配图地址", name = "src", dataType = "String") 21 | private String src; 22 | 23 | @ApiModelProperty(value = "配图名称", name = "fileName", dataType = "String") 24 | private String fileName; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/UserRoleDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.experimental.Accessors; 10 | 11 | /** 12 | * @description: 用户角色 13 | * @author: apecode 14 | * @date: 2022-06-09 11:42 15 | **/ 16 | @Data 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | @Accessors(chain = true) 20 | @Builder 21 | @ApiModel(value = "用户角色", description = "返回用户角色信息") 22 | public class UserRoleDto { 23 | 24 | @ApiModelProperty(value = "角色id", dataType = "String") 25 | private String id; 26 | 27 | @ApiModelProperty(value = "角色描述", dataType = "String") 28 | private String roleDesc; 29 | } 30 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/UserVisitAreaStatisticsDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 用户访问地区统计 12 | * @author: apecode 13 | * @date: 2022-07-13 23:51 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "用户访问地区统计", description = "用户访问地区统计") 20 | public class UserVisitAreaStatisticsDto { 21 | 22 | @ApiModelProperty(value = "区域", name = "area", dataType = "String") 23 | private String area; 24 | 25 | @ApiModelProperty(value = "数量", name = "count", dataType = "Integer") 26 | private Integer count; 27 | } 28 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/dto/VisitStatisticsDto.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.dto; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @description: 访问量统计 12 | * @author: apecode 13 | * @date: 2022-07-13 23:22 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "用户访问量统计", description = "用户访问量统计") 20 | public class VisitStatisticsDto { 21 | 22 | @ApiModelProperty(value = "日期", name = "date", dataType = "String") 23 | private String date; 24 | 25 | @ApiModelProperty(value = "浏览量", name = "viewsCount", dataType = "Integer") 26 | private Integer viewsCount; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/CategoryVo.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotBlank; 11 | 12 | /** 13 | * @description: 分类 14 | * @author: apecode 15 | * @date: 2022-06-26 16:27 16 | **/ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Builder 21 | @ApiModel(value = "分类", description = "分类") 22 | public class CategoryVo { 23 | 24 | @ApiModelProperty(name = "categoryId", value = "分类id", dataType = "String") 25 | private String categoryId; 26 | 27 | @NotBlank(message = "分类名不能为空") 28 | @ApiModelProperty(name = "name", value = "分类名", dataType = "String", required = true) 29 | private String name; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/DeleteVo.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotNull; 11 | import java.util.List; 12 | 13 | /** 14 | * @description: 逻辑删除 15 | * @author: apecode 16 | * @date: 2022-06-24 00:25 17 | **/ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Builder 22 | @ApiModel(value = "逻辑删除", description = "逻辑删除") 23 | public class DeleteVo { 24 | 25 | @NotNull(message = "id不能为空") 26 | @ApiModelProperty(name = "idList", value = "id列表", required = true, dataType = "List") 27 | private List idList; 28 | 29 | @NotNull(message = "状态不能为空") 30 | @ApiModelProperty(name = "isDelete", value = "状态", required = true, dataType = "Boolean") 31 | private Boolean isDelete; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/MessageVo.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotBlank; 11 | 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | @Builder 16 | @ApiModel(value = "留言", description = "添加留言") 17 | public class MessageVo { 18 | 19 | @NotBlank(message = "留言内容不能为空") 20 | @ApiModelProperty(name = "content", value = "留言内容", dataType = "String") 21 | private String content; 22 | @ApiModelProperty(name = "theme", value = "主题", dataType = "String") 23 | private String theme; 24 | } 25 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/PageResult.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @description: 分页对象 14 | * @author: apecode 15 | * @date: 2022-06-09 09:30 16 | **/ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Builder 21 | @ApiModel(value = "分页Vo", description = "分页对象") 22 | public class PageResult { 23 | 24 | @ApiModelProperty(name = "recordList", value = "分页列表", dataType = "List") 25 | private List recordList; 26 | 27 | @ApiModelProperty(name = "count", value = "总数", dataType = "Integer") 28 | private Integer count; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/PageResultWithObject.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | @NoArgsConstructor 10 | @ApiModel(value = "带有其他数据的页面结果", description = "带有其他数据的页面结果") 11 | public class PageResultWithObject extends PageResult { 12 | 13 | public PageResultWithObject(List recordList, Integer count, E data) { 14 | super(recordList, count); 15 | this.data = data; 16 | } 17 | 18 | public E getData() { 19 | return data; 20 | } 21 | 22 | public void setData(E data) { 23 | this.data = data; 24 | } 25 | 26 | @ApiModelProperty(name = "name", value = "数据", dataType = "E") 27 | private E data; 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/PictureInfoVo.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotBlank; 11 | import javax.validation.constraints.NotNull; 12 | 13 | /** 14 | * @description: 图片信息 15 | * @author: apecode 16 | * @date: 2022-06-23 23:55 17 | **/ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Builder 22 | @ApiModel(value = "图片信息", description = "图片信息") 23 | public class PictureInfoVo { 24 | 25 | @NotNull(message = "图片路径不能为空") 26 | @ApiModelProperty(name = "picturePath", value = "图片路径", required = true, dataType = "String") 27 | private String picturePath; 28 | 29 | @NotBlank(message = "图片名称不能为空") 30 | @ApiModelProperty(name = "pictureName", value = "图片名称", required = true, dataType = "String") 31 | private String pictureName; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/QQLoginVo.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotBlank; 11 | 12 | /** 13 | * @description: QQ登录 14 | * @author: apecode 15 | * @date: 2023-01-05 12:15 16 | **/ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Builder 21 | @ApiModel(value = "QQ登录信息", description = "QQ登录信息") 22 | public class QQLoginVo { 23 | 24 | @NotBlank(message = "openId不能为空") 25 | @ApiModelProperty(name = "openId", value = "qq openId", dataType = "String") 26 | private String openId; 27 | 28 | @NotBlank(message = "accessToken不能为空") 29 | @ApiModelProperty(name = "accessToken", value = "qq accessToken", dataType = "String") 30 | private String accessToken; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/ReviewVo.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotNull; 11 | import java.util.List; 12 | 13 | /** 14 | * @description: 审核 15 | * @author: apecode 16 | * @date: 2022-06-24 18:39 17 | **/ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Builder 22 | @ApiModel(value = "审核", description = "审核留言和评论") 23 | public class ReviewVo { 24 | 25 | @ApiModelProperty(name = "idList", value = "id列表", required = true, dataType = "List") 26 | private List idList; 27 | 28 | @NotNull(message = "状态值不能为空") 29 | @ApiModelProperty(name = "isReview", value = "审核状态", required = true, dataType = "Boolean") 30 | private Boolean isReview; 31 | 32 | @ApiModelProperty(name = "remark", value = "备注", dataType = "String") 33 | private String remark; 34 | } 35 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/TagVo.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotBlank; 11 | import javax.validation.constraints.Size; 12 | 13 | /** 14 | * @description: 标签 15 | * @author: apecode 16 | * @date: 2022-06-26 00:05 17 | **/ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Builder 22 | @ApiModel(value = "标签", description = "修改标签") 23 | public class TagVo { 24 | 25 | @ApiModelProperty(name = "id", value = "标签id", dataType = "String", required = true) 26 | private String id; 27 | 28 | @NotBlank(message = "标签名不能为空") 29 | @Size(max = 20, message = "最多20个字") 30 | @ApiModelProperty(name = "name", value = "标签名称", dataType = "String", required = true) 31 | private String name; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/TopVo.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotNull; 11 | 12 | /** 13 | * @description: 置顶 14 | * @author: apecode 15 | * @date: 2022-06-28 15:22 16 | **/ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Builder 21 | @ApiModel(value = "置顶", description = "置顶") 22 | public class TopVo { 23 | 24 | @NotNull(message = "id不能为空") 25 | @ApiModelProperty(name = "id", value = "id", dataType = "String", required = true) 26 | private String id; 27 | 28 | @NotNull(message = "置顶状态不能为空") 29 | @ApiModelProperty(name = "isTop", value = "置顶状态", dataType = "Boolean", required = true) 30 | private Boolean isTop; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/UserEnableVo.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotNull; 11 | 12 | /** 13 | * @description: 用户禁用状态 14 | * @author: apecode 15 | * @date: 2022-06-14 21:20 16 | **/ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Builder 21 | @ApiModel(value = "用户状态", description = "用户状态") 22 | public class UserEnableVo { 23 | 24 | @ApiModelProperty(name = "id", value = "用户id", required = true, dataType = "String") 25 | @NotNull(message = "用户id不能为空") 26 | private String id; 27 | 28 | @ApiModelProperty(name = "enable", value = "是否开启", required = true, dataType = "Boolean") 29 | @NotNull(message = "是否启用?") 30 | private Boolean enable; 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/blog-pojo/src/main/java/cn/apecode/vo/UserRoleVo.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.vo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotNull; 11 | import java.util.List; 12 | 13 | /** 14 | * @description: 用户角色 15 | * @author: apecode 16 | * @date: 2022-06-14 22:44 17 | **/ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Builder 22 | @ApiModel(value = "用户角色", description = "用户角色") 23 | public class UserRoleVo { 24 | 25 | @NotNull(message = "用户id不能为空") 26 | @ApiModelProperty(name = "userId", value = "用户id", required = true, dataType = "String") 27 | private String userId; 28 | 29 | @NotNull(message = "用户角色不能为空") 30 | @ApiModelProperty(name = "roleList", value = "角色id集合", dataType = "List") 31 | private List roleList; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/ArticleTagMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.dto.TagWithArticleCountDto; 4 | import cn.apecode.entity.ArticleTag; 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 | import org.apache.ibatis.annotations.Mapper; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | *

12 | * 文章所属标签 Mapper 接口 13 | *

14 | * 15 | * @author apecode 16 | * @since 2022-05-26 17 | */ 18 | @Mapper 19 | public interface ArticleTagMapper extends BaseMapper { 20 | 21 | /** 22 | * @description: 获取前台标签及文章数量 23 | * @param 24 | * @return {@link List} 25 | * @auther apecode 26 | * @date 20/3/2023 PM1:37 27 | */ 28 | List listTagFront(); 29 | } 30 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/DailyVisitMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.dto.VisitStatisticsDto; 4 | import cn.apecode.entity.DailyVisit; 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 日均访问量 Mapper 接口 14 | *

15 | * 16 | * @author apecode 17 | * @since 2022-05-26 18 | */ 19 | @Mapper 20 | public interface DailyVisitMapper extends BaseMapper { 21 | 22 | /** 23 | * @description: 用户几天访问量统计列表 24 | * @param day 25 | * @return {@link List} 26 | * @auther apecode 27 | * @date 2022/7/14 0:24 28 | */ 29 | List listAFewDaysVisit(@Param("day") int day); 30 | } 31 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/LoginLogMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.dto.LoginLogBackDto; 4 | import cn.apecode.entity.LoginLog; 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 登录日志 Mapper 接口 14 | *

15 | * 16 | * @author apecode 17 | * @since 2022-05-26 18 | */ 19 | @Mapper 20 | public interface LoginLogMapper extends BaseMapper { 21 | 22 | /** 23 | * @description: 获取登录日志 24 | * @param limitCurrent 25 | * @param size 26 | * @return {@link List} 27 | * @auther apecode 28 | * @date 2022/7/10 16:48 29 | */ 30 | List listLoginLog(@Param("current") Long limitCurrent, @Param("size") Long size); 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/LoginQqMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.entity.LoginQq; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * QQ登录 Mapper 接口 10 | *

11 | * 12 | * @author apecode 13 | * @since 2023-01-05 14 | */ 15 | @Mapper 16 | public interface LoginQqMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/MailLogMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.dto.MailLogBackDto; 4 | import cn.apecode.entity.MailLog; 5 | import cn.apecode.vo.ConditionVo; 6 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 7 | import org.apache.ibatis.annotations.Mapper; 8 | import org.apache.ibatis.annotations.Param; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | *

14 | * 邮件发送记录 Mapper 接口 15 | *

16 | * 17 | * @author apecode 18 | * @since 2022-05-26 19 | */ 20 | @Mapper 21 | public interface MailLogMapper extends BaseMapper { 22 | 23 | /** 24 | * @param limitCurrent 25 | * @param size 26 | * @param condition 27 | * @return {@link List} 28 | * @description: 获取邮件日志 29 | * @auther apecode 30 | * @date 2022/7/13 19:05 31 | */ 32 | List listMailLog(@Param("current") Long limitCurrent, @Param("size") Long size, @Param("condition") ConditionVo condition); 33 | } 34 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/MenuMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.entity.Menu; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Param; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | *

12 | * 后台菜单 Mapper 接口 13 | *

14 | * 15 | * @author apecode 16 | * @since 2022-05-26 17 | */ 18 | @Mapper 19 | public interface MenuMapper extends BaseMapper { 20 | 21 | /** 22 | * @description: 根据用户id获取菜单 23 | * @param id 24 | * @return {@link List} 25 | * @auther apecode 26 | * @date 2022/6/6 21:13 27 | */ 28 | List listUserMenusByUserId(@Param("id") Integer id); 29 | } 30 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/OperationLogMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.dto.OperationLogBackDto; 4 | import cn.apecode.entity.OperationLog; 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 操作记录 Mapper 接口 14 | *

15 | * 16 | * @author apecode 17 | * @since 2022-05-26 18 | */ 19 | @Mapper 20 | public interface OperationLogMapper extends BaseMapper { 21 | 22 | /** 23 | * @description: 获取操作日志 24 | * @param limitCurrent 25 | * @param size 26 | * @return {@link List} 27 | * @auther apecode 28 | * @date 2022/7/10 16:23 29 | */ 30 | List listOperationLog(@Param("current") Long limitCurrent, @Param("size") Long size); 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/ResourceMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.entity.Resource; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 资源信息 Mapper 接口 10 | *

11 | * 12 | * @author apecode 13 | * @since 2022-05-26 14 | */ 15 | @Mapper 16 | public interface ResourceMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/RoleMenuMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.entity.RoleMenu; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 菜单角色权限 Mapper 接口 10 | *

11 | * 12 | * @author apecode 13 | * @since 2022-05-26 14 | */ 15 | @Mapper 16 | public interface RoleMenuMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/RoleResourceMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.entity.RoleResource; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 资源角色权限 Mapper 接口 10 | *

11 | * 12 | * @author apecode 13 | * @since 2022-05-26 14 | */ 15 | @Mapper 16 | public interface RoleResourceMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/TalkPictureVideoMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.entity.TalkPictureVideo; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 说说的图片和视频 Mapper 接口 10 | *

11 | * 12 | * @author apecode 13 | * @since 2022-07-06 14 | */ 15 | @Mapper 16 | public interface TalkPictureVideoMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/UserInfoMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.entity.UserInfo; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 用户信息 Mapper 接口 10 | *

11 | * 12 | * @author apecode 13 | * @since 2022-05-26 14 | */ 15 | @Mapper 16 | public interface UserInfoMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/UserRoleMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.entity.UserRole; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 用户权限 Mapper 接口 10 | *

11 | * 12 | * @author apecode 13 | * @since 2022-05-26 14 | */ 15 | @Mapper 16 | public interface UserRoleMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/mapper/WebsiteMapper.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.mapper; 2 | 3 | import cn.apecode.entity.Website; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 博客设置 Mapper 接口 10 | *

11 | * 12 | * @author apecode 13 | * @since 2022-05-26 14 | */ 15 | @Mapper 16 | public interface WebsiteMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/ArticleTagService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service; 2 | 3 | import cn.apecode.entity.ArticleTag; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 文章所属标签 服务类 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | public interface ArticleTagService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/DailyVisitService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service; 2 | 3 | import cn.apecode.entity.DailyVisit; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 日均访问量 服务类 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | public interface DailyVisitService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/LoginLogService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service; 2 | 3 | import cn.apecode.dto.LoginLogBackDto; 4 | import cn.apecode.entity.LoginLog; 5 | import cn.apecode.vo.DeleteVo; 6 | import cn.apecode.vo.PageResult; 7 | import com.baomidou.mybatisplus.extension.service.IService; 8 | 9 | /** 10 | *

11 | * 登录日志 服务类 12 | *

13 | * 14 | * @author apecode 15 | * @since 2022-05-26 16 | */ 17 | public interface LoginLogService extends IService { 18 | 19 | /** 20 | * @description: 获取登录日志 21 | * @return {@link PageResult} 22 | * @auther apecode 23 | * @date 2022/7/10 16:46 24 | */ 25 | PageResult listLoginLog(); 26 | 27 | /** 28 | * @description: 删除登录日志 29 | * @param delete 30 | * @auther apecode 31 | * @date 2022/7/10 16:55 32 | */ 33 | void deleteLoginLog(DeleteVo delete); 34 | } 35 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/LoginQqService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service; 2 | 3 | import cn.apecode.entity.LoginQq; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * QQ登录 服务类 9 | *

10 | * 11 | * @author apecode 12 | * @since 2023-01-05 13 | */ 14 | public interface LoginQqService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/MailLogService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service; 2 | 3 | import cn.apecode.dto.MailLogBackDto; 4 | import cn.apecode.entity.MailLog; 5 | import cn.apecode.vo.ConditionVo; 6 | import cn.apecode.vo.DeleteVo; 7 | import cn.apecode.vo.PageResult; 8 | import com.baomidou.mybatisplus.extension.service.IService; 9 | 10 | /** 11 | *

12 | * 邮件发送记录 服务类 13 | *

14 | * 15 | * @author apecode 16 | * @since 2022-05-26 17 | */ 18 | public interface MailLogService extends IService { 19 | 20 | /** 21 | * @description: 获取邮件日志 22 | * @param condition 23 | * @return {@link PageResult} 24 | * @auther apecode 25 | * @date 2022/7/13 19:17 26 | */ 27 | PageResult listMailLog(ConditionVo condition); 28 | 29 | /** 30 | * @description: 删除邮件日志 31 | * @param delete 32 | * @auther apecode 33 | * @date 2022/7/13 19:47 34 | */ 35 | void deleteMailLog(DeleteVo delete); 36 | } 37 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/OperationLogService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service; 2 | 3 | import cn.apecode.dto.OperationLogBackDto; 4 | import cn.apecode.entity.OperationLog; 5 | import cn.apecode.vo.DeleteVo; 6 | import cn.apecode.vo.PageResult; 7 | import com.baomidou.mybatisplus.extension.service.IService; 8 | 9 | /** 10 | *

11 | * 操作记录 服务类 12 | *

13 | * 14 | * @author apecode 15 | * @since 2022-05-26 16 | */ 17 | public interface OperationLogService extends IService { 18 | 19 | /** 20 | * @description: 获取操作日志 21 | * @return {@link PageResult} 22 | * @auther apecode 23 | * @date 2022/7/10 16:14 24 | */ 25 | PageResult listOperationLog(); 26 | 27 | /** 28 | * @description: 删除操作日志 29 | * @param delete 30 | * @auther apecode 31 | * @date 2022/7/10 16:33 32 | */ 33 | void deleteOperationLog(DeleteVo delete); 34 | } 35 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/RoleMenuService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service; 2 | 3 | import cn.apecode.entity.RoleMenu; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 菜单角色权限 服务类 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | public interface RoleMenuService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/RoleResourceService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service; 2 | 3 | import cn.apecode.entity.RoleResource; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 资源角色权限 服务类 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | public interface RoleResourceService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/TalkPictureVideoService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service; 2 | 3 | import cn.apecode.entity.TalkPictureVideo; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 说说的图片和视频 服务类 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-07-06 13 | */ 14 | public interface TalkPictureVideoService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/UserRoleService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service; 2 | 3 | import cn.apecode.entity.UserRole; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 用户权限 服务类 9 | *

10 | * 11 | * @author apecode 12 | * @since 2022-05-26 13 | */ 14 | public interface UserRoleService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/impl/ArticleTagServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service.impl; 2 | 3 | import cn.apecode.entity.ArticleTag; 4 | import cn.apecode.mapper.ArticleTagMapper; 5 | import cn.apecode.service.ArticleTagService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 文章所属标签 服务实现类 12 | *

13 | * 14 | * @author apecode 15 | * @since 2022-05-26 16 | */ 17 | @Service 18 | public class ArticleTagServiceImpl extends ServiceImpl implements ArticleTagService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/impl/DailyVisitServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service.impl; 2 | 3 | import cn.apecode.entity.DailyVisit; 4 | import cn.apecode.mapper.DailyVisitMapper; 5 | import cn.apecode.service.DailyVisitService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 日均访问量 服务实现类 12 | *

13 | * 14 | * @author apecode 15 | * @since 2022-05-26 16 | */ 17 | @Service 18 | public class DailyVisitServiceImpl extends ServiceImpl implements DailyVisitService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/impl/LoginQqServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service.impl; 2 | 3 | import cn.apecode.entity.LoginQq; 4 | import cn.apecode.mapper.LoginQqMapper; 5 | import cn.apecode.service.LoginQqService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * QQ登录 服务实现类 12 | *

13 | * 14 | * @author apecode 15 | * @since 2023-01-05 16 | */ 17 | @Service 18 | public class LoginQqServiceImpl extends ServiceImpl implements LoginQqService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/impl/RoleMenuServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service.impl; 2 | 3 | import cn.apecode.entity.RoleMenu; 4 | import cn.apecode.mapper.RoleMenuMapper; 5 | import cn.apecode.service.RoleMenuService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 菜单角色权限 服务实现类 12 | *

13 | * 14 | * @author apecode 15 | * @since 2022-05-26 16 | */ 17 | @Service 18 | public class RoleMenuServiceImpl extends ServiceImpl implements RoleMenuService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/impl/RoleResourceServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service.impl; 2 | 3 | import cn.apecode.entity.RoleResource; 4 | import cn.apecode.mapper.RoleResourceMapper; 5 | import cn.apecode.service.RoleResourceService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 资源角色权限 服务实现类 12 | *

13 | * 14 | * @author apecode 15 | * @since 2022-05-26 16 | */ 17 | @Service 18 | public class RoleResourceServiceImpl extends ServiceImpl implements RoleResourceService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/impl/TalkPictureVideoServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service.impl; 2 | 3 | import cn.apecode.entity.TalkPictureVideo; 4 | import cn.apecode.mapper.TalkPictureVideoMapper; 5 | import cn.apecode.service.TalkPictureVideoService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 说说的图片和视频 服务实现类 12 | *

13 | * 14 | * @author apecode 15 | * @since 2022-07-06 16 | */ 17 | @Service 18 | public class TalkPictureVideoServiceImpl extends ServiceImpl implements TalkPictureVideoService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/service/impl/UserRoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.service.impl; 2 | 3 | import cn.apecode.entity.UserRole; 4 | import cn.apecode.mapper.UserRoleMapper; 5 | import cn.apecode.service.UserRoleService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 用户权限 服务实现类 12 | *

13 | * 14 | * @author apecode 15 | * @since 2022-05-26 16 | */ 17 | @Service 18 | public class UserRoleServiceImpl extends ServiceImpl implements UserRoleService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/strategy/SocialLoginStrategy.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.strategy; 2 | 3 | import cn.apecode.dto.UserInfoDto; 4 | 5 | /** 6 | * @description: 第三方登录策略 7 | * @author: apecode 8 | * @date: 2023-01-04 21:57 9 | **/ 10 | public interface SocialLoginStrategy { 11 | 12 | /** 13 | * 登录 14 | * @param data 15 | * @return {@link UserInfoDto} 16 | */ 17 | UserInfoDto login(String data); 18 | } 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/strategy/UploadFileStrategy.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.strategy; 2 | 3 | import cn.apecode.dto.UploadFileInfoDto; 4 | import org.springframework.web.multipart.MultipartFile; 5 | 6 | /** 7 | * @description: 上传接口 8 | * @author: apecode 9 | * @date: 2022-06-23 16:16 10 | **/ 11 | public interface UploadFileStrategy { 12 | 13 | /** 14 | * @description: 上传文件 15 | * @param file 16 | * @param path 17 | * @return {@link String} 18 | * @auther apecode 19 | * @date 2022/6/23 16:17 20 | */ 21 | UploadFileInfoDto uploadFile(MultipartFile file, String path); 22 | 23 | /** 24 | * @description: 删除文件 25 | * @param path 26 | * @return {@link Boolean} 27 | * @auther apecode 28 | * @date 2022/7/7 12:54 29 | */ 30 | Boolean deleteFile(String path); 31 | } 32 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/strategy/context/SocialLoginStrategyContext.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.strategy.context; 2 | 3 | import cn.apecode.common.enums.LoginTypeEnum; 4 | import cn.apecode.dto.UserInfoDto; 5 | import cn.apecode.strategy.SocialLoginStrategy; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.Map; 10 | 11 | /** 12 | * @description: 第三方登录策略上下文 13 | * @author: apecode 14 | * @date: 2023-01-05 13:49 15 | **/ 16 | @Service 17 | public class SocialLoginStrategyContext { 18 | 19 | @Resource 20 | private Map socialLoginStrategyMap; 21 | 22 | /** 23 | * @description: 执行第三方登录策略 24 | * @param data 25 | * @param loginTypeEnum 26 | * @return {@link UserInfoDto} 27 | * @auther apecode 28 | * @date 2023/1/5 13:55 29 | */ 30 | public UserInfoDto executeLoginStrategy(String data, LoginTypeEnum loginTypeEnum) { 31 | return socialLoginStrategyMap.get(loginTypeEnum.getStrategy()).login(data); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/utils/OSSConfigYml.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.utils; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * @description: oss配置属性 9 | * @author: apecode 10 | * @date: 2022-06-23 16:13 11 | **/ 12 | @Data 13 | @Configuration 14 | @ConfigurationProperties(prefix = "upload.oss") 15 | public class OSSConfigYml { 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 | } 42 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/java/cn/apecode/utils/QQConfigYml.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.utils; 2 | 3 | import io.swagger.annotations.ApiModelProperty; 4 | import lombok.Data; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * @description: qq配置属性 10 | * @author: apecode 11 | * @date: 2023-01-05 12:56 12 | **/ 13 | @Data 14 | @Configuration 15 | @ConfigurationProperties(prefix = "qq") 16 | public class QQConfigYml { 17 | 18 | @ApiModelProperty(value = "QQ appId") 19 | private String appId; 20 | 21 | @ApiModelProperty(value = "校验token地址") 22 | private String checkTokenUrl; 23 | 24 | @ApiModelProperty(value = "QQ用户信息地址") 25 | private String userInfoUrl; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/resources/mapper/LoginQqMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | id, openId, userAuthId 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/resources/mapper/RoleMenuMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | id, roleId, menuId, createTime, updateTime 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/resources/mapper/RoleResourceMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | id, roleId, resourceId, createTime, updateTime 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/resources/mapper/TalkPictureVideoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | id, talkId, src, fileName, orderNum, createTime, updateTime 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/resources/mapper/UserRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | id, userId, roleId, createTime, updateTime 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /blog-springboot/blog-service/src/main/resources/mapper/WebsiteMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | id, config, createTime, updateTime 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /blog-springboot/blog-websocket/src/main/java/cn/apecode/websocket/config/WebSocketHandshakeHandler.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.websocket.config; 2 | 3 | import org.springframework.http.server.ServerHttpRequest; 4 | import org.springframework.web.socket.WebSocketHandler; 5 | import org.springframework.web.socket.server.support.DefaultHandshakeHandler; 6 | 7 | import java.security.Principal; 8 | import java.util.Map; 9 | 10 | /** 11 | * @author apecode 12 | * @description WebSocket的握手之后拦截器 13 | * @date 1/7/2023 PM12:46 14 | */ 15 | public class WebSocketHandshakeHandler extends DefaultHandshakeHandler { 16 | 17 | @Override 18 | protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map attributes) { 19 | // 设置认证用户 20 | return (Principal) attributes.get("user"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /blog-springboot/blog-websocket/src/main/java/cn/apecode/websocket/enums/ChatMessageTypeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.websocket.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @author apecode 8 | * @description 聊天消息类型枚举 9 | * @date 20/6/2023 PM1:04 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum ChatMessageTypeEnum { 14 | 15 | CHAT(1, "聊天"), 16 | JOIN(2, "加入"), 17 | LEAVE(3, "离开"); 18 | 19 | private final Integer type; 20 | private final String desc; 21 | 22 | public static ChatMessageTypeEnum getChatMessageTypeEnum(Integer type) { 23 | for (ChatMessageTypeEnum value : ChatMessageTypeEnum.values()) { 24 | if (value.type.equals(type)) return value; 25 | } 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /blog-springboot/blog-websocket/src/main/java/cn/apecode/websocket/pojo/OnlineUser.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.websocket.pojo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * @author apecode 12 | * @description OnlineUser 13 | * @date 2/7/2023 PM6:53 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Builder 19 | @ApiModel(value = "在线用户", description = "在线用户") 20 | public class OnlineUser { 21 | 22 | @ApiModelProperty(value = "用户uid") 23 | private String uid; 24 | @ApiModelProperty(value = "昵称") 25 | private String nickname; 26 | @ApiModelProperty(value = "头像") 27 | private String avatar; 28 | @ApiModelProperty(value = "IP") 29 | private String ipAddress; 30 | @ApiModelProperty(value = "归属地") 31 | private String ipSource; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /blog-springboot/blog-websocket/src/main/java/cn/apecode/websocket/pojo/VisitorUser.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.websocket.pojo; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.*; 6 | 7 | import java.security.Principal; 8 | 9 | /** 10 | * @author apecode 11 | * @description VisitorUser 12 | * @date 2/7/2023 PM7:32 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder 18 | @ToString 19 | @ApiModel(value = "游客用户", description = "游客用户") 20 | public class VisitorUser implements Principal { 21 | 22 | @ApiModelProperty("游客uid") 23 | private String uid; 24 | @ApiModelProperty("昵称") 25 | private String nickname; 26 | @ApiModelProperty("头像") 27 | private String avatar; 28 | @ApiModelProperty("登录ip") 29 | private String ipAddress; 30 | @ApiModelProperty("ip来源") 31 | private String ipSource; 32 | 33 | @Override 34 | public String getName() { 35 | return uid; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /blog-springboot/blog-websocket/src/main/java/cn/apecode/websocket/service/SystemInfoService.java: -------------------------------------------------------------------------------- 1 | package cn.apecode.websocket.service; 2 | 3 | /** 4 | * @description: 系统消息服务类 5 | * @author: apecode 6 | * @date: 2023-07-20 17:02 7 | **/ 8 | public interface SystemInfoService { 9 | 10 | /** 11 | * @description: 获取在线人数 12 | * @return {@link Integer} 13 | * @auther apecode 14 | * @date 2023/7/21 12:04 15 | */ 16 | Integer getOnlineCount(); 17 | } 18 | -------------------------------------------------------------------------------- /blog_admin/.env.development: -------------------------------------------------------------------------------- 1 | ENV='development' 2 | 3 | VITE_API_URL='http://localhost:8081' -------------------------------------------------------------------------------- /blog_admin/.env.production: -------------------------------------------------------------------------------- 1 | ENV='production' 2 | 3 | VITE_API_URL='http://localhost:8081' -------------------------------------------------------------------------------- /blog_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 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /blog_admin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ヽ( ຶ▮ ຶ)ノ!!! 加载中~ 10 | 11 | 12 | 13 |
14 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /blog_admin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blog-admin", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@icon-park/vue-next": "^1.4.2", 13 | "axios": "^0.27.2", 14 | "crypto-js": "^4.1.1", 15 | "echarts": "^5.3.3", 16 | "jsencrypt": "^3.3.2", 17 | "md-editor-v3": "^2.5.0", 18 | "pinia": "^2.0.17", 19 | "pinia-plugin-persistedstate": "^3.0.1", 20 | "vue": "^3.2.37", 21 | "vue-echarts": "^6.2.3", 22 | "vue-router": "^4.1.3" 23 | }, 24 | "devDependencies": { 25 | "@types/node": "^18.6.3", 26 | "@vitejs/plugin-vue": "^3.0.0", 27 | "naive-ui": "^2.32.2", 28 | "typescript": "^4.6.4", 29 | "vite": "^3.0.0", 30 | "vite-plugin-cdn-import": "^0.3.5", 31 | "vite-plugin-compression": "^0.5.1", 32 | "vite-plugin-windicss": "^1.8.7", 33 | "vue-tsc": "^0.38.4", 34 | "windicss": "^3.5.6" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /blog_admin/public/sleaves.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog_admin/src/api/enum/statusCode.ts: -------------------------------------------------------------------------------- 1 | export enum StatusCode { 2 | SUCCESS = 1000, // 成功 3 | UNAUTHORIZED = 1001, // 请登录 4 | USERNAME_PASSWORD_ERROR = 1002, // 用户名或密码错误 5 | AUTHORIZED = 1003, // 无权限 6 | EXPIRATION = 1004, // 登录状态过期,请重新登录 7 | EMAIL_EXIST = 1005, // 此邮箱已被注册 8 | EMAIL_NO_EXIST = 1006, // 此邮箱不存在 9 | NICKNAME_EXIST = 1007, // 昵称已存在 10 | DISABLE = 1008, // 账号被禁用 11 | FAIL = 1009, // 失败 12 | VALID_ERROR = 1010, // 参数不正确 13 | ACCESS_LIMIT = 1011, // 请求过于频繁,请稍后重试 14 | PAGE_NOT_FOUND = 404, // 页面不存在 15 | SERVER_ERROR = 500 // 服务器错误 16 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/AlbumModel.ts: -------------------------------------------------------------------------------- 1 | declare type AlbumBackModel = { 2 | id: string, 3 | user: SimpleUserInfoModel | null, 4 | albumName: string, 5 | albumDesc: string, 6 | albumCover: string, 7 | pictureCount: number, 8 | status: boolean, 9 | createTime: string, 10 | updateTime: string 11 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/ArticleModel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 保存或更新文章参数 3 | */ 4 | declare type OnlyArticleBackModel = { 5 | id: string 6 | articleTitle: string 7 | categoryName: null 8 | articleContent: string 9 | articleCover: string 10 | isTop: boolean 11 | originalUrl: string 12 | status: number 13 | tagNameList: string[] 14 | type: number 15 | } 16 | 17 | // 后台文章信息 18 | declare type ArticleBackModel = { 19 | id: string 20 | author: SimpleUserInfoModel 21 | articleTitle: string 22 | categoryName: string 23 | articleCover: string 24 | likeCount: number 25 | viewsCount: number 26 | originalUrl: string 27 | tagNames: string[] 28 | type: number 29 | isTop: boolean 30 | status: number 31 | isDelete: boolean 32 | createTime: string 33 | updateTime: string 34 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/CategoryModel.ts: -------------------------------------------------------------------------------- 1 | // 分类前台实体 2 | declare type CategoryFrontModel = { 3 | id: string, 4 | name: string, 5 | articleCount: number, 6 | } 7 | 8 | declare type CategorySearchModel = { 9 | id: string, 10 | name: string 11 | } 12 | 13 | declare type CategoryBackModel = { 14 | id: string, 15 | name: string, 16 | articleCount: number, 17 | createTime: string, 18 | updateTime: string 19 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/CommentModel.ts: -------------------------------------------------------------------------------- 1 | declare type CommentBackModel = { 2 | id: string, 3 | user: SimpleUserInfoModel, 4 | replyUser: null | SimpleUserInfoModel 5 | commentContent: string 6 | articleTitle: null | string 7 | replyCount: number | null 8 | likeCount: number | null 9 | type: string 10 | ipSource: string 11 | browser: string 12 | os: string 13 | isReview: boolean 14 | createTime: string 15 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/FriendLinkModel.ts: -------------------------------------------------------------------------------- 1 | declare type FriendLinkBackModel = { 2 | id: string 3 | user: SimpleUserInfoModel 4 | linkName: string 5 | linkAvatar: string 6 | linkIntro: string 7 | linkUrl: string 8 | isReview: boolean 9 | remark: string 10 | createTime: string 11 | updateTime: string 12 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/LogsModel.ts: -------------------------------------------------------------------------------- 1 | declare type OperationLogBack = { 2 | id: string, 3 | optModule: string, 4 | optType: string, 5 | optUrl: string, 6 | optMethod: string, 7 | optDesc: string, 8 | requestParam: string, 9 | requestMethod: string, 10 | responseData: string, 11 | user: SimpleUserInfoModel, 12 | idAddress: string, 13 | ipSource: string, 14 | createTime: string 15 | } 16 | 17 | declare type LoginLogBack = { 18 | id: string, 19 | user: SimpleUserInfoModel, 20 | loginType: number, 21 | ipAddress: string, 22 | ipSource: string, 23 | rectangle: null | string, 24 | browser: string, 25 | os: string, 26 | createTime: string 27 | } 28 | 29 | declare type MailLogBack = { 30 | msgId: string, 31 | topicId: string | null, 32 | email: string, 33 | type: string, 34 | status: number, 35 | routeKey: string, 36 | exchange: string, 37 | createTime: string 38 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/MenuModel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 当前用户菜单 3 | */ 4 | declare type UserMenuBackModel = { 5 | id: string, 6 | name: string, 7 | title: string, 8 | path: string, 9 | component: string, 10 | icon: string, 11 | parentId: string | null, 12 | orderNum: number, 13 | isEnable: boolean, 14 | createTime: string, 15 | children: UserMenuBackModel[] | null 16 | } 17 | 18 | /** 19 | * 后台菜单 20 | */ 21 | declare type MenuBackModel = UserMenuBackModel -------------------------------------------------------------------------------- /blog_admin/src/api/model/MessageModel.ts: -------------------------------------------------------------------------------- 1 | declare type MessageBackModel = { 2 | id: string 3 | user: SimpleUserInfoModel | null 4 | nickname: string 5 | avatar: string 6 | content: string 7 | theme: string 8 | isReview: boolean 9 | ipAddress: string 10 | ipSource: string 11 | createTime: string 12 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/NoticeModel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 消息实体 3 | */ 4 | declare type NoticeBackModel = { 5 | id: string 6 | user: SimpleUserInfoModel 7 | title: string 8 | content: string 9 | url: string 10 | status: boolean 11 | createTime: string 12 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/PictureModel.ts: -------------------------------------------------------------------------------- 1 | declare type PictureBackModel = { 2 | id: string, 3 | albumId: string, 4 | pictureName: string, 5 | pictureSrc: string, 6 | width: number | null 7 | height: number | null 8 | size: string | null 9 | isDelete: boolean, 10 | user: SimpleUserInfoModel | null, 11 | createTime: string, 12 | updateTime: string 13 | } 14 | 15 | // 上传的文件信息 16 | declare type UploadFileInfoModel = { 17 | width: number 18 | height: number 19 | size: string 20 | url: string 21 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/ResourceModel.ts: -------------------------------------------------------------------------------- 1 | declare type ResourceBackModel = { 2 | id: string, 3 | name: string, 4 | url: string | null, 5 | requestMethod: string | null, 6 | isEnable: boolean, 7 | parentId: string | null, 8 | isAnonymous: boolean, 9 | createTime: string, 10 | updateTime: string, 11 | children: Array | null 12 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/ResultObject.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 返回结果 3 | */ 4 | 5 | declare type ResultObject = { 6 | status: boolean; 7 | data: T, 8 | code: number, 9 | message: string 10 | } 11 | 12 | /** 13 | * 多页结果 14 | */ 15 | declare type PageResult = { 16 | status: boolean 17 | data: { 18 | count: number 19 | recordList: T 20 | }, 21 | code: number, 22 | message: string 23 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/RoleModel.ts: -------------------------------------------------------------------------------- 1 | // 角色选项 2 | declare type roleOptionModel = { 3 | id: string, 4 | roleDesc: string 5 | } 6 | 7 | // 角色后台 8 | declare type RoleBackModel = { 9 | id: string 10 | roleAuth: string 11 | roleDesc: string 12 | createTime: string 13 | isEnable: boolean 14 | resourceIdList: Array 15 | menuIdList: Array 16 | } 17 | 18 | // 资源或菜单选项 19 | declare type ResourceOrMenuOptionModel = { 20 | "id": string, 21 | "label": string, 22 | "children": Array 23 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/TagModel.ts: -------------------------------------------------------------------------------- 1 | // 后台标签 2 | declare type TagBackModel = { 3 | id: string, 4 | name: string, 5 | articleCount: number, 6 | createTime: string 7 | } 8 | 9 | -------------------------------------------------------------------------------- /blog_admin/src/api/model/TalkModel.ts: -------------------------------------------------------------------------------- 1 | declare type TalkPictureVideoModel = { 2 | id: string, 3 | src: string, 4 | fileName: string 5 | } 6 | 7 | declare type TalkBackOnlyModel = { 8 | id: string, 9 | content: string, 10 | isTop: boolean, 11 | status: number, 12 | pictureVideos: Array 13 | } 14 | 15 | declare type TalkBackModel = { 16 | user: SimpleUserInfoModel, 17 | id: string, 18 | content: string, 19 | isTop: boolean, 20 | status: number, 21 | pictureVideos: Array, 22 | likeCount: number, 23 | commentCount: number, 24 | createTime: string, 25 | updateTime: string, 26 | } -------------------------------------------------------------------------------- /blog_admin/src/api/model/UserInfoModel.ts: -------------------------------------------------------------------------------- 1 | // 用户信息 2 | declare type UserPersonalInfoModel = { 3 | email: string 4 | uid: string 5 | loginType: number | null 6 | nickname: string 7 | avatar: string 8 | intro: string 9 | webSite: string 10 | isEmailNotice: boolean 11 | createTime: string 12 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/ArticleParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 保存或更新文章参数 3 | */ 4 | declare type SaveOrUpdateArticleParams = { 5 | id?: string 6 | articleTitle: string 7 | categoryName: null 8 | articleContent: string 9 | articleCover: string 10 | isTop: boolean 11 | originalUrl?: string 12 | status: number 13 | tagNameList: string[] 14 | type: number 15 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/CategoryParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 添加或修改分类 3 | */ 4 | declare type CategoryParams = { 5 | categoryId?: string 6 | name?: string 7 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/ConditionParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 查询参数 3 | */ 4 | declare type ConditionParams = { 5 | albumPath?: string, 6 | articleId?: string, 7 | categoryId?: string, 8 | email?: string, 9 | endTime?: string, 10 | startTime?: string, 11 | isDelete?: boolean | null | number, 12 | isReview?: boolean | number | null, 13 | keywords?: string, 14 | loginType?: number, 15 | size?: number, 16 | current?: number, 17 | status?: number | null, 18 | tagId?: string, 19 | type?: number | null, 20 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/FriendLinkParams.ts: -------------------------------------------------------------------------------- 1 | declare type FriendLinkParams = { 2 | id?: string | null 3 | linkAvatar: string 4 | linkIntro: string 5 | linkName: string 6 | linkUrl: string 7 | remark: string 8 | isReview: boolean 9 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/MenuParams.ts: -------------------------------------------------------------------------------- 1 | declare type MenuParams = { 2 | id: string | null, 3 | name: string, 4 | title: string, 5 | path: string, 6 | component: string, 7 | icon: string, 8 | parentId: string | null, 9 | orderNum: number | string, 10 | isEnable: boolean, 11 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/NoticeParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 获取后台消息参数 3 | */ 4 | declare type NoticeParams = { 5 | isRead: boolean 6 | isSystemNotice?: boolean 7 | nickname?: string, 8 | size?: number, 9 | current?: number 10 | } 11 | 12 | /** 13 | * 发送消息通知 14 | */ 15 | declare type SendNoticeParams = { 16 | title: string 17 | content: string 18 | url?: string 19 | userId: string 20 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/PhotoAlbumParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 添加或修改相册 3 | */ 4 | declare type PhotoAlbumParams = { 5 | albumId?: string 6 | albumName: string 7 | albumDesc: string 8 | albumCover: string 9 | status: boolean 10 | isDelete?: boolean 11 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/PictureParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 更新图片信息 3 | */ 4 | declare type PictureInfoParams = { 5 | picturePath: string 6 | pictureName: string 7 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/ResourceParams.ts: -------------------------------------------------------------------------------- 1 | // 新增或修改资源参数 2 | declare type ResourceParams = { 3 | id: string | null 4 | isAnonymous: boolean 5 | isEnable: boolean 6 | name: string 7 | parentId: string | null 8 | requestMethod: string | null 9 | url: string | null 10 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/ReviewParams.ts: -------------------------------------------------------------------------------- 1 | declare type ReviewParams = { 2 | idList: Array 3 | isReview: boolean 4 | remark?: string 5 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/TagParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 更新标签 3 | */ 4 | declare type UpdateTagParams = { 5 | id: string 6 | name: string 7 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/TalkParams.ts: -------------------------------------------------------------------------------- 1 | declare type TalkFormParams = { 2 | id?: string 3 | files?: Array 4 | content: string 5 | isTop: boolean 6 | status: number 7 | } 8 | 9 | /** 10 | * 说说顶置 11 | */ 12 | declare type TalkTopParams = { 13 | id: string 14 | isTop: boolean 15 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/UserParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 用户登录参数 3 | */ 4 | declare type UserLoginParams = { 5 | username: string 6 | password: string 7 | captchaVerification: string 8 | } 9 | 10 | /** 11 | * 修改密码 12 | */ 13 | declare type UpdatePassword = { 14 | oldPassword: string | null 15 | newPassword: string | null 16 | code: string | null 17 | captchaVerification: string 18 | } 19 | 20 | /** 21 | * 更新用户信息 22 | */ 23 | declare type UpdateUserInfo = { 24 | nickname: string | null 25 | intro: string | null 26 | webSite: string | null 27 | isEmailNotice: boolean | null 28 | } 29 | /** 30 | * 更新用户禁用状态 31 | */ 32 | declare type UserEnable = { 33 | id: string 34 | enable: boolean 35 | } -------------------------------------------------------------------------------- /blog_admin/src/api/params/roleParams.ts: -------------------------------------------------------------------------------- 1 | // 保存或修改角色 2 | declare type RoleParams = { 3 | isEnable: boolean 4 | menuIdList?: Array | null 5 | resourceIdList?: Array | null 6 | roleAuth: string 7 | roleDesc: string 8 | roleId?: string 9 | } -------------------------------------------------------------------------------- /blog_admin/src/api/requests/About.ts: -------------------------------------------------------------------------------- 1 | import request from '../service' 2 | 3 | /** 4 | * 获取关于我 5 | */ 6 | export function getAboutMe(): Promise> { 7 | return request.get({ 8 | url: '/about' 9 | }) 10 | } 11 | 12 | /** 13 | * 修改关于我 14 | * @param data 15 | */ 16 | export function updateAboutMe(data: FormData): Promise> { 17 | return request.put({ 18 | url: '/admin/about', 19 | data 20 | }) 21 | } -------------------------------------------------------------------------------- /blog_admin/src/api/requests/Comment.ts: -------------------------------------------------------------------------------- 1 | import request from '~/api/service' 2 | 3 | /** 4 | * 后台评论列表 5 | * @param condition 6 | */ 7 | export function listCommentBack(condition: ConditionParams): Promise>> { 8 | return request.get({ 9 | url: '/admin/comments', 10 | params: condition, 11 | isDecrypt: true 12 | }) 13 | } 14 | 15 | /** 16 | * 修改评论审核 17 | * @param data 18 | */ 19 | export function updateCommentReview(data: { idList: Array, isReview: boolean }): Promise> { 20 | return request.put({ 21 | url: '/admin/comment', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 删除评论 28 | * @param data 29 | */ 30 | export function deleteComment(data: FormData): Promise> { 31 | return request.delete({ 32 | url: '/admin/comment', 33 | data 34 | }) 35 | } -------------------------------------------------------------------------------- /blog_admin/src/api/requests/FriendLink.ts: -------------------------------------------------------------------------------- 1 | import request from '~/api/service' 2 | 3 | /** 4 | * 获取后台友链 5 | * @param condition 6 | */ 7 | export function listFriendLinkBack(condition: ConditionParams): Promise>> { 8 | return request.get({ 9 | url: '/admin/links', 10 | params: condition, 11 | isDecrypt: true 12 | }) 13 | } 14 | 15 | /** 16 | * 修改友链审核 17 | * @param data 18 | */ 19 | export function UpdateFriendLinkReview(data: ReviewParams): Promise> { 20 | return request.put({ 21 | url: '/admin/links', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 删除友链 28 | * @param friendLinkId 29 | */ 30 | export function deleteFriendLink(friendLinkId: string): Promise> { 31 | return request.delete({ 32 | url: '/admin/link/' + friendLinkId 33 | }) 34 | } 35 | 36 | /** 37 | * 新增或修改友链 38 | * @param data 39 | */ 40 | export function saveOrUpdateFriendLink(data: FriendLinkParams): Promise> { 41 | return request.post({ 42 | url: '/admin/link', 43 | data, 44 | isEncrypt: true 45 | }) 46 | } -------------------------------------------------------------------------------- /blog_admin/src/api/requests/Message.ts: -------------------------------------------------------------------------------- 1 | import request from '~/api/service' 2 | 3 | /** 4 | * 后台留言列表 5 | * @param condition 6 | */ 7 | export function listMessageBack(condition: ConditionParams): Promise>> { 8 | return request.get({ 9 | url: '/admin/messages', 10 | params: condition, 11 | isDecrypt: true 12 | }) 13 | } 14 | 15 | /** 16 | * 更新留言审核 17 | * @param data 18 | */ 19 | export function updateMessageReview(data: { idList: Array, isReview: boolean }): Promise> { 20 | return request.put({ 21 | url: '/admin/message', 22 | data, 23 | isEncrypt: true 24 | }) 25 | } 26 | 27 | /** 28 | * 删除留言 29 | * @param data 30 | */ 31 | export function deleteMessage(data: Array): Promise> { 32 | return request.delete({ 33 | url: '/admin/message', 34 | data, 35 | isEncrypt: true 36 | }) 37 | } -------------------------------------------------------------------------------- /blog_admin/src/api/requests/Role.ts: -------------------------------------------------------------------------------- 1 | import request from "~/api/service"; 2 | 3 | /** 4 | * 获取角色选项 5 | */ 6 | export function getRoleOptions(): Promise>> { 7 | return request.get({ 8 | url: '/admin/user/roles', 9 | isDecrypt: true 10 | }) 11 | } 12 | 13 | /** 14 | * 获取角色列表 15 | * @param condition 16 | */ 17 | export function listRole(condition: ConditionParams): Promise>> { 18 | return request.get({ 19 | url: '/admin/roles', 20 | params: condition, 21 | isDecrypt: true 22 | }) 23 | } 24 | 25 | /** 26 | * 保存或修改角色 27 | * @param data 28 | */ 29 | export function saveOrUpdateRole(data: RoleParams): Promise> { 30 | return request.post({ 31 | url: '/admin/role', 32 | data, 33 | isEncrypt: true 34 | }) 35 | } 36 | 37 | /** 38 | * 删除角色 39 | * @param data 40 | */ 41 | export function deleteRole(data: string): Promise> { 42 | return request.delete({ 43 | url: '/admin/role', 44 | data 45 | }) 46 | } -------------------------------------------------------------------------------- /blog_admin/src/api/requests/Tag.ts: -------------------------------------------------------------------------------- 1 | import request from '~/api/service' 2 | 3 | /** 4 | * 修改标签 5 | * @param data 6 | */ 7 | export function updateTag(data: UpdateTagParams): Promise> { 8 | return request.put({ 9 | url: '/admin/tags', 10 | data, 11 | isEncrypt: true 12 | }) 13 | } 14 | 15 | /** 16 | * 删除标签 17 | * @param data 18 | */ 19 | export function deleteTag(data: string): Promise> { 20 | return request.delete({ 21 | url: '/admin/tags', 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 后台标签列表 28 | * @param condition 29 | */ 30 | export function listTagBack(condition: ConditionParams): Promise>> { 31 | return request.get({ 32 | url: '/admin/tags', 33 | params: condition, 34 | isDecrypt: true 35 | }) 36 | } 37 | 38 | /** 39 | * 保存标签 40 | * @param tags 41 | */ 42 | export function saveTag(tags: Array): Promise> { 43 | return request.post({ 44 | url: '/admin/tags', 45 | data: tags, 46 | isEncrypt: true 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /blog_admin/src/api/requests/Website.ts: -------------------------------------------------------------------------------- 1 | import requests from '../service' 2 | 3 | // 获取后台信息 4 | export function getWebsiteInfoBack(): Promise> { 5 | return requests.get({ 6 | url: "/admin", 7 | isDecrypt: true 8 | }) 9 | } 10 | 11 | /** 12 | * 获取网站配置 13 | */ 14 | export function getWebsiteConfigure(): Promise> { 15 | return requests.get({ 16 | url: '/admin/website/config', 17 | isDecrypt: true 18 | }) 19 | } 20 | 21 | /** 22 | * 更新网站配置 23 | * @param data 24 | */ 25 | export function updateWebsiteConfigure(data: WebsiteConfigureModel): Promise> { 26 | return requests.put({ 27 | url: '/admin/website/config', 28 | data, 29 | isEncrypt: true 30 | }) 31 | } 32 | 33 | // 上传网站配置图片 34 | export function uploadWebsiteConfigurePicture(file: any): Promise> { 35 | return requests.post({ 36 | url: '/admin/config/images', 37 | headers: { 38 | 'Content-Type': 'multipart/form-data' 39 | }, 40 | data: file 41 | }) 42 | } -------------------------------------------------------------------------------- /blog_admin/src/api/service.ts: -------------------------------------------------------------------------------- 1 | import XmlRequest from "./config"; 2 | 3 | let base = import.meta.env.VITE_API_URL; 4 | 5 | const request = new XmlRequest({ 6 | timeout: 10000, 7 | baseURL: `${base}`, 8 | headers: { 9 | 'X-Requested-With': 'XMLHttpRequest', 10 | 'Content-Type': 'application/json; charset=utf-8' 11 | } 12 | }) 13 | 14 | export default request; -------------------------------------------------------------------------------- /blog_admin/src/assets/fonts/ZhuZiAWan.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog_admin/src/assets/fonts/ZhuZiAWan.woff2 -------------------------------------------------------------------------------- /blog_admin/src/assets/imgs/local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog_admin/src/assets/imgs/local.png -------------------------------------------------------------------------------- /blog_admin/src/components/DescSetting.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /blog_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 | '-', 14 | 'codeRow', 15 | 'code', 16 | 'link', 17 | 'image', 18 | 'table', 19 | 'mermaid', 20 | 'katex', 21 | 0, 22 | '-', 23 | 'revoke', 24 | 'next', 25 | 'save', 26 | '=', 27 | 'prettier', 28 | 'pageFullscreen', 29 | 'fullscreen', 30 | 'preview', 31 | 'htmlPreview', 32 | 'catalog', 33 | ]; -------------------------------------------------------------------------------- /blog_admin/src/components/common/dataTable/index.ts: -------------------------------------------------------------------------------- 1 | // 表格尺寸设置 2 | import {SelectOption} from "naive-ui"; 3 | import {reactive, ref} from "vue"; 4 | 5 | export const tableSizeOption = [ 6 | { 7 | label: "宽松", 8 | value: "large" 9 | }, 10 | { 11 | label: "舒适", 12 | value: "medium" 13 | }, 14 | { 15 | label: "小巧", 16 | value: "small" 17 | }, 18 | { 19 | label: "紧凑", 20 | value: "tiny" 21 | }, 22 | ] 23 | 24 | // 表格样式设置 25 | export const tableSet = reactive({ 26 | striped: true, 27 | singleLine: false, 28 | singleColumn: false 29 | }) 30 | // 表格默认尺寸 31 | export const tableSize = ref("medium") 32 | 33 | export const tableSizeHandle = (value: string, option: SelectOption) => { 34 | tableSize.value = value 35 | } -------------------------------------------------------------------------------- /blog_admin/src/components/layouts/TriggerCollapse.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 23 | 24 | -------------------------------------------------------------------------------- /blog_admin/src/components/verifition/api/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 此处可直接引用自己项目封装好的 axios 配合后端联调 3 | */ 4 | 5 | 6 | import request from "./../utils/axios" //组件内部封装的axios 7 | // import request from "@/api/axios.js" //调用项目封装的axios 8 | 9 | //获取验证图片 以及token 10 | export function reqGet(data) { 11 | return request({ 12 | url: '/captcha/get', 13 | method: 'post', 14 | data 15 | }) 16 | } 17 | 18 | //滑动或者点选验证 19 | export function reqCheck(data) { 20 | return request({ 21 | url: '/captcha/check', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /blog_admin/src/components/verifition/utils/ase.js: -------------------------------------------------------------------------------- 1 | import CryptoJS from 'crypto-js' 2 | /** 3 | * @word 要加密的内容 4 | * @keyWord String 服务器随机返回的关键字 5 | * */ 6 | export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){ 7 | var key = CryptoJS.enc.Utf8.parse(keyWord); 8 | var srcs = CryptoJS.enc.Utf8.parse(word); 9 | var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}); 10 | return encrypted.toString(); 11 | } 12 | -------------------------------------------------------------------------------- /blog_admin/src/components/verifition/utils/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const service = axios.create({ 4 | timeout: 40000, 5 | headers: { 6 | 'X-Requested-With': 'XMLHttpRequest', 7 | 'Content-Type': 'application/json; charset=UTF-8' 8 | }, 9 | }) 10 | service.interceptors.request.use( 11 | config => { 12 | config.baseURL = import.meta.env.VITE_API_URL; 13 | return config 14 | }, 15 | error => { 16 | Promise.reject(error) 17 | } 18 | ) 19 | 20 | // response interceptor 21 | service.interceptors.response.use( 22 | response => { 23 | const res = response.data; 24 | return res 25 | }, 26 | error => { 27 | } 28 | ) 29 | export default service 30 | -------------------------------------------------------------------------------- /blog_admin/src/constant.ts: -------------------------------------------------------------------------------- 1 | // 公钥 2 | export const publicKey = "-----BEGIN PUBLIC KEY-----公钥-----END PUBLIC KEY-----"; 3 | // 私钥 4 | export const privateKey = "-----BEGIN RSA PRIVATE KEY-----私钥-----END RSA PRIVATE KEY-----"; -------------------------------------------------------------------------------- /blog_admin/src/echarts/echart.d.ts: -------------------------------------------------------------------------------- 1 | //echart.d.ts 2 | import { ComposeOption } from 'echarts/core'; 3 | import { 4 | BarSeriesOption, 5 | LineSeriesOption 6 | } from 'echarts/charts'; 7 | import { 8 | // 组件类型的定义后缀都为 ComponentOption 9 | TitleComponentOption, 10 | TooltipComponentOption, 11 | GridComponentOption, 12 | // 数据集组件 13 | DatasetComponentOption, 14 | } from 'echarts/components'; 15 | 16 | type ECOption = ComposeOption< 17 | | BarSeriesOption 18 | | LineSeriesOption 19 | | TitleComponentOption 20 | | TooltipComponentOption 21 | | GridComponentOption 22 | | DatasetComponentOption 23 | >; 24 | 25 | export { ECOption } -------------------------------------------------------------------------------- /blog_admin/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // 获取自定义环境变量的 智能提示 4 | interface ImportMetaEnv { 5 | readonly VITE_API_URL: string 6 | } 7 | 8 | interface ImportMeta { 9 | readonly env: ImportMetaEnv 10 | } -------------------------------------------------------------------------------- /blog_admin/src/main.ts: -------------------------------------------------------------------------------- 1 | // 全局样式 2 | import './style/base.css' 3 | import '@icon-park/vue-next/styles/index.css'; 4 | 5 | import { createApp } from 'vue' 6 | import App from './App.vue' 7 | import { setupRouter, setupRouterGuard, router } from '~/router'; 8 | import { setupStore } from '~/store' 9 | import { setupECharts } from './echarts'; 10 | 11 | const app = createApp(App) 12 | setupRouter(app) 13 | setupRouterGuard(router) 14 | setupStore(app) 15 | setupECharts(app) 16 | import 'virtual:windi.css' 17 | import 'virtual:windi-devtools' 18 | app.mount('#app') 19 | -------------------------------------------------------------------------------- /blog_admin/src/router/routes.ts: -------------------------------------------------------------------------------- 1 | import { RouteRecordRaw } from 'vue-router'; 2 | import PageLayout from '../layout/PageLayout.vue'; 3 | 4 | export const constantRoutes: RouteRecordRaw[] = [ 5 | { 6 | path: '/pageLayout', 7 | name: 'root', 8 | component: PageLayout, 9 | redirect: '/home', 10 | children: [] 11 | }, 12 | { 13 | path: '/login', 14 | name: "Login", 15 | component: () => import("~/views/login/Login.vue"), 16 | meta: { 17 | title: "后台登录" 18 | } 19 | } 20 | ] 21 | 22 | -------------------------------------------------------------------------------- /blog_admin/src/settings.ts: -------------------------------------------------------------------------------- 1 | export type TriggerStyle = 'bar' | 'arrow-circle' | 'custom' 2 | export type MenuMode = 'vertical' | 'horizontal' 3 | 4 | export interface SettingConfig { 5 | isShowDraw: boolean 6 | isShowLogo: boolean 7 | isFixedHeader: boolean 8 | isCollapse: boolean 9 | isShowTagViews: boolean 10 | isShowBreadcrumb: boolean 11 | isShowBreadcrumbIcon: boolean 12 | isInverted: boolean 13 | collapsedIconSize: number 14 | collapsedWidth: number 15 | globalTheme: 'darkTheme' | 'lightTheme' 16 | menuMode: MenuMode 17 | triggerStyle: TriggerStyle 18 | } 19 | 20 | export default { 21 | isShowDraw: false, 22 | isShowLogo: true, 23 | isFixedHeader: true, 24 | isCollapse: false, 25 | isShowTagViews: true, 26 | isShowBreadcrumb: true, 27 | isShowBreadcrumbIcon: true, 28 | isInverted: false, 29 | collapsedIconSize: 24, 30 | collapsedWidth: 50, 31 | globalTheme: 'darkTheme', 32 | menuMode: 'vertical', 33 | triggerStyle: 'bar' 34 | } as SettingConfig -------------------------------------------------------------------------------- /blog_admin/src/shims.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@kangc/v-md-editor/lib/theme/vuepress.js'; 2 | declare module '@kangc/v-md-editor' -------------------------------------------------------------------------------- /blog_admin/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { App } from 'vue'; 2 | import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' 3 | import {createPinia} from "pinia"; 4 | export { useGlobalStore } from './modules/global' 5 | export { useWebsiteStore } from './modules/website' 6 | export { useMenuStore } from './modules/menu'; 7 | export { useSettingStore } from './modules/setting' 8 | export { useUserInfoStore } from './modules/userInfo' 9 | export { useTagsViewStore } from './modules/tagsView' 10 | 11 | const store = createPinia(); 12 | store.use(piniaPluginPersistedstate) 13 | export function setupStore(app: App) { 14 | app.use(store); 15 | } -------------------------------------------------------------------------------- /blog_admin/src/store/modules/global.ts: -------------------------------------------------------------------------------- 1 | import type { Ref } from 'vue'; 2 | import { Names } from './store-name' 3 | import {defineStore} from "pinia" 4 | import {ref, nextTick} from "vue" 5 | 6 | export const useGlobalStore = defineStore(Names.GLOBAL, () => { 7 | let isRouterAlive: Ref = ref(true) 8 | 9 | // 刷新局部组件 10 | const reload = async () => { 11 | isRouterAlive.value = false 12 | await nextTick(() => { 13 | isRouterAlive.value = true 14 | }) 15 | } 16 | 17 | return { 18 | isRouterAlive, 19 | reload 20 | } 21 | }) -------------------------------------------------------------------------------- /blog_admin/src/store/modules/menu.ts: -------------------------------------------------------------------------------- 1 | import type { Ref } from 'vue'; 2 | import { Names } from './store-name' 3 | import {defineStore} from "pinia"; 4 | import {ref} from "vue"; 5 | 6 | export const useMenuStore = defineStore(Names.MENU, () => { 7 | 8 | let menus: Ref | null> = ref | null>(null); 9 | 10 | // 保存菜单 11 | const saveMenu = (menu: Array) => { 12 | menus.value = menu 13 | }; 14 | 15 | // 清除菜单 16 | const clearMenu = () => { 17 | menus.value = null 18 | } 19 | 20 | return { menus, saveMenu, clearMenu } 21 | }, { persist: { storage: sessionStorage } }) -------------------------------------------------------------------------------- /blog_admin/src/store/modules/setting.ts: -------------------------------------------------------------------------------- 1 | import type { SettingConfig, TriggerStyle } from '~/settings'; 2 | import { Names } from "./store-name" 3 | import settings from "~/settings" 4 | import {defineStore} from "pinia"; 5 | import {computed, reactive, toRefs} from "vue"; 6 | 7 | export const useSettingStore = defineStore(Names.SETTING, () => { 8 | const setting = reactive(settings) 9 | const changeSetting = ( 10 | key: keyof SettingConfig, 11 | value: boolean | TriggerStyle 12 | ) => { 13 | // @ts-ignore 14 | setting[key] = value 15 | } 16 | 17 | // 18 | const editorTheme = computed(() => { 19 | return setting.globalTheme === "darkTheme" ? "dark" : ""; 20 | }) 21 | 22 | return { 23 | ...toRefs(setting), 24 | changeSetting, 25 | editorTheme 26 | } 27 | }, { persist: { storage: localStorage } }) -------------------------------------------------------------------------------- /blog_admin/src/store/modules/store-name.ts: -------------------------------------------------------------------------------- 1 | export const enum Names { 2 | GLOBAL = "BLOG_GLOBAL", 3 | WEBSITE = "BLOG_WEBSITE", 4 | SETTING = "BLOG_SETTING", 5 | USERINFO = "BLOG_USERINFO", 6 | MENU = "BLOG_MENU", 7 | TAGSVIEW = 'BLOG_TAGSVIEW' 8 | } -------------------------------------------------------------------------------- /blog_admin/src/store/modules/website.ts: -------------------------------------------------------------------------------- 1 | import type { Ref } from 'vue'; 2 | import { Names } from './store-name' 3 | import {defineStore} from "pinia"; 4 | import {ref} from "vue"; 5 | 6 | export const useWebsiteStore = defineStore(Names.WEBSITE, () => { 7 | let noReadNoticeCount: Ref = ref(0); 8 | 9 | return { 10 | noReadNoticeCount, 11 | } 12 | }) -------------------------------------------------------------------------------- /blog_admin/src/store/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { RouterMeta } from 'vue-router' 2 | 3 | export interface TagView extends RouterMeta { 4 | fullPath: string, 5 | [key: string]: any 6 | } -------------------------------------------------------------------------------- /blog_admin/src/utils/Msp.ts: -------------------------------------------------------------------------------- 1 | import local from "~/assets/imgs/local.png"; 2 | 3 | const generateMap = (domId: string, lng: string = "116.404", lat: string = '39.915') => { 4 | let BMap = (window as any).BMap; // 注意要带window,不然会报错(注意官方api,会有改动,之前是Bmap,后面3.0版本改为了BMap,最好查文档或者打印一下window) 5 | let map = new BMap.Map(domId); // domId必须和dom上的id一直 6 | map.clearOverlays() 7 | map.enableScrollWheelZoom(true) 8 | map.enableContinuousZoom(true) 9 | map.addControl(new BMap.NavigationControl()); 10 | map.addControl(new BMap.ScaleControl()); 11 | map.addControl(new BMap.OverviewMapControl()); 12 | let point = new BMap.Point(lng, lat); 13 | map.centerAndZoom(point, 12) 14 | let myIcon = new BMap.Icon(local, new BMap.Size(40, 40)); 15 | let marker = new BMap.Marker(point, {icon: myIcon}) 16 | map.addOverlay(marker) 17 | }; 18 | 19 | export { 20 | generateMap 21 | } -------------------------------------------------------------------------------- /blog_admin/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { NIcon } from 'naive-ui' 2 | import { h } from 'vue' 3 | import { Icon } from '@icon-park/vue-next/lib/runtime' 4 | 5 | export const renderIcon = (icon: Icon) => { 6 | const slots = { 7 | default: () => h(icon) 8 | } 9 | return () => h(NIcon, null, slots) 10 | } 11 | 12 | // 根据图标字符串动态渲染图标 13 | // 缺点:打包时会把所有图标都打包 14 | export async function asyncRenderIcon(icon: any) { 15 | const { [icon]: iconComp }: any = await import('@icon-park/vue-next'); 16 | return () => h(NIcon, null, { default: () => h(iconComp) }); 17 | } -------------------------------------------------------------------------------- /blog_admin/src/utils/rsa.ts: -------------------------------------------------------------------------------- 1 | import JSEncrypt from 'jsencrypt' 2 | import { publicKey, privateKey } from '~/constant'; 3 | 4 | export default class RSAUtil { 5 | 6 | public static encryptByPublicKey(data: { key: string, keyIV: string }): string | boolean { 7 | let plaintext = JSON.stringify(data); 8 | const encryptor = new JSEncrypt() 9 | encryptor.setPublicKey(publicKey) 10 | return encryptor.encrypt(plaintext) 11 | } 12 | 13 | public static decryptByPrivateKey(content: string): string | boolean { 14 | const decrypt = new JSEncrypt(); 15 | decrypt.setPrivateKey(privateKey); 16 | const decryptedContent = decrypt.decrypt(content); 17 | return decryptedContent; 18 | } 19 | } -------------------------------------------------------------------------------- /blog_admin/src/utils/utils.ts: -------------------------------------------------------------------------------- 1 | import {smilingFaces, humans, animalsAndNature, others} from "~/utils/dynamicEmojis" 2 | 3 | const emojis = {...smilingFaces, ...humans, ...animalsAndNature, ...others} as any 4 | 5 | /** 6 | * 判断设备 7 | */ 8 | export const isMobile = () => { 9 | return navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i); 10 | } 11 | 12 | // 解析emoji 13 | export const parseComment = (comment: string, width: string, height: string) => { 14 | let reg = /\[.+?\]/g; 15 | return comment.replace(reg, (str: string) => { 16 | return ``; 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /blog_admin/src/views/error/PageNotFound.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /blog_admin/src/views/home/data/category.ts: -------------------------------------------------------------------------------- 1 | import type { Ref } from 'vue'; 2 | import type { ECOption } from '~/echarts/echart'; 3 | import {ref} from "vue"; 4 | 5 | const categoriesData: Array = []; 6 | 7 | const categoryOption: Ref = ref({ 8 | title: { 9 | text: '分类', 10 | left: 'left' 11 | }, 12 | tooltip: { 13 | trigger: 'item', 14 | formatter: '{b}
{c}篇文章 ({d}%)', 15 | borderRadius: 4, 16 | backgroundColor: "rgba(50,50,50,0.5)", 17 | borderColor: "#181616", 18 | textStyle: { 19 | color: "#ffffff" 20 | }, 21 | }, 22 | toolbox: { 23 | show: true, 24 | feature: { 25 | saveAsImage: { show: true } 26 | } 27 | }, 28 | series: { 29 | name: 'category', 30 | type: 'pie', 31 | radius: [20, 140], 32 | roseType: 'area', 33 | itemStyle: { 34 | borderRadius: 5 35 | }, 36 | data: [] as any 37 | } 38 | } as any); 39 | 40 | export { 41 | categoryOption, 42 | categoriesData 43 | } -------------------------------------------------------------------------------- /blog_admin/src/views/home/data/systemDiskInfo.ts: -------------------------------------------------------------------------------- 1 | const SystemDiskInfoOption = { 2 | title: { 3 | text: '系统硬盘情况', 4 | left: 'left' 5 | }, 6 | tooltip: { 7 | formatter: '{b} 已使用:{c}GB' 8 | }, 9 | series: { 10 | name: 'Pressure', 11 | type: 'gauge', 12 | min: 0, 13 | max: 0, 14 | radius: '90%', 15 | progress: { 16 | show: true 17 | }, 18 | itemStyle: { 19 | color: '#FFAB91' 20 | }, 21 | detail: { 22 | valueAnimation: true, 23 | formatter: '{value} GB', 24 | }, 25 | title: { 26 | offsetCenter: [0, '85%'] 27 | }, 28 | data: [ 29 | { 30 | value: 0, 31 | name: '' 32 | } 33 | ] 34 | } 35 | }; 36 | 37 | export { 38 | SystemDiskInfoOption 39 | } -------------------------------------------------------------------------------- /blog_admin/src/views/home/data/systemMemory.ts: -------------------------------------------------------------------------------- 1 | const SystemMemoryOption = { 2 | title: { 3 | text: '系统内存情况', 4 | left: 'left' 5 | }, 6 | tooltip: { 7 | formatter: '{b}
已使用:{c}GB' 8 | }, 9 | series: { 10 | name: 'Pressure', 11 | type: 'gauge', 12 | min: 0, 13 | max: 0, 14 | radius: '90%', 15 | progress: { 16 | show: true 17 | }, 18 | itemStyle: { 19 | color: '#30cfd0' 20 | }, 21 | detail: { 22 | valueAnimation: true, 23 | formatter: '{value} GB', 24 | }, 25 | title: { 26 | offsetCenter: [0, '85%'] 27 | }, 28 | data: [ 29 | { 30 | value: 0, 31 | name: '' 32 | } 33 | ] 34 | } 35 | }; 36 | 37 | export { 38 | SystemMemoryOption 39 | } -------------------------------------------------------------------------------- /blog_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_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 | "sourceMap": true, 10 | "resolveJsonModule": true, 11 | "isolatedModules": false, 12 | "esModuleInterop": true, 13 | "lib": [ 14 | "ESNext", 15 | "DOM" 16 | ], 17 | "skipLibCheck": true, 18 | "types": [ 19 | "node" 20 | ], 21 | "paths": { 22 | "~/*": [ 23 | "./src/*" 24 | ] 25 | } 26 | }, 27 | "include": [ 28 | "src/**/*.ts", 29 | "src/**/*.d.ts", 30 | "src/**/*.tsx", 31 | "src/**/*.vue", 32 | "./*.d.ts" 33 | ], 34 | "references": [ 35 | { 36 | "path": "./tsconfig.node.json" 37 | } 38 | ] 39 | } -------------------------------------------------------------------------------- /blog_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/.env.development: -------------------------------------------------------------------------------- 1 | ENV='development' 2 | 3 | VITE_API_URL='http://localhost:8081' 4 | VITE_WEBSOCKET_URL='http://localhost:8081/ws' -------------------------------------------------------------------------------- /blog_vue/.env.production: -------------------------------------------------------------------------------- 1 | ENV='production' 2 | 3 | VITE_API_URL='http://localhost:8081' 4 | VITE_WEBSOCKET_URL='http://localhost:8081/ws' -------------------------------------------------------------------------------- /blog_vue/.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 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /blog_vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ヽ( ຶ▮ ຶ)ノ!!! 加载中~ 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /blog_vue/public/sleaves.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog_vue/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 25 | 26 | 33 | -------------------------------------------------------------------------------- /blog_vue/src/api/entity/AlbumEntity.ts: -------------------------------------------------------------------------------- 1 | // 相册 2 | declare type AlbumEntity = { 3 | id: string 4 | albumName: string 5 | albumCover: string 6 | pictureCount: number | null 7 | updateTime: string 8 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/CategoryEntity.ts: -------------------------------------------------------------------------------- 1 | declare type CategoryEntity = { 2 | id: string, 3 | name: string, 4 | articleCount: number 5 | } 6 | 7 | // 分类列表 8 | declare type CategoryFrontEntity = { 9 | categories: CategoryEntity 10 | newsArticleList: NewsArticleEntity 11 | newsCommentList: NewCommentEntity 12 | } 13 | 14 | // 分类搜索 15 | declare type CategorySearchEntity = { 16 | id: string, 17 | name: string, 18 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/ChatRoomEntity.ts: -------------------------------------------------------------------------------- 1 | // 游客信息 2 | declare type VisitorUser = { 3 | uid: string 4 | nickname: string 5 | ipAddress: string 6 | ipSource: string 7 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/CommentEntity.ts: -------------------------------------------------------------------------------- 1 | // 最新评论 2 | declare type NewCommentEntity = { 3 | topicId: string 4 | type: number 5 | user: SimpleUserInfoEntity 6 | commentContent: string 7 | createTime: string 8 | } 9 | 10 | declare type CommentEntity = { 11 | id: string 12 | user: SimpleUserInfoEntity 13 | commentContent: string 14 | distance: null | string 15 | geoIp: null | string; 16 | browser: string 17 | os: string 18 | replyCount: number | null 19 | likeCount: number | null 20 | createTime: string 21 | replyList: Array 22 | } 23 | 24 | 25 | declare type ReplyEntity = { 26 | id: string 27 | parentId: string 28 | replyCommentId: string 29 | user: SimpleUserInfoEntity 30 | replyUser: SimpleUserInfoEntity | null 31 | commentContent: string 32 | distance: null | string 33 | geoIp: null | string 34 | browser: string 35 | os: string 36 | likeCount: null | number 37 | createTime: string 38 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/FriendLinkEntity.ts: -------------------------------------------------------------------------------- 1 | declare type FriendLinkEntity = { 2 | user: SimpleUserInfoEntity 3 | linkName: string 4 | linkAvatar: string 5 | linkIntro: string 6 | linkUrl: string 7 | createTime: string 8 | } 9 | 10 | declare type UserFriendLinkEntity = { 11 | id: string 12 | user: SimpleUserInfoEntity | null 13 | linkName: string 14 | linkAvatar: string 15 | linkIntro: string 16 | linkUrl: string 17 | isReview: boolean 18 | remark: string 19 | createTime: string 20 | updateTime: string 21 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/MessageEntity.ts: -------------------------------------------------------------------------------- 1 | declare type MessageTheme = "default" | "orange" | "tomato" | "FlamingoPink" | "watermelon" | "PrestigeBlue" | "UfoGreen" | "BrightGreek" | "wisteria" 2 | 3 | declare type MessageEntity = { 4 | user: SimpleUserInfoEntity | null 5 | nickname: string 6 | avatar: string 7 | content: string 8 | theme: MessageTheme 9 | createTime: string 10 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/NoticeEntity.ts: -------------------------------------------------------------------------------- 1 | declare type NoticeEntity = { 2 | id: string 3 | title: string 4 | content: string 5 | url: string | null 6 | status: boolean 7 | createTime: string 8 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/PictureEntity.ts: -------------------------------------------------------------------------------- 1 | declare type PictureEntity = { 2 | pictureName: string 3 | pictureSrc: string 4 | width: number | null 5 | height: number | null 6 | size: string 7 | createTime: string 8 | } 9 | 10 | // 图片相册信息 11 | declare type PictureAlbumInfoEntity = { 12 | albumName: string 13 | albumDesc: string 14 | createTime: string 15 | updateTime: string 16 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/ResultObject.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 返回结果 3 | */ 4 | 5 | declare type ResultObject = { 6 | status: boolean; 7 | data: T, 8 | code: number, 9 | message: string 10 | } 11 | 12 | /** 13 | * 多页结果 14 | */ 15 | declare type PageResult = { 16 | status: boolean 17 | data: { 18 | count: number 19 | recordList: T 20 | }, 21 | code: number, 22 | message: string 23 | } 24 | 25 | /** 26 | * 带有其他对象的页面结果 27 | */ 28 | declare type PageResultWithObject = { 29 | status: boolean 30 | data: { 31 | count: number 32 | recordList: T 33 | data: E 34 | }, 35 | code: number, 36 | message: string 37 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/TagEntity.ts: -------------------------------------------------------------------------------- 1 | declare type TagEntity = { 2 | id: string 3 | name: string 4 | } 5 | 6 | declare type TagSearchEntity = { 7 | id: string 8 | name: string 9 | } 10 | 11 | declare type ArticleTagEntity = TagSearchEntity 12 | 13 | declare type TagWithArticleCount = { 14 | id: string 15 | name: string, 16 | articleCount: number 17 | } 18 | 19 | // 标签列表 20 | declare type TagFrontEntity = { 21 | tags: Array 22 | newsArticleList: Array 23 | newsCommentList: Array 24 | } 25 | -------------------------------------------------------------------------------- /blog_vue/src/api/entity/TalkEntity.ts: -------------------------------------------------------------------------------- 1 | declare type TalkEntity = { 2 | user: SimpleUserInfoEntity 3 | id: string 4 | content: string 5 | isTop: boolean 6 | src: Array 7 | likeCount: number | null 8 | commentCount: number | null 9 | createTime: string | Date 10 | rectangle: string | null 11 | isLike: Boolean 12 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/UserEntity.ts: -------------------------------------------------------------------------------- 1 | declare type SimpleUserInfoEntity = { 2 | uid: string, 3 | nickname: string, 4 | avatar: string, 5 | intro: string, 6 | webSite: string 7 | } 8 | 9 | declare type UserEntity = { 10 | nickname: string 11 | uid: string 12 | email: string | null 13 | avatar: string 14 | articleLikeSet: Array 15 | commentLikeSet: Array 16 | talkLikeSet: Array 17 | token: string 18 | tokenHead: string 19 | } 20 | 21 | // 上传的文件信息 22 | declare type UploadFileInfoModel = { 23 | width: number 24 | height: number 25 | size: string 26 | url: string 27 | } 28 | 29 | // 用户信息 30 | declare type UserInfoModel = { 31 | email: string | null 32 | uid: string 33 | loginType: 0 34 | nickname: string 35 | avatar: string 36 | intro: string 37 | webSite: string 38 | isEmailNotice: boolean 39 | bindQQ: boolean 40 | createTime: string 41 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/WebSocketMessage.ts: -------------------------------------------------------------------------------- 1 | 2 | declare type ChatMessage = { 3 | sender: SimpleUserInfoEntity 4 | type: string, 5 | time: Date, 6 | ipSource: string, 7 | data: T 8 | } 9 | 10 | // 发送消息 11 | declare type SnedMessage = { 12 | uid: string, 13 | message: T 14 | } 15 | 16 | // 在线用户 17 | declare type OnlineUser = { 18 | uid: string 19 | nickname: string 20 | avatar: string 21 | ipAddress: string 22 | ipSource: string 23 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/WebsiteInfoEntity.ts: -------------------------------------------------------------------------------- 1 | declare type WebsiteInfoEntity = { 2 | articleCount: number, 3 | categoryCount: number, 4 | tagCount: number, 5 | viewsCount: number, 6 | onlyViewCount: number, 7 | websiteAvatar: string, 8 | websiteName: string, 9 | websiteAuthor: string, 10 | websiteIntro: string, 11 | websiteNotice: string, 12 | websiteCreateTime: string, 13 | websiteRecordNo: string, 14 | websiteBackgroundImages: Array, 15 | homeTyperTexts: Array 16 | socialLogin: {}, 17 | qq: string, 18 | wechat: string, 19 | touristAvatar: string, 20 | defaultAvatar: string, 21 | weiXinQRCode: string, 22 | alipayQRCode: string, 23 | isCommentReview: string, 24 | isMessageReview: string, 25 | isAutoPlayer: boolean, 26 | chatRoomNotice: string, 27 | } -------------------------------------------------------------------------------- /blog_vue/src/api/entity/YiYanEntity.ts: -------------------------------------------------------------------------------- 1 | declare type YiYanEntity = { 2 | id: number, 3 | uuid: string, 4 | hitokoto: string, 5 | type: string, 6 | from: string, 7 | from_who: string, 8 | creator: string, 9 | creator_uid: number, 10 | reviewer: number, 11 | commit_from: string, 12 | created_at: string, 13 | length: number 14 | } -------------------------------------------------------------------------------- /blog_vue/src/api/enum/StatusCode.ts: -------------------------------------------------------------------------------- 1 | export enum StatusCode { 2 | SUCCESS = 1000, // 成功 3 | UNAUTHORIZED = 1001, // 请登录 4 | USERNAME_PASSWORD_ERROR = 1002, // 用户名或密码错误 5 | AUTHORIZED = 1003, // 无权限 6 | EXPIRATION = 1004, // 登录状态过期,请重新登录 7 | EMAIL_EXIST = 1005, // 此邮箱已被注册 8 | EMAIL_NO_EXIST = 1006, // 此邮箱不存在 9 | NICKNAME_EXIST = 1007, // 昵称已存在 10 | DISABLE = 1008, // 账号被禁用 11 | FAIL = 1009, // 失败 12 | VALID_ERROR = 1010, // 参数不正确 13 | ACCESS_LIMIT = 1011, // 请求过于频繁,请稍后重试 14 | PAGE_NOT_FOUND = 404, // 页面不存在 15 | SERVER_ERROR = 500 // 服务器错误 16 | } -------------------------------------------------------------------------------- /blog_vue/src/api/enum/WebSocketEnum.ts: -------------------------------------------------------------------------------- 1 | // 聊天消息类型枚举 2 | export enum ChatMessageTypeEnum { 3 | CHAT = 1, // 聊天 4 | JOIN = 2, // 加入 5 | LEAVE = 3, // 离开 6 | } -------------------------------------------------------------------------------- /blog_vue/src/api/params/CommentParams.ts: -------------------------------------------------------------------------------- 1 | declare type commentParams = { 2 | commentContent: string 3 | parentId?: string 4 | replyCommentId?: string 5 | topicId: string 6 | type: number 7 | } 8 | 9 | // 查询评论参数 10 | declare type CommentQueryParams = { 11 | topicId: string, 12 | type: number, 13 | current?: number, 14 | size?: number 15 | } 16 | 17 | /** 18 | * 发送评论 19 | */ 20 | declare type SaveCommentParams = { 21 | topicId: string 22 | commentContent: string 23 | parentId?: string 24 | replyCommentId?: string 25 | type: number 26 | } 27 | -------------------------------------------------------------------------------- /blog_vue/src/api/params/ConditionParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 查询参数 3 | */ 4 | declare interface ConditionParams { 5 | albumPath?: string, 6 | articleId?: string, 7 | categoryId?: string, 8 | email?: string, 9 | endTime?: string, 10 | startTime?: string, 11 | isDelete?: boolean | null | number, 12 | isReview?: boolean | number | null, 13 | keywords?: string, 14 | loginType?: number, 15 | size?: number, 16 | current?: number, 17 | status?: number | null, 18 | tagId?: string, 19 | type?: number | null, 20 | } -------------------------------------------------------------------------------- /blog_vue/src/api/params/FriendLinkParams.ts: -------------------------------------------------------------------------------- 1 | declare type FriendLinkParams = { 2 | id?: string 3 | linkAvatar: string 4 | linkIntro: string 5 | linkName: string 6 | linkUrl: string 7 | } 8 | 9 | /** 10 | * 用户保存或修改友链 11 | */ 12 | declare type SaveOrUpdateFriendLink = { 13 | id?: string 14 | linkName: string 15 | linkAvatar: string 16 | linkUrl: string 17 | linkIntro: string 18 | } -------------------------------------------------------------------------------- /blog_vue/src/api/params/UserParams.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 用户登录参数 3 | */ 4 | declare type UserLoginParams = { 5 | username: string 6 | password: string 7 | captchaVerification: string 8 | } 9 | 10 | /** 11 | * QQ登录参数 12 | */ 13 | declare type QQLoginParams = { 14 | accessToken: string 15 | openId: string 16 | } 17 | 18 | /** 19 | * 修改用户信息 20 | */ 21 | declare type UserInfoParams = { 22 | intro: string 23 | isEmailNotice: boolean 24 | nickname: string 25 | webSite: string 26 | } 27 | 28 | /** 29 | * 绑定或解绑邮箱 30 | */ 31 | declare type BindOrUnBindEmail = { 32 | captchaVerification: string 33 | code: string 34 | email: string 35 | } 36 | 37 | /** 38 | * 更新密码 39 | */ 40 | declare type UpdatePasswordParams = { 41 | oldPassword: string 42 | newPassword: string 43 | code: string 44 | captchaVerification: string 45 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/Album.ts: -------------------------------------------------------------------------------- 1 | import {request} from "@/api/services" 2 | 3 | /** 4 | * 获取相册列表 5 | * @param condition 6 | */ 7 | export function getAlbums(condition: ConditionParams): Promise>> { 8 | return request.get({ 9 | url: "/albums", 10 | params: condition, 11 | isDecrypt: true 12 | }) 13 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/Category.ts: -------------------------------------------------------------------------------- 1 | import {request} from "@/api/services" 2 | 3 | /** 4 | * 获取分类列表 5 | */ 6 | export function getCategories(): Promise> { 7 | return request.get({ 8 | url: '/categories', 9 | isDecrypt: true 10 | }) 11 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/ChatRoom.ts: -------------------------------------------------------------------------------- 1 | import { request } from '@/api/services' 2 | 3 | // 获取聊天室游客信息 4 | export function getChatVisitorInfo(): Promise> { 5 | return request.get({ 6 | url: '/getChatVisitorInfo' 7 | }) 8 | } 9 | 10 | // 获取在线用户列表 11 | export function getOnlineUserList(): Promise>> { 12 | return request.get({ 13 | url: '/getOnlineUserList' 14 | }) 15 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/FriendLink.ts: -------------------------------------------------------------------------------- 1 | import { request } from "@/api/services" 2 | 3 | /** 4 | * 获取友链列表 5 | * @param size 6 | * @param current 7 | */ 8 | export function getFriendLink({ size, current }: ConditionParams): Promise>> { 9 | return request.get({ 10 | url: "/links", 11 | params: { size, current } 12 | }) 13 | } 14 | 15 | /** 16 | * 保存或修改友链 17 | * @param data 18 | */ 19 | export function saveOrUpdateFriendLink(data: SaveOrUpdateFriendLink): Promise> { 20 | return request.post({ 21 | url: "/user/link", 22 | data 23 | }) 24 | } 25 | 26 | /** 27 | * 获取用户友链 28 | */ 29 | export function getUserFriendLink(): Promise>> { 30 | return request.get({ 31 | url: "/user/link", 32 | }) 33 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/Message.ts: -------------------------------------------------------------------------------- 1 | import {request} from "@/api/services" 2 | 3 | /** 4 | * 获取留言列表 5 | * @param condition 6 | */ 7 | export function getMessages(condition: ConditionParams): Promise>> { 8 | return request.get({ 9 | url: "/messages", 10 | params: condition, 11 | isDecrypt: true 12 | }) 13 | } 14 | 15 | /** 16 | * 添加留言 17 | * @param data 18 | */ 19 | export function saveMessage(data: {content: string, theme: string}): Promise> { 20 | return request.post({ 21 | url: "/message", 22 | data, 23 | isEncrypt: true, 24 | }) 25 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/Notice.ts: -------------------------------------------------------------------------------- 1 | import {request} from "@/api/services" 2 | 3 | /** 4 | * 获取用户通知列表 5 | * @param isRead 6 | * @param current 7 | * @param size 8 | */ 9 | export function getUserNotices(isRead: boolean, {current, size}: ConditionParams): Promise>> { 10 | return request.get({ 11 | url: "/user/notice", 12 | params: {isRead, current, size}, 13 | isDecrypt: true 14 | }) 15 | } 16 | 17 | /** 18 | * 更新通知已阅 19 | * @param noticeList 20 | */ 21 | export function updateNotice(noticeList: Array): Promise> { 22 | return request.put({ 23 | url: "/user/notice", 24 | data: noticeList 25 | }) 26 | } 27 | 28 | /** 29 | * 获取用户未阅通知数量 30 | */ 31 | export function getUserNoReadNoticeCount(): Promise> { 32 | return request.get({ 33 | url: "/user/notice/noread" 34 | }) 35 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/Picture.ts: -------------------------------------------------------------------------------- 1 | import {request} from "@/api/services" 2 | 3 | /** 4 | * 根据相册id获取图片 5 | * @param albumId 6 | */ 7 | export function getPicturesByAlbumId(condition: ConditionParams): Promise, PictureAlbumInfoEntity>> { 8 | return request.get({ 9 | url: `/album/${condition.albumPath}/pictures`, 10 | params: condition, 11 | isDecrypt: true 12 | }) 13 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/SystemInfo.ts: -------------------------------------------------------------------------------- 1 | import { request } from '@/api/services' 2 | 3 | export function getOnlineCount(): Promise> { 4 | return request.get({ 5 | url: '/getOnlineCount' 6 | }) 7 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/Tag.ts: -------------------------------------------------------------------------------- 1 | import {request} from "@/api/services" 2 | 3 | /** 4 | * 获取标签列表 5 | * @param condition 6 | */ 7 | export function getTags(condition: ConditionParams): Promise> { 8 | return request.get({ 9 | url: "/tags", 10 | params: condition, 11 | isDecrypt: true 12 | }) 13 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/Talk.ts: -------------------------------------------------------------------------------- 1 | import {request} from "@/api/services" 2 | import {useWebsiteInfoStore} from "@/store"; 3 | import {storeToRefs} from "pinia"; 4 | 5 | /** 6 | * 获取说说列表 7 | * @param size 8 | * @param current 9 | */ 10 | export function getTalk({size, current}: ConditionParams): Promise>> { 11 | return request.get({ 12 | url: "/talks", 13 | params: {size, current}, 14 | isDecrypt: true 15 | }) 16 | } 17 | 18 | /** 19 | * 根据说说id获取说说 20 | * @param talkId 21 | */ 22 | export function getTalkByTalkId(talkId: string): Promise> { 23 | const {rectangle} = storeToRefs(useWebsiteInfoStore()); 24 | return request.get({ 25 | headers: { 26 | "rectangle": rectangle.value 27 | }, 28 | url: `/talk/${talkId}`, 29 | isDecrypt: true 30 | }) 31 | } 32 | 33 | /** 34 | * 点赞说说 35 | * @param talkId 36 | */ 37 | export function talkLike(talkId: string): Promise> { 38 | return request.post({ 39 | url: `/user/talk/${talkId}/like` 40 | }) 41 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/WebsiteInfo.ts: -------------------------------------------------------------------------------- 1 | import {request} from '@/api/services' 2 | 3 | /** 4 | * 获取博客信息 5 | */ 6 | export function getBlogInfo(): Promise> { 7 | return request.get({ 8 | url: '/', 9 | isDecrypt: true 10 | }) 11 | } 12 | 13 | /** 14 | * 获取关于我 15 | */ 16 | export function getAbout(): Promise> { 17 | return request.get({ 18 | url: "/about" 19 | }) 20 | } -------------------------------------------------------------------------------- /blog_vue/src/api/requests/YiYan.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export function getYiYan(): Promise { 4 | return axios.get('https://v1.hitokoto.cn').then((resp) => resp.data) 5 | } -------------------------------------------------------------------------------- /blog_vue/src/api/services.ts: -------------------------------------------------------------------------------- 1 | import BlogXmlRequest from "@/api/config"; 2 | 3 | let blogBase = import.meta.env.VITE_API_URL; 4 | 5 | const request = new BlogXmlRequest({ 6 | timeout: 10000, 7 | baseURL: `${blogBase}`, 8 | headers: { 9 | 'X-Requested-With': 'XMLHttpRequest', 10 | 'Content-Type': 'application/json; charset=utf-8' 11 | } 12 | }) 13 | 14 | 15 | export { 16 | request, 17 | } -------------------------------------------------------------------------------- /blog_vue/src/assets/css/dark.css: -------------------------------------------------------------------------------- 1 | :root.dark { 2 | --font-size: 14px; 3 | --theme-bg: rgb(30, 32, 32); 4 | --theme-bg2: rgb(47, 50, 52); 5 | --theme-translucent: rgb(30, 32, 32, 0.6); 6 | --theme-translucent-reverse: rgb(224, 224, 224, 0.6); 7 | --theme-bg-reverse: rgb(224, 224, 224); 8 | --text-color: rgb(255, 255, 255); 9 | --text-color-reverse: rgb(30, 32, 32); 10 | --text-color2: rgb(206, 214, 224); 11 | 12 | /*.wares style*/ 13 | --parallax-1: rgba(30, 32, 32, 0.7); 14 | --parallax-2: rgba(30, 32, 32, 0.5); 15 | --parallax-3: rgba(30, 32, 32, 0.3); 16 | --parallax-4: rgba(30, 32, 32, 1); 17 | 18 | --theme-shadow: 3px 3px 7px #141515, 19 | -4px -4px 7px #2F3234; 20 | 21 | --theme-shadow-inset: 2px 2px 6px #141515 inset, 22 | -2px -2px 6px #2F3234 inset; 23 | 24 | --theme-shadow-reverse: 3px 3px 7px #c5c5c5, 25 | -3px -3px 8px #ffffff; 26 | 27 | --theme-shadow-inset-reverse: 2px 2px 6px #c5c5c5 inset, 28 | -3px -3px 8px #ffffff inset; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /blog_vue/src/assets/css/light.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --font-size: 14px; 3 | --theme-bg: rgb(224, 224, 224); 4 | --theme-bg2: rgb(255, 255, 255); 5 | --theme-translucent: rgb(224, 224, 224, 0.6); 6 | --theme-translucent-reverse: rgb(30, 32, 32, 0.6); 7 | --theme-bg-reverse: rgb(30, 32, 32); 8 | --text-color: rgb(30, 32, 32); 9 | --text-color-reverse: rgb(255, 255, 255); 10 | --text-color2: rgb(87, 96, 111); 11 | 12 | /*.wares style*/ 13 | --parallax-1: rgba(224, 224, 224, 0.7); 14 | --parallax-2: rgba(224, 224, 224, 0.5); 15 | --parallax-3: rgba(224, 224, 224, 0.3); 16 | --parallax-4: rgba(224, 224, 224, 1); 17 | 18 | --theme-shadow: 3px 3px 7px #c5c5c5, 19 | -3px -3px 8px #ffffff; 20 | 21 | --theme-shadow-inset: 2px 2px 6px #c5c5c5 inset, 22 | -3px -3px 8px #ffffff inset; 23 | 24 | --theme-shadow-reverse: 3px 3px 7px #141515, 25 | -4px -4px 7px #2F3234; 26 | 27 | --theme-shadow-inset-reverse: 2px 2px 6px #141515 inset, 28 | -2px -2px 6px #2F3234 inset; 29 | } -------------------------------------------------------------------------------- /blog_vue/src/assets/fonts/ZhuZiAWan.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog_vue/src/assets/fonts/ZhuZiAWan.woff2 -------------------------------------------------------------------------------- /blog_vue/src/assets/imgs/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog_vue/src/assets/imgs/heart.png -------------------------------------------------------------------------------- /blog_vue/src/assets/imgs/public_security_record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog_vue/src/assets/imgs/public_security_record.png -------------------------------------------------------------------------------- /blog_vue/src/assets/imgs/qq_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apecodex/blog/b70cc7906a98a66bfd3677dc83b3aa6eef13f35f/blog_vue/src/assets/imgs/qq_login.png -------------------------------------------------------------------------------- /blog_vue/src/components/AppMain.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | 19 | -------------------------------------------------------------------------------- /blog_vue/src/components/BoxComponent.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /blog_vue/src/components/Mask.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /blog_vue/src/components/layout/header/website/ChatRoomBtn.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | -------------------------------------------------------------------------------- /blog_vue/src/components/modal/FriendLinkHooks.ts: -------------------------------------------------------------------------------- 1 | import {computed, reactive, ref} from "vue"; 2 | 3 | const lockBtn = ref(false) 4 | 5 | const friendLinkForm = reactive({ 6 | id: "", 7 | linkAvatar: "", 8 | linkIntro: "", 9 | linkName: "", 10 | linkUrl: "" 11 | } as FriendLinkParams) 12 | 13 | // 清空表单 14 | const clearFriendLinkForm = () => { 15 | friendLinkForm.id = ""; 16 | friendLinkForm.linkAvatar = ""; 17 | friendLinkForm.linkIntro = ""; 18 | friendLinkForm.linkName = ""; 19 | friendLinkForm.linkUrl = ""; 20 | } 21 | 22 | // 是否填了 23 | const checkFriendLinkForm = computed(() => { 24 | const linkAvatar = friendLinkForm.linkAvatar?.length === 0; 25 | const linkName = friendLinkForm.linkName?.length === 0; 26 | const linkUrl = friendLinkForm.linkUrl?.length === 0; 27 | return linkAvatar || linkName || linkUrl || !lockBtn; 28 | }) 29 | 30 | 31 | export { 32 | lockBtn, 33 | friendLinkForm, 34 | clearFriendLinkForm, 35 | checkFriendLinkForm 36 | } -------------------------------------------------------------------------------- /blog_vue/src/components/skeleton/Skeleton.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /blog_vue/src/components/verifition/api/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 此处可直接引用自己项目封装好的 axios 配合后端联调 3 | */ 4 | 5 | 6 | import request from "./../utils/axios" //组件内部封装的axios 7 | // import request from "@/api/axios.js" //调用项目封装的axios 8 | 9 | //获取验证图片 以及token 10 | export function reqGet(data) { 11 | return request({ 12 | url: '/captcha/get', 13 | method: 'post', 14 | data 15 | }) 16 | } 17 | 18 | //滑动或者点选验证 19 | export function reqCheck(data) { 20 | return request({ 21 | url: '/captcha/check', 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /blog_vue/src/components/verifition/utils/ase.js: -------------------------------------------------------------------------------- 1 | import CryptoJS from 'crypto-js' 2 | /** 3 | * @word 要加密的内容 4 | * @keyWord String 服务器随机返回的关键字 5 | * */ 6 | export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){ 7 | var key = CryptoJS.enc.Utf8.parse(keyWord); 8 | var srcs = CryptoJS.enc.Utf8.parse(word); 9 | var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}); 10 | return encrypted.toString(); 11 | } 12 | -------------------------------------------------------------------------------- /blog_vue/src/components/verifition/utils/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const service = axios.create({ 4 | timeout: 40000, 5 | headers: { 6 | 'X-Requested-With': 'XMLHttpRequest', 7 | 'Content-Type': 'application/json; charset=UTF-8' 8 | }, 9 | }) 10 | service.interceptors.request.use( 11 | config => { 12 | config.baseURL = import.meta.env.VITE_API_URL; 13 | return config 14 | }, 15 | error => { 16 | Promise.reject(error) 17 | } 18 | ) 19 | 20 | // response interceptor 21 | service.interceptors.response.use( 22 | response => { 23 | const res = response.data; 24 | return res 25 | }, 26 | error => { 27 | } 28 | ) 29 | export default service 30 | -------------------------------------------------------------------------------- /blog_vue/src/config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | // qq appid 3 | QQ_APPID: "", 4 | // qq回调地址 5 | QQ_REDIRECT_URI: "" 6 | } -------------------------------------------------------------------------------- /blog_vue/src/constant.ts: -------------------------------------------------------------------------------- 1 | // 默认图片 2 | export const loadingImg = "https://apecode.oss-cn-chengdu.aliyuncs.com/config/bdaea39db57dc0b48d763262514268db.gif" 3 | // 表情包加载中 4 | export const emojiLoadingImg = "https://apecode.oss-cn-chengdu.aliyuncs.com/config/075864206c78ca820b742056ea0d85c1.svg" 5 | // 评论背景 6 | export const commentBg = ["https://apecode.oss-cn-chengdu.aliyuncs.com/config/62fe96fcf50c3f1b0822bebdf1e6c280.gif", "https://apecode.oss-cn-chengdu.aliyuncs.com/config/7750e382c372aad43c12a7423cae83bb.gif"] 7 | // 公钥 8 | export const publicKey = "-----BEGIN PUBLIC KEY-----公钥-----END PUBLIC KEY-----"; 9 | // 私钥 10 | export const privateKey = "-----BEGIN RSA PRIVATE KEY-----私钥-----END RSA PRIVATE KEY-----"; -------------------------------------------------------------------------------- /blog_vue/src/directives/Lazy.ts: -------------------------------------------------------------------------------- 1 | // 图片懒加载 2 | export default { 3 | mounted: (el: HTMLImageElement) => { 4 | const imgSrc = el.getAttribute("data-src"); 5 | const observer = new IntersectionObserver(([{isIntersecting}]) => { 6 | // 元素出现在可视区域,和离开可视区域被触发 7 | if (isIntersecting) { 8 | // 加载图片 9 | el.src = imgSrc as string 10 | observer.unobserve(el); 11 | } 12 | }) 13 | observer.observe(el) 14 | } 15 | } -------------------------------------------------------------------------------- /blog_vue/src/directives/index.ts: -------------------------------------------------------------------------------- 1 | import type {App} from "vue" 2 | import lazy from "./Lazy" 3 | 4 | export function setupDirective(app: App) { 5 | app.directive("lazy", lazy); 6 | } -------------------------------------------------------------------------------- /blog_vue/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // 获取自定义环境变量的 智能提示 4 | interface ImportMetaEnv { 5 | readonly VITE_API_URL: string 6 | } 7 | 8 | interface ImportMeta { 9 | readonly env: ImportMetaEnv 10 | } -------------------------------------------------------------------------------- /blog_vue/src/layout/LRLayout.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | 16 | -------------------------------------------------------------------------------- /blog_vue/src/layout/PageLayout.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | -------------------------------------------------------------------------------- /blog_vue/src/main.ts: -------------------------------------------------------------------------------- 1 | import {createApp} from 'vue' 2 | import '@/assets/css/base.css' 3 | import App from './App.vue' 4 | import {setupStore} from '@/store' 5 | import {setupRouter} from '@/router' 6 | import {setupDirective} from "@/directives" 7 | import Notifications from '@kyvg/vue3-notification' 8 | import 'virtual:windi.css' 9 | import 'virtual:windi-devtools' 10 | 11 | const app = createApp(App) 12 | setupStore(app) 13 | setupRouter(app) 14 | setupDirective(app) 15 | // 通知状态 16 | app.use(Notifications) 17 | app.mount('#app') 18 | 19 | console.clear(); 20 | console.log('%c作者:apecode.','color:pink'); 21 | console.log('%cQQ: 1473018671','color: red;'); 22 | console.log('%cgithub: https://github.com/apecodex','color: green;'); -------------------------------------------------------------------------------- /blog_vue/src/settings.ts: -------------------------------------------------------------------------------- 1 | export interface SettingConfig { 2 | globalTheme: 'darkTheme' | 'lightTheme', 3 | // 文章预览主题 4 | previewTheme: 'default' | 'github' | 'vuepress' | 'mk-cute' | 'smart-blue' | 'cyanosis', 5 | // 文章代码主题 6 | codeTheme: 'atom' | 'a11y' | 'github' | 'gradient' | 'kimbie' | 'paraiso' | 'qtcreator' | 'stackoverflow' 7 | // 代码是否展示行号 8 | showCodeRowNumber: boolean 9 | loginFlag: boolean, 10 | registerFlag: boolean, 11 | searchFlag: boolean, 12 | loadingFlag: boolean, 13 | friendLinkFlag: boolean, 14 | articleThemeFlag: boolean, 15 | forgetPasswordFlag: boolean, 16 | bindOrUnbindEmailFlag: boolean, 17 | } 18 | 19 | export default { 20 | globalTheme: 'darkTheme', 21 | previewTheme: 'cyanosis', 22 | codeTheme: 'github', 23 | showCodeRowNumber: true, 24 | loginFlag: false, 25 | registerFlag: false, 26 | searchFlag: false, 27 | loadingFlag: false, 28 | friendLinkFlag: false, 29 | articleThemeFlag: false, 30 | forgetPasswordFlag: false, 31 | bindOrUnbindEmailFlag: false 32 | } as SettingConfig -------------------------------------------------------------------------------- /blog_vue/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { App } from 'vue' 2 | import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' 3 | import { createPinia } from "pinia"; 4 | 5 | export { useGlobalStore } from "./modules/global" 6 | export { useSettingStore } from './modules/setting' 7 | export { useWebsiteInfoStore } from './modules/websiteInfo' 8 | export { useUserInfoStore } from './modules/userInfo' 9 | export { useWebSocketStore } from "./modules/websocket" 10 | 11 | const store = createPinia(); 12 | store.use(piniaPluginPersistedstate) 13 | 14 | export function setupStore(app: App) { 15 | app.use(store); 16 | } -------------------------------------------------------------------------------- /blog_vue/src/store/modules/global.ts: -------------------------------------------------------------------------------- 1 | import type {Ref} from "vue" 2 | import Names from "@/store/modules/store-name"; 3 | import {defineStore} from "pinia"; 4 | import {nextTick, ref} from "vue"; 5 | 6 | export const useGlobalStore = defineStore(Names.GLOBAL, () => { 7 | let isRouterAlive: Ref = ref(true) 8 | 9 | 10 | // 刷新局部组件 11 | const reload = async () => { 12 | isRouterAlive.value = false 13 | await nextTick(() => { 14 | isRouterAlive.value = true 15 | }) 16 | } 17 | 18 | return { 19 | isRouterAlive, 20 | reload 21 | } 22 | }) -------------------------------------------------------------------------------- /blog_vue/src/store/modules/store-name.ts: -------------------------------------------------------------------------------- 1 | const enum Names { 2 | GLOBAL = "WebGlobal_Blog", 3 | SETTING = "WebSetting_Blog", 4 | WEBSITE = "WebsiteInfo_Blog", 5 | USERINFO = "UserInfo_Blog", 6 | WEBSOCKET = "WebSocket_Blog" 7 | } 8 | 9 | export default Names -------------------------------------------------------------------------------- /blog_vue/src/store/modules/websiteInfo.ts: -------------------------------------------------------------------------------- 1 | import Names from "./store-name" 2 | import type { Ref } from "vue" 3 | import { defineStore } from "pinia"; 4 | import { ref } from "vue"; 5 | 6 | export const useWebsiteInfoStore = defineStore(Names.WEBSITE, () => { 7 | const websiteInfo: Ref = ref(null); 8 | // 用户经纬度 9 | const rectangle = ref(""); 10 | 11 | // 第三方登录前的url地址 12 | const originalLoginUrl = ref(""); 13 | 14 | // 在线人数 15 | const onlineCount: Ref = ref(0); 16 | 17 | // 更改在线人数 18 | const changeOnlineCount = (count: number) => { 19 | onlineCount.value = count; 20 | } 21 | 22 | // 保持网站信息 23 | const saveWebsiteInfo = (info: WebsiteInfoEntity) => { 24 | websiteInfo.value = info 25 | } 26 | 27 | return { 28 | websiteInfo, 29 | saveWebsiteInfo, 30 | rectangle, 31 | originalLoginUrl, 32 | onlineCount, 33 | changeOnlineCount 34 | } 35 | }, { persist: { storage: sessionStorage } }) -------------------------------------------------------------------------------- /blog_vue/src/utils/rsa.ts: -------------------------------------------------------------------------------- 1 | import JSEncrypt from 'jsencrypt' 2 | import { publicKey, privateKey } from '@/constant'; 3 | 4 | export default class RSAUtil { 5 | 6 | public static encryptByPublicKey(data: { key: string, keyIV: string }): string | boolean { 7 | let plaintext = JSON.stringify(data); 8 | const encryptor = new JSEncrypt() 9 | encryptor.setPublicKey(publicKey) 10 | return encryptor.encrypt(plaintext) 11 | } 12 | 13 | public static decryptByPrivateKey(content: string): string | boolean { 14 | const decrypt = new JSEncrypt(); 15 | decrypt.setPrivateKey(privateKey); 16 | const decryptedContent = decrypt.decrypt(content); 17 | return decryptedContent; 18 | } 19 | } -------------------------------------------------------------------------------- /blog_vue/src/views/about/AboutHooks.ts: -------------------------------------------------------------------------------- 1 | import type {Ref} from "vue" 2 | import {ref} from "vue" 3 | import {getAbout} from "@/api/requests/WebsiteInfo" 4 | import {useSettingStore} from "@/store" 5 | import {storeToRefs} from "pinia"; 6 | import {notify} from "@kyvg/vue3-notification" 7 | import {scrollDown} from "@/utils/utils"; 8 | 9 | const settingStore = useSettingStore(); 10 | const {loadingFlag} = storeToRefs(settingStore); 11 | 12 | const aboutData: Ref = ref(null); 13 | 14 | const createAboutData = async () => { 15 | loadingFlag.value = true; 16 | aboutData.value = null; 17 | await getAbout().then((resp: ResultObject) => { 18 | if (resp.status) { 19 | aboutData.value = resp.data 20 | } 21 | }).catch(() => { 22 | notify({ 23 | text: "数据获取失败,请重试", 24 | type: "warn" 25 | }); 26 | }).finally(() => { 27 | loadingFlag.value = false; 28 | scrollDown(); 29 | }) 30 | } 31 | 32 | export { 33 | aboutData, 34 | createAboutData 35 | } -------------------------------------------------------------------------------- /blog_vue/src/views/archive/ArchiveHooks.ts: -------------------------------------------------------------------------------- 1 | import type {Ref} from "vue" 2 | import {getArticleArchives} from "@/api/requests/Article" 3 | import {useSettingStore} from "@/store" 4 | import {storeToRefs} from "pinia"; 5 | import {notify} from "@kyvg/vue3-notification" 6 | import {ref} from "vue"; 7 | import {scrollDown} from "@/utils/utils"; 8 | 9 | const settingStore = useSettingStore(); 10 | const {loadingFlag} = storeToRefs(settingStore); 11 | 12 | const archivesData: Ref | null> = ref(null); 13 | 14 | const createArchives = async () => { 15 | loadingFlag.value = true; 16 | await getArticleArchives().then((resp: ResultObject>) => { 17 | if (resp.status) { 18 | archivesData.value = resp.data; 19 | } 20 | }).catch(() => { 21 | notify({ 22 | text: "归档获取失败,请重试", 23 | type: "warn" 24 | }) 25 | }).finally(() => { 26 | loadingFlag.value = false; 27 | scrollDown(); 28 | }) 29 | } 30 | 31 | 32 | export { 33 | archivesData, 34 | createArchives 35 | } -------------------------------------------------------------------------------- /blog_vue/src/views/comm/CommentUser.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 26 | 27 | -------------------------------------------------------------------------------- /blog_vue/src/views/home/Home.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | -------------------------------------------------------------------------------- /blog_vue/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 | 9 | declare module 'canvas-confetti' -------------------------------------------------------------------------------- /blog_vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "moduleResolution": "Node", 7 | "strict": true, 8 | "jsx": "preserve", 9 | "sourceMap": true, 10 | "resolveJsonModule": true, 11 | "isolatedModules": false, 12 | "esModuleInterop": true, 13 | "lib": [ 14 | "ESNext", 15 | "DOM" 16 | ], 17 | "skipLibCheck": true, 18 | "types": [ 19 | "node" 20 | ], 21 | "paths": { 22 | "@/*": [ 23 | "./src/*" 24 | ] 25 | } 26 | }, 27 | "include": [ 28 | "src/**/*.ts", 29 | "src/**/*.d.ts", 30 | "src/**/*.tsx", 31 | "src/**/*.vue", 32 | "./*.d.ts" 33 | ], 34 | "references": [ 35 | { 36 | "path": "./tsconfig.node.json" 37 | } 38 | ] 39 | } -------------------------------------------------------------------------------- /blog_vue/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts", "vite.base.config.ts", "vite.dev.config.ts", "vite.prod.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /blog_vue/vite.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig, UserConfigExport} from 'vite' 2 | 3 | import viteBaseConfig from './vite.base.config' 4 | import viteDevConfig from './vite.dev.config' 5 | import viteProdConfig from './vite.prod.config' 6 | 7 | const envResolver = { 8 | 'build': () => ({...viteBaseConfig, ...viteProdConfig}), 9 | 'serve': () => ({...viteBaseConfig, ...viteDevConfig}) 10 | } as UserConfigExport 11 | 12 | export default defineConfig(({command}) => { 13 | return envResolver[command](); 14 | }) -------------------------------------------------------------------------------- /blog_vue/vite.dev.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig, UserConfigExport} from 'vite' 2 | 3 | export default defineConfig({ 4 | server: { 5 | host: true, 6 | port: 5173 7 | } 8 | }) as UserConfigExport 9 | -------------------------------------------------------------------------------- /blog_vue/vite.prod.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig, UserConfigExport} from 'vite' 2 | 3 | export default defineConfig({ 4 | build: { 5 | outDir: 'dist', //指定输出路径 6 | assetsDir: 'static/img/', // 指定生成静态资源的存放路径 7 | rollupOptions: { 8 | output: { 9 | manualChunks(id) { 10 | if (id.includes('node_modules')) { 11 | const arr = id.toString().split('node_modules/')[1].split('/') 12 | switch (arr[0]) { 13 | case 'windicss': 14 | case '@icon-park/vue-next': 15 | return '_' + arr[0] 16 | break 17 | default: 18 | return '__vendor' 19 | break 20 | } 21 | } 22 | }, 23 | chunkFileNames: 'static/js1/[name]-[hash].js', 24 | entryFileNames: 'static/js2/[name]-[hash].js', 25 | assetFileNames: 'static/[ext]/[name]-[hash].[ext]' 26 | }, 27 | }, 28 | target: 'es2015' 29 | }, 30 | server: { 31 | host: true, 32 | port: 5173 33 | } 34 | }) as UserConfigExport 35 | -------------------------------------------------------------------------------- /blog_vue/windi.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'windicss/helpers' 2 | 3 | export default defineConfig({ 4 | darkMode: 'class', 5 | }); --------------------------------------------------------------------------------