├── pic
├── home.png
├── detail.png
├── 移动端详情页.png
└── 移动端首页.png
├── weblog-vue3
├── public
│ └── favicon.ico
├── src
│ ├── assets
│ │ ├── no-data.png
│ │ ├── developer.png
│ │ ├── weblog-logo.png
│ │ ├── weblog-logo-mini.png
│ │ ├── logo.svg
│ │ └── main.css
│ ├── api
│ │ ├── admin
│ │ │ ├── file.js
│ │ │ ├── blogsettings.js
│ │ │ ├── user.js
│ │ │ ├── comment.js
│ │ │ ├── dashboard.js
│ │ │ ├── category.js
│ │ │ ├── tag.js
│ │ │ ├── article.js
│ │ │ └── wiki.js
│ │ └── frontend
│ │ │ ├── search.js
│ │ │ ├── statistics.js
│ │ │ ├── archive.js
│ │ │ ├── blogsettings.js
│ │ │ ├── tag.js
│ │ │ ├── article.js
│ │ │ ├── category.js
│ │ │ ├── wiki.js
│ │ │ └── comment.js
│ ├── stores
│ │ ├── index.js
│ │ ├── comment.js
│ │ ├── menu.js
│ │ ├── blogsettings.js
│ │ └── user.js
│ ├── components
│ │ ├── icons
│ │ │ ├── IconSupport.vue
│ │ │ ├── IconTooling.vue
│ │ │ ├── IconCommunity.vue
│ │ │ └── IconDocumentation.vue
│ │ ├── CountTo.vue
│ │ ├── ArticlePVLineChat.vue
│ │ └── FormDialog.vue
│ ├── layouts
│ │ ├── admin
│ │ │ └── components
│ │ │ │ └── AdminFooter.vue
│ │ └── frontend
│ │ │ └── components
│ │ │ ├── Footer.vue
│ │ │ ├── WikiFooter.vue
│ │ │ └── ScrollToTopButton.vue
│ ├── App.vue
│ ├── composables
│ │ ├── util.js
│ │ └── cookie.js
│ ├── main.js
│ ├── permission.js
│ └── axios.js
├── postcss.config.js
├── tailwind.config.js
├── index.html
├── .gitignore
├── README.md
├── package.json
└── vite.config.js
├── weblog-springboot
├── weblog-module-admin
│ ├── src
│ │ ├── main
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── quanxiaoha
│ │ │ │ └── weblog
│ │ │ │ └── admin
│ │ │ │ ├── package-info.java
│ │ │ │ ├── model
│ │ │ │ ├── package-info.java
│ │ │ │ └── vo
│ │ │ │ │ ├── file
│ │ │ │ │ └── UploadFileRspVO.java
│ │ │ │ │ ├── wiki
│ │ │ │ │ ├── DeleteWikiReqVO.java
│ │ │ │ │ ├── FindWikiCatalogListReqVO.java
│ │ │ │ │ ├── UpdateWikiIsTopReqVO.java
│ │ │ │ │ ├── UpdateWikiIsPublishReqVO.java
│ │ │ │ │ ├── UpdateWikiCatalogReqVO.java
│ │ │ │ │ ├── FindWikiPageListReqVO.java
│ │ │ │ │ ├── FindWikiCatalogListRspVO.java
│ │ │ │ │ ├── AddWikiReqVO.java
│ │ │ │ │ ├── UpdateWikiCatalogItemReqVO.java
│ │ │ │ │ ├── UpdateWikiReqVO.java
│ │ │ │ │ └── FindWikiPageListRspVO.java
│ │ │ │ │ ├── comment
│ │ │ │ │ ├── DeleteCommentReqVO.java
│ │ │ │ │ ├── ExamineCommentReqVO.java
│ │ │ │ │ ├── FindCommentPageListRspVO.java
│ │ │ │ │ └── FindCommentPageListReqVO.java
│ │ │ │ │ ├── tag
│ │ │ │ │ ├── DeleteTagReqVO.java
│ │ │ │ │ ├── SearchTagsReqVO.java
│ │ │ │ │ ├── AddTagReqVO.java
│ │ │ │ │ ├── FindTagPageListRspVO.java
│ │ │ │ │ └── FindTagPageListReqVO.java
│ │ │ │ │ ├── article
│ │ │ │ │ ├── DeleteArticleReqVO.java
│ │ │ │ │ ├── FindArticleDetailReqVO.java
│ │ │ │ │ ├── UpdateArticleIsTopReqVO.java
│ │ │ │ │ ├── FindArticlePageListRspVO.java
│ │ │ │ │ ├── FindArticlePageListReqVO.java
│ │ │ │ │ ├── FindArticleDetailRspVO.java
│ │ │ │ │ ├── PublishArticleReqVO.java
│ │ │ │ │ └── UpdateArticleReqVO.java
│ │ │ │ │ ├── dashboard
│ │ │ │ │ ├── FindDashboardPVStatisticsInfoRspVO.java
│ │ │ │ │ └── FindDashboardStatisticsInfoRspVO.java
│ │ │ │ │ ├── user
│ │ │ │ │ ├── FindUserInfoRspVO.java
│ │ │ │ │ └── UpdateAdminUserPasswordReqVO.java
│ │ │ │ │ ├── category
│ │ │ │ │ ├── DeleteCategoryReqVO.java
│ │ │ │ │ ├── AddCategoryReqVO.java
│ │ │ │ │ ├── FindCategoryPageListRspVO.java
│ │ │ │ │ └── FindCategoryPageListReqVO.java
│ │ │ │ │ └── blogsettings
│ │ │ │ │ ├── FindBlogSettingsRspVO.java
│ │ │ │ │ └── UpdateBlogSettingsReqVO.java
│ │ │ │ ├── service
│ │ │ │ ├── package-info.java
│ │ │ │ ├── AdminStatisticsService.java
│ │ │ │ ├── AdminFileService.java
│ │ │ │ ├── AdminDashboardService.java
│ │ │ │ ├── AdminUserService.java
│ │ │ │ ├── AdminBlogSettingsService.java
│ │ │ │ ├── AdminCommentService.java
│ │ │ │ ├── AdminTagService.java
│ │ │ │ ├── AdminCategoryService.java
│ │ │ │ └── AdminArticleService.java
│ │ │ │ ├── event
│ │ │ │ ├── DeleteArticleEvent.java
│ │ │ │ ├── UpdateArticleEvent.java
│ │ │ │ ├── PublishArticleEvent.java
│ │ │ │ ├── UpdateCommentEvent.java
│ │ │ │ └── ReadArticleEvent.java
│ │ │ │ ├── config
│ │ │ │ ├── MinioProperties.java
│ │ │ │ ├── MinioConfig.java
│ │ │ │ └── TheadPoolConfig.java
│ │ │ │ ├── convert
│ │ │ │ ├── CommentConvert.java
│ │ │ │ ├── ArticleDetailConvert.java
│ │ │ │ ├── WikiConvert.java
│ │ │ │ └── BlogSettingsConvert.java
│ │ │ │ ├── runner
│ │ │ │ ├── StatisticsTagArticleTotalRunner.java
│ │ │ │ └── StatisticsCategoryArticleTotalRunner.java
│ │ │ │ ├── controller
│ │ │ │ └── AdminFileController.java
│ │ │ │ └── schedule
│ │ │ │ └── InitPVRecordScheduledTask.java
│ │ └── test
│ │ │ └── java
│ │ │ └── com
│ │ │ └── quanxiaoha
│ │ │ └── weblog
│ │ │ └── admin
│ │ │ └── WeblogModuleAdminApplicationTests.java
│ └── .gitignore
├── weblog-module-common
│ ├── src
│ │ ├── main
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── quanxiaoha
│ │ │ │ └── weblog
│ │ │ │ └── common
│ │ │ │ ├── package-info.java
│ │ │ │ ├── model
│ │ │ │ ├── package-info.java
│ │ │ │ ├── BasePageQuery.java
│ │ │ │ └── vo
│ │ │ │ │ └── SelectRspVO.java
│ │ │ │ ├── domain
│ │ │ │ ├── package-info.java
│ │ │ │ ├── dos
│ │ │ │ │ ├── UserRoleDO.java
│ │ │ │ │ ├── ArticlePublishCountDO.java
│ │ │ │ │ ├── ArticleTagRelDO.java
│ │ │ │ │ ├── ArticleContentDO.java
│ │ │ │ │ ├── ArticleCategoryRelDO.java
│ │ │ │ │ ├── TagDO.java
│ │ │ │ │ ├── UserDO.java
│ │ │ │ │ ├── CategoryDO.java
│ │ │ │ │ ├── StatisticsArticlePVDO.java
│ │ │ │ │ ├── WikiDO.java
│ │ │ │ │ ├── ArticleDO.java
│ │ │ │ │ ├── WikiCatalogDO.java
│ │ │ │ │ ├── BlogSettingsDO.java
│ │ │ │ │ └── CommentDO.java
│ │ │ │ └── mapper
│ │ │ │ │ ├── BlogSettingsMapper.java
│ │ │ │ │ ├── UserRoleMapper.java
│ │ │ │ │ ├── UserMapper.java
│ │ │ │ │ ├── StatisticsArticlePVMapper.java
│ │ │ │ │ └── ArticleContentMapper.java
│ │ │ │ ├── exception
│ │ │ │ ├── BaseExceptionInterface.java
│ │ │ │ └── BizException.java
│ │ │ │ ├── aspect
│ │ │ │ └── ApiOperationLog.java
│ │ │ │ ├── enums
│ │ │ │ ├── WikiCatalogLevelEnum.java
│ │ │ │ ├── ArticleTypeEnum.java
│ │ │ │ ├── CommentStatusEnum.java
│ │ │ │ └── ResponseCodeEnum.java
│ │ │ │ ├── config
│ │ │ │ ├── InsertBatchMapper.java
│ │ │ │ ├── InsertBatchSqlInjector.java
│ │ │ │ └── MybatisPlusConfig.java
│ │ │ │ ├── constant
│ │ │ │ └── Constants.java
│ │ │ │ ├── utils
│ │ │ │ └── JsonUtil.java
│ │ │ │ └── mail
│ │ │ │ └── MailHelper.java
│ │ └── test
│ │ │ └── java
│ │ │ └── com
│ │ │ └── quanxiaoha
│ │ │ └── weblog
│ │ │ └── common
│ │ │ └── WeblogModuleCommonApplicationTests.java
│ └── .gitignore
├── weblog-web
│ ├── src
│ │ └── main
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── quanxiaoha
│ │ │ │ └── weblog
│ │ │ │ └── web
│ │ │ │ ├── service
│ │ │ │ ├── BlogSettingsService.java
│ │ │ │ ├── StatisticsService.java
│ │ │ │ ├── SearchService.java
│ │ │ │ ├── ArchiveService.java
│ │ │ │ ├── TagService.java
│ │ │ │ ├── CategoryService.java
│ │ │ │ ├── ArticleService.java
│ │ │ │ ├── WikiService.java
│ │ │ │ ├── CommentService.java
│ │ │ │ └── impl
│ │ │ │ │ └── BlogSettingsServiceImpl.java
│ │ │ │ ├── utils
│ │ │ │ └── StringUtil.java
│ │ │ │ ├── model
│ │ │ │ └── vo
│ │ │ │ │ ├── tag
│ │ │ │ │ ├── FindTagListReqVO.java
│ │ │ │ │ ├── FindTagListRspVO.java
│ │ │ │ │ ├── FindTagArticlePageListRspVO.java
│ │ │ │ │ └── FindTagArticlePageListReqVO.java
│ │ │ │ │ ├── archive
│ │ │ │ │ ├── FindArchiveArticlePageListReqVO.java
│ │ │ │ │ ├── FindArchiveArticlePageListRspVO.java
│ │ │ │ │ └── FindArchiveArticleRspVO.java
│ │ │ │ │ ├── article
│ │ │ │ │ ├── FindIndexArticlePageListReqVO.java
│ │ │ │ │ ├── FindArticleDetailReqVO.java
│ │ │ │ │ ├── FindPreNextArticleRspVO.java
│ │ │ │ │ ├── FindIndexArticlePageListRspVO.java
│ │ │ │ │ └── FindArticleDetailRspVO.java
│ │ │ │ │ ├── category
│ │ │ │ │ ├── FindCategoryListReqVO.java
│ │ │ │ │ ├── FindCategoryListRspVO.java
│ │ │ │ │ ├── FindCategoryArticlePageListRspVO.java
│ │ │ │ │ └── FindCategoryArticlePageListReqVO.java
│ │ │ │ │ ├── comment
│ │ │ │ │ ├── FindCommentListReqVO.java
│ │ │ │ │ ├── FindQQUserInfoReqVO.java
│ │ │ │ │ ├── FindCommentListRspVO.java
│ │ │ │ │ ├── FindQQUserInfoRspVO.java
│ │ │ │ │ ├── FindCommentItemRspVO.java
│ │ │ │ │ └── PublishCommentReqVO.java
│ │ │ │ │ ├── wiki
│ │ │ │ │ ├── FindWikiCatalogListReqVO.java
│ │ │ │ │ ├── FindWikiArticlePreNextReqVO.java
│ │ │ │ │ ├── FindWikiListRspVO.java
│ │ │ │ │ ├── FindWikiArticlePreNextRspVO.java
│ │ │ │ │ └── FindWikiCatalogListRspVO.java
│ │ │ │ │ ├── search
│ │ │ │ │ ├── SearchArticlePageListReqVO.java
│ │ │ │ │ └── SearchArticlePageListRspVO.java
│ │ │ │ │ ├── blogsettings
│ │ │ │ │ └── FindBlogSettingsDetailRspVO.java
│ │ │ │ │ └── statistics
│ │ │ │ │ └── FindStatisticsInfoRspVO.java
│ │ │ │ ├── event
│ │ │ │ └── PublishCommentEvent.java
│ │ │ │ ├── WeblogWebApplication.java
│ │ │ │ ├── convert
│ │ │ │ ├── CommentConvert.java
│ │ │ │ └── BlogSettingsConvert.java
│ │ │ │ ├── config
│ │ │ │ ├── RestTemplateConfig.java
│ │ │ │ └── ToolGoodConfig.java
│ │ │ │ └── controller
│ │ │ │ ├── StatisticsController.java
│ │ │ │ ├── BlogSettingsController.java
│ │ │ │ ├── SearchController.java
│ │ │ │ └── ArchiveController.java
│ │ │ └── resources
│ │ │ ├── application.yml
│ │ │ ├── spy.properties
│ │ │ ├── application-dev.yml
│ │ │ └── application-prod.yml
│ ├── .gitignore
│ └── Dockerfile
├── weblog-module-jwt
│ ├── src
│ │ ├── test
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── quanxiaoha
│ │ │ │ └── weblog
│ │ │ │ └── jwt
│ │ │ │ └── WeblogModuleJwtApplicationTests.java
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── quanxiaoha
│ │ │ └── weblog
│ │ │ └── jwt
│ │ │ ├── model
│ │ │ └── LoginRspVO.java
│ │ │ ├── exception
│ │ │ └── UsernameOrPasswordNullException.java
│ │ │ ├── config
│ │ │ └── PasswordEncoderConfig.java
│ │ │ └── handler
│ │ │ ├── RestAccessDeniedHandler.java
│ │ │ └── RestAuthenticationEntryPoint.java
│ └── .gitignore
├── .gitignore
└── weblog-module-search
│ └── src
│ └── main
│ └── java
│ └── com
│ └── quanxiaoha
│ └── weblog
│ └── search
│ ├── config
│ └── LuceneProperties.java
│ └── index
│ └── ArticleIndex.java
├── .gitignore
├── LICENSE
└── README.md
/pic/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MusaTabitai/weblog/HEAD/pic/home.png
--------------------------------------------------------------------------------
/pic/detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MusaTabitai/weblog/HEAD/pic/detail.png
--------------------------------------------------------------------------------
/pic/移动端详情页.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MusaTabitai/weblog/HEAD/pic/移动端详情页.png
--------------------------------------------------------------------------------
/pic/移动端首页.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MusaTabitai/weblog/HEAD/pic/移动端首页.png
--------------------------------------------------------------------------------
/weblog-vue3/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MusaTabitai/weblog/HEAD/weblog-vue3/public/favicon.ico
--------------------------------------------------------------------------------
/weblog-vue3/src/assets/no-data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MusaTabitai/weblog/HEAD/weblog-vue3/src/assets/no-data.png
--------------------------------------------------------------------------------
/weblog-vue3/src/assets/developer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MusaTabitai/weblog/HEAD/weblog-vue3/src/assets/developer.png
--------------------------------------------------------------------------------
/weblog-vue3/src/assets/weblog-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MusaTabitai/weblog/HEAD/weblog-vue3/src/assets/weblog-logo.png
--------------------------------------------------------------------------------
/weblog-vue3/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/weblog-vue3/src/assets/weblog-logo-mini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MusaTabitai/weblog/HEAD/weblog-vue3/src/assets/weblog-logo-mini.png
--------------------------------------------------------------------------------
/weblog-vue3/src/api/admin/file.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 上传文件
4 | export function uploadFile(form) {
5 | return axios.post("/admin/file/upload", form)
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/weblog-vue3/src/api/frontend/search.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 文章搜索
4 | export function getArticleSearchPageList(data) {
5 | return axios.post("/article/search", data)
6 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/api/frontend/statistics.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取统计信息(文章总数、分类总数、标签总数、总访问量)
4 | export function getStatisticsInfo() {
5 | return axios.post("/statistics/info")
6 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/api/frontend/archive.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取文章归档分页数据
4 | export function getArchivePageList(data) {
5 | return axios.post("/archive/list", data)
6 | }
7 |
8 |
9 |
--------------------------------------------------------------------------------
/weblog-vue3/src/api/frontend/blogsettings.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取博客设置详情
4 | export function getBlogSettingsDetail() {
5 | return axios.post("/blog/settings/detail")
6 | }
7 |
8 |
9 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @author: 木萨·塔布提
3 | * @url: blog.arnasoft.site
4 | * @date: 2023-08-16 9:28
5 | * @description: TODO
6 | **/
7 | package com.quanxiaoha.weblog.admin;
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @author: 木萨·塔布提
3 | * @url: blog.arnasoft.site
4 | * @date: 2023-08-10 9:20
5 | * @description: TODO
6 | **/
7 | package com.quanxiaoha.weblog.common;
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @author: 木萨·塔布提
3 | * @url: blog.arnasoft.site
4 | * @date: 2023-09-15 14:07
5 | * @description: TODO
6 | **/
7 | package com.quanxiaoha.weblog.admin.model;
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/service/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @author: 木萨·塔布提
3 | * @url: blog.arnasoft.site
4 | * @date: 2023-09-15 14:02
5 | * @description: TODO
6 | **/
7 | package com.quanxiaoha.weblog.admin.service;
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/model/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @author: 木萨·塔布提
3 | * @url: blog.arnasoft.site
4 | * @date: 2023-09-19 8:53
5 | * @description: TODO
6 | **/
7 | package com.quanxiaoha.weblog.common.model;
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @author: 木萨·塔布提
3 | * @url: blog.arnasoft.site
4 | * @date: 2023-08-22 16:57
5 | * @description: TODO
6 | **/
7 | package com.quanxiaoha.weblog.common.domain;
--------------------------------------------------------------------------------
/weblog-vue3/src/stores/index.js:
--------------------------------------------------------------------------------
1 | // 引入全局状态管理 Pinia
2 | import { createPinia } from 'pinia'
3 | import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
4 |
5 | const pinia = createPinia()
6 | // 持久化插件
7 | pinia.use(piniaPluginPersistedstate)
8 |
9 | // 暴露出去
10 | export default pinia
--------------------------------------------------------------------------------
/weblog-vue3/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/weblog-vue3/src/api/frontend/tag.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取标签列表
4 | export function getTagList(data) {
5 | return axios.post("/tag/list", data)
6 | }
7 |
8 | // 获取标签下文章列表
9 | export function getTagArticlePageList(data) {
10 | return axios.post("/tag/article/list", data)
11 | }
12 |
13 |
14 |
--------------------------------------------------------------------------------
/weblog-vue3/src/stores/comment.js:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia'
2 | import { ref } from 'vue'
3 |
4 | export const useCommentStore = defineStore('comment', () => {
5 | // 评论用户信息
6 | const userInfo = ref({})
7 |
8 | return { userInfo }
9 | },
10 | {
11 | // 开启持久化
12 | persist: true,
13 | }
14 | )
--------------------------------------------------------------------------------
/weblog-vue3/src/api/frontend/article.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取文章列表
4 | export function getArticlePageList(data) {
5 | return axios.post("/article/list", data)
6 | }
7 |
8 | // 获取文章详情
9 | export function getArticleDetail(articleId) {
10 | return axios.post("/article/detail", {articleId})
11 | }
12 |
13 |
14 |
--------------------------------------------------------------------------------
/weblog-vue3/src/api/admin/blogsettings.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取博客设置详情
4 | export function getBlogSettingsDetail() {
5 | return axios.post("/admin/blog/settings/detail")
6 | }
7 |
8 | // 更新博客设置
9 | export function updateBlogSettings(data) {
10 | return axios.post("/admin/blog/settings/update", data)
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/weblog-vue3/src/api/frontend/category.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取分类列表
4 | export function getCategoryList(data) {
5 | return axios.post("/category/list", data)
6 | }
7 |
8 | // 获取分类-文章列表
9 | export function getCategoryArticlePageList(data) {
10 | return axios.post("/category/article/list", data)
11 | }
12 |
13 |
14 |
--------------------------------------------------------------------------------
/weblog-vue3/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{vue,js,ts,jsx,tsx}",
6 | "./node_modules/flowbite/**/*.js",
7 | ],
8 | theme: {
9 | extend: {},
10 | },
11 | plugins: [
12 | require('flowbite/plugin')
13 | ]
14 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/components/icons/IconSupport.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/weblog-vue3/src/layouts/admin/components/AdminFooter.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Copyright © 2024. All rights reserved. Provided by
程序猿小萨
5 |
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 | replay_pid*
25 |
--------------------------------------------------------------------------------
/weblog-vue3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/weblog-vue3/src/api/frontend/wiki.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取知识库列表
4 | export function getWikiList() {
5 | return axios.post("/wiki/list")
6 | }
7 |
8 | // 获取知识库文章上下页
9 | export function getWikiArticlePreNext(data) {
10 | return axios.post("/wiki/article/preNext", data)
11 | }
12 |
13 | // 获取知识库目录
14 | export function getWikiCatalogs(id) {
15 | return axios.post("/wiki/catalog/list", {id})
16 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/exception/BaseExceptionInterface.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.exception;
2 |
3 | /**
4 | * @author: 木萨·塔布提
5 | * @url: blog.arnasoft.site
6 | * @date: 2023-08-15 9:54
7 | * @description: 通用异常接口
8 | **/
9 | public interface BaseExceptionInterface {
10 | String getErrorCode();
11 |
12 | String getErrorMessage();
13 | }
14 |
--------------------------------------------------------------------------------
/weblog-vue3/src/api/admin/user.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 登录接口
4 | export function login(username, password) {
5 | return axios.post("/login", {username, password})
6 | }
7 |
8 | // 获取登录用户信息
9 | export function getUserInfo() {
10 | return axios.post("/admin/user/info")
11 | }
12 |
13 | // 修改用户密码
14 | export function updateAdminPassword(data) {
15 | return axios.post("/admin/password/update", data)
16 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/api/admin/comment.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取评论分页数据
4 | export function getCommentPageList(data) {
5 | return axios.post("/admin/comment/list", data)
6 | }
7 |
8 | // 删除评论
9 | export function deleteComment(id) {
10 | return axios.post("/admin/comment/delete", {id})
11 | }
12 |
13 | // 审核评论
14 | export function examineComment(data) {
15 | return axios.post("/admin/comment/examine", data)
16 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/api/frontend/comment.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取 QQ 用户信息
4 | export function getUserInfoByQQ(qq) {
5 | return axios.post("/comment/qq/userInfo", { qq })
6 | }
7 |
8 | // 发布评论
9 | export function publishComment(data) {
10 | return axios.post("/comment/publish", data)
11 | }
12 |
13 | // 获取所有评论
14 | export function getComments(routerUrl) {
15 | return axios.post("/comment/list", { routerUrl })
16 | }
--------------------------------------------------------------------------------
/weblog-vue3/.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 | .DS_Store
12 | dist
13 | dist-ssr
14 | coverage
15 | *.local
16 |
17 | /cypress/videos/
18 | /cypress/screenshots/
19 |
20 | # Editor directories and files
21 | .vscode/*
22 | !.vscode/extensions.json
23 | .idea
24 | *.suo
25 | *.ntvs*
26 | *.njsproj
27 | *.sln
28 | *.sw?
29 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/aspect/ApiOperationLog.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.aspect;
2 |
3 | import java.lang.annotation.*;
4 |
5 | @Retention(RetentionPolicy.RUNTIME)
6 | @Target({ElementType.METHOD})
7 | @Documented
8 | public @interface ApiOperationLog {
9 | /**
10 | * API 功能描述
11 | *
12 | * @return
13 | */
14 | String description() default "";
15 |
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/weblog-vue3/src/stores/menu.js:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia'
2 | import { ref } from 'vue'
3 |
4 | export const useMenuStore = defineStore('menu', () => {
5 | // 左边栏菜单默认宽度
6 | const menuWidth = ref("250px")
7 |
8 | // 展开或伸缩左边栏菜单
9 | function handleMenuWidth() {
10 | menuWidth.value = menuWidth.value == '250px' ? '64px' : '250px'
11 | }
12 |
13 | return { menuWidth, handleMenuWidth }
14 | },
15 | {
16 | // 开启持久化
17 | persist: true,
18 | }
19 | )
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/service/BlogSettingsService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.service;
2 |
3 | import com.quanxiaoha.weblog.common.utils.Response;
4 |
5 | /**
6 | * @author: 木萨·塔布提
7 | * @url: blog.arnasoft.site
8 | * @date: 2023-09-15 14:03
9 | * @description: 博客设置
10 | **/
11 | public interface BlogSettingsService {
12 | /**
13 | * 获取博客设置信息
14 | * @return
15 | */
16 | Response findDetail();
17 | }
18 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/service/StatisticsService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.service;
2 |
3 | import com.quanxiaoha.weblog.common.utils.Response;
4 |
5 | /**
6 | * @Author: 木萨·塔布提
7 | * @Date: 2024-03-27 16:37
8 | * @Version: v1.0.0
9 | * @Description: TODO
10 | **/
11 | public interface StatisticsService {
12 | /**
13 | * 获取文章总数、分类总数、标签总数、总访问量统计信息
14 | * @return
15 | */
16 | Response findInfo();
17 | }
18 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/utils/StringUtil.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.utils;
2 |
3 | /**
4 | * @Author: 木萨·塔布提
5 | * @Date: 2024/4/3 19:53
6 | * @Version: v1.0.0
7 | * @Description: TODO
8 | **/
9 | public class StringUtil {
10 |
11 | /**
12 | * 判断字符串是否是纯数字
13 | * @param str
14 | * @return
15 | */
16 | public static boolean isPureNumber(String str) {
17 | return str.matches("\\d+");
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/service/AdminStatisticsService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.service;
2 |
3 | /**
4 | * @Author: 木萨·塔布提
5 | * @Date: 2024/3/28 20:32
6 | * @Version: v1.0.0
7 | * @Description: TODO
8 | **/
9 | public interface AdminStatisticsService {
10 |
11 | /**
12 | * 统计各分类下文章总数
13 | */
14 | void statisticsCategoryArticleTotal();
15 |
16 | /**
17 | * 统计各标签下文章总数
18 | */
19 | void statisticsTagArticleTotal();
20 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/model/BasePageQuery.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.model;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author: 木萨·塔布提
7 | * @url: blog.arnasoft.site
8 | * @date: 2023-09-19 8:54
9 | * @description: TODO
10 | **/
11 | @Data
12 | public class BasePageQuery {
13 | /**
14 | * 当前页码, 默认第一页
15 | */
16 | private Long current = 1L;
17 | /**
18 | * 每页展示的数据数量,默认每页展示 10 条数据
19 | */
20 | private Long size = 10L;
21 | }
22 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/enums/WikiCatalogLevelEnum.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.enums;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 |
6 | /**
7 | * @Author: 木萨·塔布提
8 | * @Date: 2024-04-01 12:23
9 | * @Version: v1.0.0
10 | * @Description: TODO
11 | **/
12 | @Getter
13 | @AllArgsConstructor
14 | public enum WikiCatalogLevelEnum {
15 |
16 | // 一级目录
17 | ONE(1),
18 | // 二级目录
19 | TWO(2);
20 |
21 | private Integer value;
22 |
23 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/enums/ArticleTypeEnum.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.enums;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 |
6 | /**
7 | * @Author: 木萨·塔布提
8 | * @Date: 2024-04-01 12:23
9 | * @Version: v1.0.0
10 | * @Description: TODO
11 | **/
12 | @Getter
13 | @AllArgsConstructor
14 | public enum ArticleTypeEnum {
15 |
16 | NORMAL(1, "普通"),
17 | WIKI(2, "收录于知识库");
18 |
19 | private Integer value;
20 | private String description;
21 |
22 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/api/admin/dashboard.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取仪表盘基础信息(文章数、分类数、标签数、总浏览量)
4 | export function getBaseStatisticsInfo(data) {
5 | return axios.post("/admin/dashboard/statistics", data)
6 | }
7 |
8 | // 获取仪表盘文章发布热点统计信息
9 | export function getPublishArticleStatisticsInfo(data) {
10 | return axios.post("/admin/dashboard/publishArticle/statistics", data)
11 | }
12 |
13 | // 获取仪表盘最近一周 PV 访问量信息
14 | export function getArticlePVStatisticsInfo(data) {
15 | return axios.post("/admin/dashboard/pv/statistics", data)
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-jwt/src/test/java/com/quanxiaoha/weblog/jwt/WeblogModuleJwtApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.jwt;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = WeblogModuleJwtApplicationTests.Application.class)
7 | class WeblogModuleJwtApplicationTests {
8 |
9 | public static class Application {
10 | }
11 |
12 | @Test
13 | void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/weblog-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 |
--------------------------------------------------------------------------------
/weblog-vue3/src/api/admin/category.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取分类分页数据
4 | export function getCategoryPageList(data) {
5 | return axios.post("/admin/category/list", data)
6 | }
7 |
8 | // 添加分类
9 | export function addCategory(data) {
10 | return axios.post("/admin/category/add", data)
11 | }
12 |
13 | // 删除分类
14 | export function deleteCategory(id) {
15 | return axios.post("/admin/category/delete", {id})
16 | }
17 |
18 | // 获取分类 select 数据
19 | export function getCategorySelectList() {
20 | return axios.post("/admin/category/select/list")
21 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/.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 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-jwt/.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 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/.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 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/.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 |
--------------------------------------------------------------------------------
/weblog-vue3/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-jwt/src/main/java/com/quanxiaoha/weblog/jwt/model/LoginRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.jwt.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-08-24 9:43
12 | * @description: 用户登录
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class LoginRspVO {
19 |
20 | /**
21 | * Token 值
22 | */
23 | private String token;
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/config/InsertBatchMapper.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.config;
2 |
3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 | import org.apache.ibatis.annotations.Param;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-06-13 22:50
12 | * @description: 批量插入
13 | **/
14 | public interface InsertBatchMapper extends BaseMapper {
15 |
16 | // 批量插入
17 | int insertBatchSomeColumn(@Param("list") List batchList);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/tag/FindTagListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.tag;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024/3/28 23:18
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class FindTagListReqVO {
19 |
20 | /**
21 | * 展示数量
22 | */
23 | private Long size;
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/archive/FindArchiveArticlePageListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.archive;
2 |
3 | import com.quanxiaoha.weblog.common.model.BasePageQuery;
4 | import io.swagger.annotations.ApiModel;
5 | import lombok.Builder;
6 | import lombok.Data;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-09-15 14:07
12 | * @description: 文章归档
13 | **/
14 | @Data
15 | @Builder
16 | @ApiModel(value = "文章归档分页 VO")
17 | public class FindArchiveArticlePageListReqVO extends BasePageQuery {
18 | }
19 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/article/FindIndexArticlePageListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.article;
2 |
3 | import com.quanxiaoha.weblog.common.model.BasePageQuery;
4 | import io.swagger.annotations.ApiModel;
5 | import lombok.Builder;
6 | import lombok.Data;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-09-15 14:07
12 | * @description: 首页-文章分页
13 | **/
14 | @Data
15 | @Builder
16 | @ApiModel(value = "首页查询文章分页 VO")
17 | public class FindIndexArticlePageListReqVO extends BasePageQuery {
18 | }
19 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/Dockerfile:
--------------------------------------------------------------------------------
1 | # FROM 指定使用哪个镜像作为基准
2 | FROM openjdk:8-jdk-alpine
3 |
4 | # 创建目录, 并设置该目录为工作目录
5 | RUN mkdir -p /weblog
6 | WORKDIR /weblog
7 |
8 | # 复制文件到镜像中
9 | COPY weblog-web-0.0.1-SNAPSHOT.jar app.jar
10 |
11 | # 设置时区
12 | ENV TZ=Asia/Shanghai
13 |
14 | # 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
15 | ENV JAVA_OPTS="-Xms300m -Xmx300m -Djava.security.egd=file:/dev/./urandom"
16 |
17 | # 应用参数,可通过 docker run -e "ARGS=" 来设置,如 -e "ARGS=--spring.profiles.active=prod"
18 | ENV ARGS=""
19 |
20 | # 暴露 8080 端口
21 | EXPOSE 8080
22 |
23 | # 启动后端服务
24 | CMD java ${JAVA_OPTS} -jar app.jar $ARGS
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/category/FindCategoryListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.category;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024/3/28 23:18
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class FindCategoryListReqVO {
19 |
20 | /**
21 | * 展示数量
22 | */
23 | private Long size;
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/tag/FindTagListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.tag;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-04-19 16:06
12 | * @description: 标签
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class FindTagListRspVO {
19 | private Long id;
20 | private String name;
21 | private Integer articlesTotal;
22 | }
23 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-search/src/main/java/com/quanxiaoha/weblog/search/config/LuceneProperties.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.search.config;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.stereotype.Component;
6 |
7 | /**
8 | * @Author: 木萨·塔布提
9 | * @Date: 2024-03-27 17:56
10 | * @Version: v1.0.0
11 | * @Description: TODO
12 | **/
13 | @ConfigurationProperties(prefix = "lucene")
14 | @Component
15 | @Data
16 | public class LuceneProperties {
17 | /**
18 | * 索引存放的文件夹
19 | */
20 | private String indexDir;
21 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/stores/blogsettings.js:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia'
2 | import { ref } from 'vue'
3 | import { getBlogSettingsDetail } from '@/api/frontend/blogsettings'
4 |
5 | export const useBlogSettingsStore = defineStore('blogsettings', () => {
6 | // 博客设置信息
7 | const blogSettings = ref({})
8 |
9 | // 获取博客设置信息
10 | function getBlogSettings() {
11 | // 调用后台获取博客设置信息接口
12 | console.log('获取博客设置信息')
13 | getBlogSettingsDetail().then(res => {
14 | if (res.success) {
15 | blogSettings.value = res.data
16 | }
17 | })
18 | }
19 |
20 |
21 | return { blogSettings, getBlogSettings }
22 | })
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/category/FindCategoryListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.category;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-04-19 16:06
12 | * @description: 分类
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class FindCategoryListRspVO {
19 | private Long id;
20 | private String name;
21 | private Integer articlesTotal;
22 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/api/admin/tag.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取标签分页数据
4 | export function getTagPageList(data) {
5 | return axios.post("/admin/tag/list", data)
6 | }
7 |
8 | // 添加标签
9 | export function addTag(data) {
10 | return axios.post("/admin/tag/add", data)
11 | }
12 |
13 | // 删除标签
14 | export function deleteTag(id) {
15 | return axios.post("/admin/tag/delete", {id})
16 | }
17 |
18 | // 根据标签名模糊查询
19 | export function searchTags(key) {
20 | return axios.post("/admin/tag/search", {key})
21 | }
22 |
23 | // 获取标签 select 列表数据
24 | export function getTagSelectList() {
25 | return axios.post("/admin/tag/select/list")
26 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/service/SearchService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.service;
2 |
3 | import com.quanxiaoha.weblog.common.utils.Response;
4 | import com.quanxiaoha.weblog.web.model.vo.search.SearchArticlePageListReqVO;
5 |
6 | /**
7 | * @Author: 木萨·塔布提
8 | * @Date: 2024-03-27 18:12
9 | * @Version: v1.0.0
10 | * @Description: TODO
11 | **/
12 | public interface SearchService {
13 |
14 | /**
15 | * 关键词分页搜索
16 | * @param searchArticlePageListReqVO
17 | * @return
18 | */
19 | Response searchArticlePageList(SearchArticlePageListReqVO searchArticlePageListReqVO);
20 | }
21 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/constant/Constants.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.constant;
2 |
3 | import java.time.format.DateTimeFormatter;
4 |
5 | /**
6 | * @author: 木萨·塔布提
7 | * @url: blog.arnasoft.site
8 | * @date: 2023/11/13 11:22
9 | * @description: 全局静态变量
10 | **/
11 | public interface Constants {
12 | /**
13 | * 月-日 格式
14 | */
15 | DateTimeFormatter MONTH_DAY_FORMATTER = DateTimeFormatter.ofPattern("MM-dd");
16 |
17 | /**
18 | * 年-月-日 小时-分钟-秒
19 | */
20 | DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
21 | }
22 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/UserRoleDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.Builder;
7 | import lombok.Data;
8 |
9 | import java.util.Date;
10 |
11 | @Data
12 | @Builder
13 | @TableName("t_user_role")
14 | public class UserRoleDO {
15 | @TableId(type = IdType.AUTO)
16 | private Long id;
17 | private String username;
18 | private String role;
19 | private Date createTime;
20 | }
21 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/enums/CommentStatusEnum.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.enums;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 |
6 | /**
7 | * @Author: 木萨·塔布提
8 | * @Date: 2024/4/3 20:43
9 | * @Version: v1.0.0
10 | * @Description: TODO
11 | **/
12 |
13 | @Getter
14 | @AllArgsConstructor
15 | public enum CommentStatusEnum {
16 |
17 | // ----------- 通用异常状态码 -----------
18 | WAIT_EXAMINE(1, "等待审核"),
19 | NORMAL(2, "正常"),
20 | EXAMINE_FAILED(3, "审核不通过"),
21 | ;
22 |
23 | private Integer code;
24 | private String description;
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/event/DeleteArticleEvent.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.event;
2 |
3 | import lombok.Getter;
4 | import org.springframework.context.ApplicationEvent;
5 |
6 | /**
7 | * @Author: 木萨·塔布提
8 | * @Date: 2024-03-27 19:17
9 | * @Version: v1.0.0
10 | * @Description: TODO
11 | **/
12 | @Getter
13 | public class DeleteArticleEvent extends ApplicationEvent {
14 |
15 | /**
16 | * 文章 ID
17 | */
18 | private Long articleId;
19 |
20 | public DeleteArticleEvent(Object source, Long articleId) {
21 | super(source);
22 | this.articleId = articleId;
23 | }
24 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/event/UpdateArticleEvent.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.event;
2 |
3 | import lombok.Getter;
4 | import org.springframework.context.ApplicationEvent;
5 |
6 | /**
7 | * @Author: 木萨·塔布提
8 | * @Date: 2024-03-27 19:19
9 | * @Version: v1.0.0
10 | * @Description: TODO
11 | **/
12 | @Getter
13 | public class UpdateArticleEvent extends ApplicationEvent {
14 |
15 | /**
16 | * 文章 ID
17 | */
18 | private Long articleId;
19 |
20 | public UpdateArticleEvent(Object source, Long articleId) {
21 | super(source);
22 | this.articleId = articleId;
23 | }
24 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/file/UploadFileRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.file;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDateTime;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-09-15 14:07
14 | * @description: 上传文件
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class UploadFileRspVO {
21 |
22 | /**
23 | * 文件的访问链接
24 | */
25 | private String url;
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/service/AdminFileService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.service;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.user.UpdateAdminUserPasswordReqVO;
4 | import com.quanxiaoha.weblog.common.utils.Response;
5 | import org.springframework.web.multipart.MultipartFile;
6 |
7 | /**
8 | * @author: 木萨·塔布提
9 | * @url: blog.arnasoft.site
10 | * @date: 2023-09-15 14:03
11 | * @description: TODO
12 | **/
13 | public interface AdminFileService {
14 | /**
15 | * 上传文件
16 | * @param file
17 | * @return
18 | */
19 | Response uploadFile(MultipartFile file);
20 | }
21 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/event/PublishCommentEvent.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.event;
2 |
3 | import lombok.Getter;
4 | import org.springframework.context.ApplicationEvent;
5 |
6 | /**
7 | * @Author: 木萨·塔布提
8 | * @Date: 2024/4/3 21:41
9 | * @Version: v1.0.0
10 | * @Description: TODO
11 | **/
12 |
13 | @Getter
14 | public class PublishCommentEvent extends ApplicationEvent {
15 |
16 | /**
17 | * 评论 ID
18 | */
19 | private Long commentId;
20 |
21 | public PublishCommentEvent(Object source, Long commentId) {
22 | super(source);
23 | this.commentId = commentId;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/comment/FindCommentListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.comment;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import javax.validation.constraints.NotBlank;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024/4/3 21:20
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindCommentListReqVO {
21 |
22 | @NotBlank(message = "路由地址不能为空")
23 | private String routerUrl;
24 |
25 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/comment/FindQQUserInfoReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.comment;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import javax.validation.constraints.NotBlank;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024/4/3 19:50
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindQQUserInfoReqVO {
21 |
22 | @NotBlank(message = "QQ 号不能为空")
23 | private String qq;
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/event/PublishArticleEvent.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.event;
2 |
3 | import lombok.Getter;
4 | import org.springframework.context.ApplicationEvent;
5 |
6 | /**
7 | * @Author: 木萨·塔布提
8 | * @Date: 2024-03-27 19:10
9 | * @Version: v1.0.0
10 | * @Description: TODO
11 | **/
12 | @Getter
13 | public class PublishArticleEvent extends ApplicationEvent {
14 |
15 | /**
16 | * 文章 ID
17 | */
18 | private Long articleId;
19 |
20 | public PublishArticleEvent(Object source, Long articleId) {
21 | super(source);
22 | this.articleId = articleId;
23 | }
24 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/wiki/FindWikiCatalogListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.wiki;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import javax.validation.constraints.NotNull;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024-04-01 18:32
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindWikiCatalogListReqVO {
21 |
22 | @NotNull(message = "知识库 ID 不能为空")
23 | private Long id;
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/event/UpdateCommentEvent.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.event;
2 |
3 | import lombok.Getter;
4 | import org.springframework.context.ApplicationEvent;
5 |
6 | /**
7 | * @Author: 木萨·塔布提
8 | * @Date: 2024/4/6 23:23
9 | * @Version: v1.0.0
10 | * @Description: TODO
11 | **/
12 | @Getter
13 | public class UpdateCommentEvent extends ApplicationEvent {
14 |
15 | /**
16 | * 评论 ID
17 | */
18 | private Long commentId;
19 |
20 | public UpdateCommentEvent(Object source, Long commentId) {
21 | super(source);
22 | this.commentId = commentId;
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/service/ArchiveService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.service;
2 |
3 | import com.quanxiaoha.weblog.common.utils.Response;
4 | import com.quanxiaoha.weblog.web.model.vo.archive.FindArchiveArticlePageListReqVO;
5 |
6 | /**
7 | * @author: 木萨·塔布提
8 | * @url: blog.arnasoft.site
9 | * @date: 2023-09-15 14:03
10 | * @description: 归档文章
11 | **/
12 | public interface ArchiveService {
13 | /**
14 | * 获取文章归档分页数据
15 | * @param findArchiveArticlePageListReqVO
16 | * @return
17 | */
18 | Response findArchivePageList(FindArchiveArticlePageListReqVO findArchiveArticlePageListReqVO);
19 | }
20 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/event/ReadArticleEvent.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.event;
2 |
3 | import lombok.Getter;
4 | import org.springframework.context.ApplicationEvent;
5 |
6 | /**
7 | * @author: 木萨·塔布提
8 | * @url: blog.arnasoft.site
9 | * @date: 2023/11/9 10:05
10 | * @description: 文章被阅读事件
11 | **/
12 |
13 | @Getter
14 | public class ReadArticleEvent extends ApplicationEvent {
15 |
16 | /**
17 | * 文章 ID
18 | */
19 | private Long articleId;
20 |
21 | public ReadArticleEvent(Object source, Long articleId) {
22 | super(source);
23 | this.articleId = articleId;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-jwt/src/main/java/com/quanxiaoha/weblog/jwt/exception/UsernameOrPasswordNullException.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.jwt.exception;
2 |
3 | import org.springframework.security.core.AuthenticationException;
4 |
5 | /**
6 | * @author: 木萨·塔布提
7 | * @url: blog.arnasoft.site
8 | * @date: 2023-08-24 17:11
9 | * @description: 用户名或者密码为空异常
10 | **/
11 | public class UsernameOrPasswordNullException extends AuthenticationException {
12 | public UsernameOrPasswordNullException(String msg, Throwable cause) {
13 | super(msg, cause);
14 | }
15 |
16 | public UsernameOrPasswordNullException(String msg) {
17 | super(msg);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/config/MinioProperties.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.config;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.stereotype.Component;
6 |
7 | /**
8 | * @author: 木萨·塔布提
9 | * @url: blog.arnasoft.site
10 | * @date: 2023-05-11 8:49
11 | * @description: TODO
12 | **/
13 | @ConfigurationProperties(prefix = "minio")
14 | @Component
15 | @Data
16 | public class MinioProperties {
17 | private String endpoint;
18 | private String accessKey;
19 | private String secretKey;
20 | private String bucketName;
21 | }
22 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/article/FindArticleDetailReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.article;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | /**
10 | * @author: 木萨·塔布提
11 | * @url: blog.arnasoft.site
12 | * @date: 2023-09-15 14:07
13 | * @description: 文章详情
14 | **/
15 | @Data
16 | @AllArgsConstructor
17 | @NoArgsConstructor
18 | @Builder
19 | @ApiModel(value = "查询文章详情 VO")
20 | public class FindArticleDetailReqVO {
21 | /**
22 | * 文章 ID
23 | */
24 | private Long articleId;
25 | }
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/model/vo/SelectRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.model.vo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023/9/20 16:02
12 | * @description: TODO
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class SelectRspVO {
19 | /**
20 | * Select 下拉列表的展示文字
21 | */
22 | private String label;
23 |
24 | /**
25 | * Select 下拉列表的 value 值,如 ID 等
26 | */
27 | private Object value;
28 | }
29 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | profiles:
3 | # 默认激活 dev 环境
4 | active: dev
5 | mail:
6 | host: smtp.qq.com # 邮件服务器的地址,小哈这里使用的 QQ 邮件
7 | username: # 发送邮件的邮箱账号
8 | password: # 授权码,或发送邮件的邮箱账号的密码
9 | default-encoding: utf-8 # 邮件内容的字符编码
10 | protocol: smtps # 邮件传输协议:smtps 表示SMTP over SSL,是一种加密的SMTP连接方式,用于确保邮件传输的安全性。
11 | port: 465 # 邮件服务器的端口号:465 是 SMTPS(SMTP over SSL)的常用端口号,用于加密的邮件传输。
12 |
13 | jwt:
14 | # 签发人
15 | issuer:
16 | # 秘钥
17 | secret:
18 | # token 过期时间(单位:分钟) 24*60
19 | tokenExpireTime: 1440
20 | # token 请求头中的 key 值
21 | tokenHeaderKey: Authorization
22 | # token 请求头中的 value 值前缀
23 | tokenPrefix: Bearer
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/article/FindPreNextArticleRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.article;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-09-15 14:07
12 | * @description: 文章上下页
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class FindPreNextArticleRspVO {
19 | /**
20 | * 文章 ID
21 | */
22 | private Long articleId;
23 |
24 | /**
25 | * 文章标题
26 | */
27 | private String articleTitle;
28 | }
29 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/DeleteWikiReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @Author: 木萨·塔布提
13 | * @Date: 2024-04-01 12:22
14 | * @Version: v1.0.0
15 | * @Description: TODO
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "删除知识库 VO")
22 | public class DeleteWikiReqVO {
23 |
24 | @NotNull(message = "知识库 ID 不能为空")
25 | private Long id;
26 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-search/src/main/java/com/quanxiaoha/weblog/search/index/ArticleIndex.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.search.index;
2 |
3 | /**
4 | * @Author: 木萨·塔布提
5 | * @Date: 2024-03-27 17:57
6 | * @Version: v1.0.0
7 | * @Description: TODO
8 | **/
9 | public interface ArticleIndex {
10 | /**
11 | * 索引名称
12 | */
13 | String NAME = "article";
14 |
15 | // --------------------- 文档字段 ---------------------
16 | String COLUMN_ID = "id";
17 |
18 | String COLUMN_TITLE = "title";
19 |
20 | String COLUMN_COVER = "cover";
21 |
22 | String COLUMN_SUMMARY = "summary";
23 |
24 | String COLUMN_CONTENT = "content";
25 |
26 | String COLUMN_CREATE_TIME = "createTime";
27 | }
28 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/WeblogWebApplication.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.context.annotation.ComponentScan;
6 | import org.springframework.scheduling.annotation.EnableScheduling;
7 |
8 | @SpringBootApplication
9 | @ComponentScan({"com.quanxiaoha.weblog.*"}) // 多模块项目中,必需手动指定扫描 com.quanxiaoha.weblog 包下面的所有类
10 | @EnableScheduling // 启用定时任务
11 | public class WeblogWebApplication {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(WeblogWebApplication.class, args);
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/comment/DeleteCommentReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.comment;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @Author: 木萨·塔布提
13 | * @Date: 2024/4/6 23:15
14 | * @Version: v1.0.0
15 | * @Description: TODO
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "删除评论 VO")
22 | public class DeleteCommentReqVO {
23 |
24 | @NotNull(message = "评论 ID 不能为空")
25 | private Long id;
26 | }
27 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/tag/DeleteTagReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.tag;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-09-15 14:07
15 | * @description: 删除标签
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "删除标签 VO")
22 | public class DeleteTagReqVO {
23 |
24 | @NotNull(message = "标签 ID 不能为空")
25 | private Long id;
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/ArticlePublishCountDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDate;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-08-22 17:01
14 | * @description: 以日为维度统计文章发布数量
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class ArticlePublishCountDO {
21 | /**
22 | * 日期
23 | */
24 | private LocalDate date;
25 |
26 | /**
27 | * 文章发布数量
28 | */
29 | private Long count;
30 | }
31 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/comment/FindCommentListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.comment;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024/4/3 21:20
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindCommentListRspVO {
21 |
22 | /**
23 | * 总评论数
24 | */
25 | private Integer total;
26 |
27 | /**
28 | * 评论集合
29 | */
30 | private List comments;
31 |
32 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/assets/main.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | body {
6 | font-family: -apple-system-font,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Hiragino Sans GB,Microsoft YaHei UI,Microsoft YaHei,Arial,sans-serif;
7 | color: #4c4e4d;
8 | font-size: 16px;
9 | background: #f4f4f4;
10 | line-height: 1.6;
11 | }
12 |
13 | [type='text']:focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus {
14 | box-shadow: 0 0 0 1px transparent inset!important;
15 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/article/DeleteArticleReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.article;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-09-15 14:07
15 | * @description: 删除文章
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "删除文章 VO")
22 | public class DeleteArticleReqVO {
23 |
24 | @NotNull(message = "文章 ID 不能为空")
25 | private Long id;
26 | }
27 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/dashboard/FindDashboardPVStatisticsInfoRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.dashboard;
2 |
3 |
4 | import io.swagger.annotations.ApiModel;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import java.util.List;
11 |
12 | @Data
13 | @AllArgsConstructor
14 | @NoArgsConstructor
15 | @Builder
16 | @ApiModel(value = "查询仪表盘文章 PV 访问量信息入参 VO")
17 | public class FindDashboardPVStatisticsInfoRspVO {
18 | /**
19 | * 日期集合
20 | */
21 | private List pvDates;
22 |
23 | /**
24 | * PV 浏览量集合
25 | */
26 | private List pvCounts;
27 | }
28 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/tag/SearchTagsReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.tag;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotBlank;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-09-15 14:07
15 | * @description: 标签模糊查询
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "标签模糊查询 VO")
22 | public class SearchTagsReqVO {
23 |
24 | @NotBlank(message = "标签查询关键词不能为空")
25 | private String key;
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/wiki/FindWikiArticlePreNextReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.wiki;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import javax.validation.constraints.NotNull;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024-04-01 18:42
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindWikiArticlePreNextReqVO {
21 |
22 | @NotNull(message = "知识库 ID 不能为空")
23 | private Long id;
24 |
25 | @NotNull(message = "文章 ID 不能为空")
26 | private Long articleId;
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/tag/FindTagArticlePageListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.tag;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDate;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-09-15 14:07
14 | * @description: 标签下文章列表
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindTagArticlePageListRspVO {
21 | private Long id;
22 | private String cover;
23 | private String title;
24 | /**
25 | * 发布日期
26 | */
27 | private LocalDate createDate;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/weblog-vue3/README.md:
--------------------------------------------------------------------------------
1 | # 程序猿小萨博客
2 |
3 | This template should help get you started developing with Vue 3 in Vite.
4 |
5 | ## Recommended IDE Setup
6 |
7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
8 |
9 | ## Customize configuration
10 |
11 | See [Vite Configuration Reference](https://vitejs.dev/config/).
12 |
13 | ## Project Setup
14 |
15 | ```sh
16 | npm install
17 | ```
18 |
19 | ### Compile and Hot-Reload for Development
20 |
21 | ```sh
22 | npm run dev
23 | ```
24 |
25 | ### Compile and Minify for Production
26 |
27 | ```sh
28 | npm run build
29 | ```
30 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/mapper/BlogSettingsMapper.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
6 | import com.quanxiaoha.weblog.common.domain.dos.BlogSettingsDO;
7 | import com.quanxiaoha.weblog.common.domain.dos.UserDO;
8 |
9 | import java.time.LocalDateTime;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-08-22 17:06
15 | * @description: TODO
16 | **/
17 | public interface BlogSettingsMapper extends BaseMapper {
18 | }
19 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/exception/BizException.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.exception;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * @author: 木萨·塔布提
8 | * @url: blog.arnasoft.site
9 | * @date: 2023-08-15 9:52
10 | * @description: 业务异常
11 | **/
12 | @Getter
13 | @Setter
14 | public class BizException extends RuntimeException {
15 | // 异常码
16 | private String errorCode;
17 | // 错误信息
18 | private String errorMessage;
19 |
20 | public BizException(BaseExceptionInterface baseExceptionInterface) {
21 | this.errorCode = baseExceptionInterface.getErrorCode();
22 | this.errorMessage = baseExceptionInterface.getErrorMessage();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/user/FindUserInfoRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.user;
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 | * @author: 木萨·塔布提
14 | * @url: blog.arnasoft.site
15 | * @date: 2023-09-15 14:07
16 | * @description: 查询用户信息
17 | **/
18 | @Data
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @Builder
22 | public class FindUserInfoRspVO {
23 | /**
24 | * 用户名
25 | */
26 | private String username;
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/archive/FindArchiveArticlePageListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.archive;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.YearMonth;
9 | import java.util.List;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-09-15 14:07
15 | * @description: 文章归档
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | public class FindArchiveArticlePageListRspVO {
22 | /**
23 | * 归档的月份
24 | */
25 | private YearMonth month;
26 |
27 | private List articles;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/comment/FindQQUserInfoRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.comment;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024/4/3 19:52
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 |
15 | @Data
16 | @AllArgsConstructor
17 | @NoArgsConstructor
18 | @Builder
19 | public class FindQQUserInfoRspVO {
20 |
21 | /**
22 | * 头像
23 | */
24 | private String avatar;
25 |
26 | /**
27 | * 昵称
28 | */
29 | private String nickname;
30 |
31 | /**
32 | * 邮箱
33 | */
34 | private String mail;
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/service/AdminDashboardService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.service;
2 |
3 | import com.quanxiaoha.weblog.common.utils.Response;
4 |
5 | /**
6 | * @author: 木萨·塔布提
7 | * @url: blog.arnasoft.site
8 | * @date: 2023-09-15 14:03
9 | * @description: 仪表盘
10 | **/
11 | public interface AdminDashboardService {
12 |
13 | /**
14 | * 获取仪表盘基础统计信息
15 | * @return
16 | */
17 | Response findDashboardStatistics();
18 |
19 | /**
20 | * 获取文章发布热点统计信息
21 | * @return
22 | */
23 | Response findDashboardPublishArticleStatistics();
24 |
25 | /**
26 | * 获取文章最近一周 PV 访问量统计信息
27 | * @return
28 | */
29 | Response findDashboardPVStatistics();
30 | }
31 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/service/AdminUserService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.service;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.user.UpdateAdminUserPasswordReqVO;
4 | import com.quanxiaoha.weblog.common.utils.Response;
5 |
6 | /**
7 | * @author: 木萨·塔布提
8 | * @url: blog.arnasoft.site
9 | * @date: 2023-09-15 14:03
10 | * @description: TODO
11 | **/
12 | public interface AdminUserService {
13 | /**
14 | * 修改密码
15 | * @param updateAdminUserPasswordReqVO
16 | * @return
17 | */
18 | Response updatePassword(UpdateAdminUserPasswordReqVO updateAdminUserPasswordReqVO);
19 |
20 | /**
21 | * 获取当前登录用户信息
22 | * @return
23 | */
24 | Response findUserInfo();
25 | }
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/category/FindCategoryArticlePageListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.category;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDate;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-09-15 14:07
14 | * @description: 分类文章
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindCategoryArticlePageListRspVO {
21 | private Long id;
22 | private String cover;
23 | private String title;
24 | /**
25 | * 发布日期
26 | */
27 | private LocalDate createDate;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/weblog-vue3/src/layouts/frontend/components/Footer.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
--------------------------------------------------------------------------------
/weblog-vue3/src/stores/user.js:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia'
2 | import { ref } from 'vue'
3 | import { getUserInfo } from '@/api/admin/user'
4 | import { removeToken } from '@/composables/cookie'
5 |
6 | export const useUserStore = defineStore('user', () => {
7 | // 用户信息
8 | const userInfo = ref({})
9 |
10 | // 设置用户信息
11 | function setUserInfo() {
12 | // 调用后头获取用户信息接口
13 | getUserInfo().then(res => {
14 | if (res.success == true) {
15 | userInfo.value = res.data
16 | }
17 | })
18 | }
19 |
20 | // 退出登录
21 | function logout() {
22 | // 删除 cookie 中的 token 令牌
23 | removeToken()
24 | // 删除登录用户信息
25 | userInfo.value = {}
26 | }
27 |
28 | return { userInfo, setUserInfo, logout }
29 | },
30 | {
31 | // 开启持久化
32 | persist: true,
33 | }
34 | )
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/FindWikiCatalogListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @Author: 木萨·塔布提
13 | * @Date: 2024-04-01 13:37
14 | * @Version: v1.0.0
15 | * @Description: TODO
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "查询知识库目录数据入参 VO")
22 | public class FindWikiCatalogListReqVO {
23 |
24 | /**
25 | * 知识库 ID
26 | */
27 | @NotNull(message = "知识库 ID 不能为空")
28 | private Long id;
29 |
30 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/tag/FindTagArticlePageListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.tag;
2 |
3 | import com.quanxiaoha.weblog.common.model.BasePageQuery;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-09-15 14:07
15 | * @description: 标签下文章列表
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | public class FindTagArticlePageListReqVO extends BasePageQuery {
22 |
23 | /**
24 | * 标签 ID
25 | */
26 | @NotNull(message = "标签 ID 不能为空")
27 | private Long id;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/article/FindArticleDetailReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.article;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-09-15 14:07
15 | * @description: 文章详情
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "查询文章详情入参 VO")
22 | public class FindArticleDetailReqVO {
23 |
24 | /**
25 | * 文章 ID
26 | */
27 | @NotNull(message = "文章 ID 不能为空")
28 | private Long id;
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/wiki/FindWikiListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.wiki;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024-04-01 18:22
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class FindWikiListRspVO {
19 | private Long id;
20 | private String cover;
21 | private String title;
22 | private String summary;
23 |
24 | /**
25 | * 是否置顶
26 | */
27 | private Boolean isTop;
28 |
29 | /**
30 | * 第一篇文章 ID
31 | */
32 | private Long firstArticleId;
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/wiki/FindWikiArticlePreNextRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.wiki;
2 |
3 | import com.quanxiaoha.weblog.web.model.vo.article.FindPreNextArticleRspVO;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | /**
10 | * @Author: 木萨·塔布提
11 | * @Date: 2024-04-01 18:43
12 | * @Version: v1.0.0
13 | * @Description: TODO
14 | **/
15 |
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindWikiArticlePreNextRspVO {
21 | /**
22 | * 上一篇文章
23 | */
24 | private FindPreNextArticleRspVO preArticle;
25 | /**
26 | * 下一篇文章
27 | */
28 | private FindPreNextArticleRspVO nextArticle;
29 |
30 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/api/admin/article.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取文章分页数据
4 | export function getArticlePageList(data) {
5 | return axios.post("/admin/article/list", data)
6 | }
7 |
8 | // 删除文章
9 | export function deleteArticle(id) {
10 | return axios.post("/admin/article/delete", {id})
11 | }
12 |
13 | // 发布文章
14 | export function publishArticle(data) {
15 | return axios.post("/admin/article/publish", data)
16 | }
17 |
18 | // 获取文章详情
19 | export function getArticleDetail(id) {
20 | return axios.post("/admin/article/detail", {id})
21 | }
22 |
23 | // 更新文章
24 | export function updateArticle(data) {
25 | return axios.post("/admin/article/update", data)
26 | }
27 |
28 | // 更新文章置顶状态
29 | export function updateArticleIsTop(data) {
30 | return axios.post("/admin/article/isTop/update", data)
31 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/UpdateWikiIsTopReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @Author: 木萨·塔布提
13 | * @Date: 2024-04-01 13:12
14 | * @Version: v1.0.0
15 | * @Description: TODO
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "更新知识库置顶状态 VO")
22 | public class UpdateWikiIsTopReqVO {
23 |
24 | @NotNull(message = "知识库 ID 不能为空")
25 | private Long id;
26 |
27 | @NotNull(message = "知识库置顶状态不能为空")
28 | private Boolean isTop;
29 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/category/FindCategoryArticlePageListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.category;
2 |
3 | import com.quanxiaoha.weblog.common.model.BasePageQuery;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-09-15 14:07
15 | * @description: 分类文章
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | public class FindCategoryArticlePageListReqVO extends BasePageQuery {
22 |
23 | /**
24 | * 分类 ID
25 | */
26 | @NotNull(message = "分类 ID 不能为空")
27 | private Long id;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/article/UpdateArticleIsTopReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.article;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @Author: 木萨·塔布提
13 | * @Date: 2024-03-31 17:09
14 | * @Version: v1.0.0
15 | * @Description: TODO
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "更新文章置顶状态 VO")
22 | public class UpdateArticleIsTopReqVO {
23 |
24 | @NotNull(message = "文章 ID 不能为空")
25 | private Long id;
26 |
27 | @NotNull(message = "文章置顶状态不能为空")
28 | private Boolean isTop;
29 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/convert/CommentConvert.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.convert;
2 |
3 | import com.quanxiaoha.weblog.common.domain.dos.CommentDO;
4 | import com.quanxiaoha.weblog.web.model.vo.comment.FindCommentItemRspVO;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.factory.Mappers;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024/4/3 21:23
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 | @Mapper
15 | public interface CommentConvert {
16 | /**
17 | * 初始化 convert 实例
18 | */
19 | CommentConvert INSTANCE = Mappers.getMapper(CommentConvert.class);
20 |
21 | /**
22 | * CommentDO -> FindCommentItemRspVO
23 | * @param bean
24 | * @return
25 | */
26 | FindCommentItemRspVO convertDO2VO(CommentDO bean);
27 |
28 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/convert/CommentConvert.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.convert;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.comment.FindCommentPageListRspVO;
4 | import com.quanxiaoha.weblog.common.domain.dos.CommentDO;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.factory.Mappers;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024/4/6 22:35
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 |
15 | @Mapper
16 | public interface CommentConvert {
17 | /**
18 | * 初始化 convert 实例
19 | */
20 | CommentConvert INSTANCE = Mappers.getMapper(CommentConvert.class);
21 |
22 | /**
23 | * 将 DO 转化为 VO
24 | * @param bean
25 | * @return
26 | */
27 | FindCommentPageListRspVO convertDO2VO(CommentDO bean);
28 |
29 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/UpdateWikiIsPublishReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @Author: 木萨·塔布提
13 | * @Date: 2024-04-01 13:17
14 | * @Version: v1.0.0
15 | * @Description: TODO
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "更新知识库发布状态 VO")
22 | public class UpdateWikiIsPublishReqVO {
23 |
24 | @NotNull(message = "知识库 ID 不能为空")
25 | private Long id;
26 |
27 | @NotNull(message = "知识库发布状态不能为空")
28 | private Boolean isPublish;
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/service/TagService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.service;
2 |
3 | import com.quanxiaoha.weblog.common.utils.Response;
4 | import com.quanxiaoha.weblog.web.model.vo.tag.FindTagArticlePageListReqVO;
5 | import com.quanxiaoha.weblog.web.model.vo.tag.FindTagListReqVO;
6 |
7 | /**
8 | * @author: 木萨·塔布提
9 | * @url: blog.arnasoft.site
10 | * @date: 2023-09-15 14:03
11 | * @description: 分类
12 | **/
13 | public interface TagService {
14 | /**
15 | * 获取标签列表
16 | * @return
17 | */
18 | Response findTagList(FindTagListReqVO findTagListReqVO);
19 |
20 | /**
21 | * 获取标签下文章分页列表
22 | * @param findTagArticlePageListReqVO
23 | * @return
24 | */
25 | Response findTagPageList(FindTagArticlePageListReqVO findTagArticlePageListReqVO);
26 | }
27 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/test/java/com/quanxiaoha/weblog/common/WeblogModuleCommonApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common;
2 |
3 | import com.quanxiaoha.weblog.common.domain.dos.UserDO;
4 | import com.quanxiaoha.weblog.common.domain.mapper.UserMapper;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.junit.jupiter.api.Test;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.boot.test.context.SpringBootTest;
9 |
10 | import java.util.Date;
11 |
12 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = WeblogModuleCommonApplicationTests.Application.class)
13 | @Slf4j
14 | class WeblogModuleCommonApplicationTests {
15 |
16 | public static class Application {
17 | }
18 |
19 | @Test
20 | public void test() {
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/wiki/FindWikiCatalogListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.wiki;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024-04-01 18:32
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindWikiCatalogListRspVO {
21 |
22 | /**
23 | * 知识库 ID
24 | */
25 | private Long id;
26 |
27 | private Long articleId;
28 |
29 | private String title;
30 |
31 | private Integer level;
32 |
33 | /**
34 | * 二级目录
35 | */
36 | private List children;
37 |
38 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/composables/util.js:
--------------------------------------------------------------------------------
1 | import nprogress from "nprogress"
2 |
3 | nprogress.configure({ showSpinner: false });
4 |
5 | // 消息提示
6 | export function showMessage(message = '提示内容', type = 'success', customClass = '') {
7 | return ElMessage({
8 | type: type,
9 | message,
10 | customClass,
11 | })
12 | }
13 |
14 | // 弹出确认框
15 | export function showModel(content = '提示内容', type = 'warning', title = '') {
16 | return ElMessageBox.confirm(
17 | content,
18 | title,
19 | {
20 | confirmButtonText: '确定',
21 | cancelButtonText: '取消',
22 | type,
23 | }
24 | )
25 | }
26 |
27 | // 显示页面加载 Loading
28 | export function showPageLoading() {
29 | nprogress.start()
30 | }
31 |
32 | // 隐藏页面加载 Loading
33 | export function hidePageLoading() {
34 | nprogress.done()
35 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/category/DeleteCategoryReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.category;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 | import org.hibernate.validator.constraints.Length;
9 |
10 | import javax.validation.constraints.NotBlank;
11 | import javax.validation.constraints.NotNull;
12 |
13 | /**
14 | * @author: 木萨·塔布提
15 | * @url: blog.arnasoft.site
16 | * @date: 2023-09-15 14:07
17 | * @description: 删除分类
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @ApiModel(value = "删除分类 VO")
24 | public class DeleteCategoryReqVO {
25 |
26 | @NotNull(message = "分类 ID 不能为空")
27 | private Long id;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/service/AdminBlogSettingsService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.service;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.blogsettings.UpdateBlogSettingsReqVO;
4 | import com.quanxiaoha.weblog.admin.model.vo.user.UpdateAdminUserPasswordReqVO;
5 | import com.quanxiaoha.weblog.common.utils.Response;
6 |
7 | /**
8 | * @author: 木萨·塔布提
9 | * @url: blog.arnasoft.site
10 | * @date: 2023-09-15 14:03
11 | * @description: TODO
12 | **/
13 | public interface AdminBlogSettingsService {
14 | /**
15 | * 更新博客设置信息
16 | * @param updateBlogSettingsReqVO
17 | * @return
18 | */
19 | Response updateBlogSettings(UpdateBlogSettingsReqVO updateBlogSettingsReqVO);
20 |
21 | /**
22 | * 获取博客设置详情
23 | * @return
24 | */
25 | Response findDetail();
26 | }
27 |
--------------------------------------------------------------------------------
/weblog-vue3/src/layouts/frontend/components/WikiFooter.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/convert/ArticleDetailConvert.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.convert;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.article.FindArticleDetailRspVO;
4 | import com.quanxiaoha.weblog.common.domain.dos.ArticleDO;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.factory.Mappers;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023/10/8 14:57
12 | * @description: 文章详情转换
13 | **/
14 | @Mapper
15 | public interface ArticleDetailConvert {
16 | /**
17 | * 初始化 convert 实例
18 | */
19 | ArticleDetailConvert INSTANCE = Mappers.getMapper(ArticleDetailConvert.class);
20 |
21 | /**
22 | * 将 DO 转化为 VO
23 | * @param bean
24 | * @return
25 | */
26 | FindArticleDetailRspVO convertDO2VO(ArticleDO bean);
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/utils/JsonUtil.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.utils;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import lombok.extern.slf4j.Slf4j;
6 |
7 | /**
8 | * @author: 木萨·塔布提
9 | * @url: blog.arnasoft.site
10 | * @date: 2023-08-14 16:27
11 | * @description: JSON 工具类
12 | **/
13 | @Slf4j
14 | public class JsonUtil {
15 |
16 | private static final ObjectMapper INSTANCE = new ObjectMapper();
17 |
18 | public static String toJsonString(Object obj) {
19 | try {
20 | return INSTANCE.writeValueAsString(obj);
21 | } catch (JsonProcessingException e) {
22 | // todo Jackson 出参打印包含 Java 8 新日期出错问题
23 | return obj.toString();
24 | }
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/search/SearchArticlePageListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.search;
2 |
3 | import com.quanxiaoha.weblog.common.model.BasePageQuery;
4 | import io.swagger.annotations.ApiModel;
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 | * @Author: 木萨·塔布提
14 | * @Date: 2024-03-27 18:11
15 | * @Version: v1.0.0
16 | * @Description: TODO
17 | **/
18 | @Data
19 | @Builder
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @ApiModel(value = "文章搜索 VO")
23 | public class SearchArticlePageListReqVO extends BasePageQuery {
24 | /**
25 | * 查询关键词
26 | */
27 | @NotBlank(message = "搜索关键词不能为空")
28 | private String word;
29 | }
30 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/ArticleTagRelDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Builder;
8 | import lombok.Data;
9 | import lombok.NoArgsConstructor;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-08-22 17:01
15 | * @description: 文章
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @TableName("t_article_tag_rel")
22 | public class ArticleTagRelDO {
23 |
24 | @TableId(type = IdType.AUTO)
25 | private Long id;
26 |
27 | private Long articleId;
28 |
29 | private Long tagId;
30 | }
31 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/convert/BlogSettingsConvert.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.convert;
2 |
3 | import com.quanxiaoha.weblog.common.domain.dos.BlogSettingsDO;
4 | import com.quanxiaoha.weblog.web.model.vo.blogsettings.FindBlogSettingsDetailRspVO;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.factory.Mappers;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023/10/8 14:57
12 | * @description: 博客设置转换
13 | **/
14 | @Mapper
15 | public interface BlogSettingsConvert {
16 | /**
17 | * 初始化 convert 实例
18 | */
19 | BlogSettingsConvert INSTANCE = Mappers.getMapper(BlogSettingsConvert.class);
20 |
21 | /**
22 | * 将 DO 转化为 VO
23 | * @param bean
24 | * @return
25 | */
26 | FindBlogSettingsDetailRspVO convertDO2VO(BlogSettingsDO bean);
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/blogsettings/FindBlogSettingsDetailRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.blogsettings;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-09-15 14:07
12 | * @description: 博客设置详情
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class FindBlogSettingsDetailRspVO {
19 | private String logo;
20 | private String name;
21 | private String author;
22 | private String introduction;
23 | private String avatar;
24 | private String githubHomepage;
25 | private String csdnHomepage;
26 | private String giteeHomepage;
27 | private String zhihuHomepage;
28 | }
29 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/category/AddCategoryReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.category;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 | import org.hibernate.validator.constraints.Length;
9 |
10 | import javax.validation.constraints.NotBlank;
11 |
12 | /**
13 | * @author: 木萨·塔布提
14 | * @url: blog.arnasoft.site
15 | * @date: 2023-09-15 14:07
16 | * @description: 分类新增
17 | **/
18 | @Data
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @Builder
22 | @ApiModel(value = "添加分类 VO")
23 | public class AddCategoryReqVO {
24 |
25 | @NotBlank(message = "分类名称不能为空")
26 | @Length(min = 1, max = 20, message = "分类名称字数限制 1 ~ 20 之间")
27 | private String name;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/dashboard/FindDashboardStatisticsInfoRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.dashboard;
2 |
3 |
4 | import io.swagger.annotations.ApiModel;
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 = "查询仪表盘基础统计信息入参 VO")
15 | public class FindDashboardStatisticsInfoRspVO {
16 | /**
17 | * 文章总数
18 | */
19 | private Long articleTotalCount;
20 |
21 | /**
22 | * 分类总数
23 | */
24 | private Long categoryTotalCount;
25 |
26 | /**
27 | * 标签总数
28 | */
29 | private Long tagTotalCount;
30 |
31 | /**
32 | * 总浏览量
33 | */
34 | private Long pvTotalCount;
35 | }
36 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/tag/AddTagReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.tag;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 | import org.hibernate.validator.constraints.Length;
9 |
10 | import javax.validation.constraints.NotBlank;
11 | import javax.validation.constraints.NotEmpty;
12 | import java.util.List;
13 |
14 | /**
15 | * @author: 木萨·塔布提
16 | * @url: blog.arnasoft.site
17 | * @date: 2023-09-15 14:07
18 | * @description: 标签新增
19 | **/
20 | @Data
21 | @AllArgsConstructor
22 | @NoArgsConstructor
23 | @Builder
24 | @ApiModel(value = "添加标签 VO")
25 | public class AddTagReqVO {
26 |
27 | @NotEmpty(message = "标签集合不能为空")
28 | private List tags;
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/statistics/FindStatisticsInfoRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.statistics;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024-03-27 16:19
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class FindStatisticsInfoRspVO {
19 | /**
20 | * 文章总数
21 | */
22 | private Long articleTotalCount;
23 |
24 | /**
25 | * 分类总数
26 | */
27 | private Long categoryTotalCount;
28 |
29 | /**
30 | * 标签总数
31 | */
32 | private Long tagTotalCount;
33 |
34 | /**
35 | * 总浏览量
36 | */
37 | private Long pvTotalCount;
38 | }
39 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/ArticleContentDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Builder;
8 | import lombok.Data;
9 | import lombok.NoArgsConstructor;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-08-22 17:01
15 | * @description: 文章内容
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @TableName("t_article_content")
22 | public class ArticleContentDO {
23 |
24 | @TableId(type = IdType.AUTO)
25 | private Long id;
26 |
27 | private Long articleId;
28 |
29 | private String content;
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/ArticleCategoryRelDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Builder;
8 | import lombok.Data;
9 | import lombok.NoArgsConstructor;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-08-22 17:01
15 | * @description: 文章
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @TableName("t_article_category_rel")
22 | public class ArticleCategoryRelDO {
23 |
24 | @TableId(type = IdType.AUTO)
25 | private Long id;
26 |
27 | private Long articleId;
28 |
29 | private Long categoryId;
30 | }
31 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/archive/FindArchiveArticleRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.archive;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDate;
9 | import java.time.YearMonth;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-09-15 14:07
15 | * @description: 归档列表中的文章
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | public class FindArchiveArticleRspVO {
22 | private Long id;
23 | private String cover;
24 | private String title;
25 | /**
26 | * 发布日期
27 | */
28 | private LocalDate createDate;
29 |
30 | /**
31 | * 发布的月份(此字段不需要展示在前端,主要用于按月份分组使用)
32 | */
33 | private YearMonth createMonth;
34 | }
35 |
--------------------------------------------------------------------------------
/weblog-vue3/src/main.js:
--------------------------------------------------------------------------------
1 | import '@/assets/main.css'
2 | import 'animate.css';
3 | import 'nprogress/nprogress.css'
4 |
5 | import { createApp } from 'vue'
6 | // 引入全局状态管理 Pinia
7 | import pinia from '@/stores'
8 | import App from '@/App.vue'
9 | // 导入路由
10 | import router from '@/router'
11 | // 导入全局路由守卫
12 | import '@/permission'
13 | // 导入 Element Plus 图标
14 | import * as ElementPlusIconsVue from '@element-plus/icons-vue'
15 | // 导入 element-plus 暗黑 css
16 | import 'element-plus/theme-chalk/dark/css-vars.css'
17 | // 图片点击放大
18 | import 'viewerjs/dist/viewer.css'
19 | import VueViewer from 'v-viewer'
20 |
21 | const app = createApp(App)
22 |
23 | // 应用路由
24 | app.use(router)
25 | // 应用 Pinia
26 | app.use(pinia)
27 |
28 | // 引入图标
29 | for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
30 | app.component(key, component)
31 | }
32 |
33 | app.use(VueViewer)
34 |
35 | app.mount('#app')
36 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/comment/ExamineCommentReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.comment;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.NotNull;
10 |
11 | /**
12 | * @Author: 木萨·塔布提
13 | * @Date: 2024/4/6 23:19
14 | * @Version: v1.0.0
15 | * @Description: TODO
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "评论审核 VO")
22 | public class ExamineCommentReqVO {
23 |
24 | @NotNull(message = "评论 ID 不能为空")
25 | private Long id;
26 |
27 | @NotNull(message = "评论状态不能为空")
28 | private Integer status;
29 |
30 | /**
31 | * 原因
32 | */
33 | private String reason;
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/search/SearchArticlePageListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.search;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024-03-27 18:12
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 | @Data
15 | @Builder
16 | @AllArgsConstructor
17 | @NoArgsConstructor
18 | public class SearchArticlePageListRspVO {
19 | /**
20 | * 文章 ID
21 | */
22 | private Long id;
23 | /**
24 | * 封面
25 | */
26 | private String cover;
27 | /**
28 | * 标题
29 | */
30 | private String title;
31 | /**
32 | * 摘要
33 | */
34 | private String summary;
35 | /**
36 | * 发布日期
37 | */
38 | private String createDate;
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/config/RestTemplateConfig.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.http.client.SimpleClientHttpRequestFactory;
6 | import org.springframework.web.client.RestTemplate;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024/4/3 19:39
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 |
15 | @Configuration
16 | public class RestTemplateConfig {
17 |
18 | @Bean
19 | public RestTemplate restTemplate() {
20 | SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
21 | factory.setConnectTimeout(5000); // 连接超时时间:5秒
22 | factory.setReadTimeout(5000); // 读取超时时间:5秒
23 | return new RestTemplate(factory);
24 | }
25 |
26 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/service/CategoryService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.service;
2 |
3 | import com.quanxiaoha.weblog.common.utils.Response;
4 | import com.quanxiaoha.weblog.web.model.vo.category.FindCategoryArticlePageListReqVO;
5 | import com.quanxiaoha.weblog.web.model.vo.category.FindCategoryListReqVO;
6 |
7 | /**
8 | * @author: 木萨·塔布提
9 | * @url: blog.arnasoft.site
10 | * @date: 2023-09-15 14:03
11 | * @description: 分类
12 | **/
13 | public interface CategoryService {
14 | /**
15 | * 获取分类列表
16 | * @return
17 | */
18 | Response findCategoryList(FindCategoryListReqVO findCategoryListReqVO);
19 |
20 | /**
21 | * 获取分类下文章分页数据
22 | * @param findCategoryArticlePageListReqVO
23 | * @return
24 | */
25 | Response findCategoryArticlePageList(FindCategoryArticlePageListReqVO findCategoryArticlePageListReqVO);
26 | }
27 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/tag/FindTagPageListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.tag;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDateTime;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-09-15 14:07
14 | * @description: 标签分页
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindTagPageListRspVO {
21 |
22 | /**
23 | * 标签 ID
24 | */
25 | private Long id;
26 |
27 | /**
28 | * 标签名称
29 | */
30 | private String name;
31 |
32 | /**
33 | * 创建时间
34 | */
35 | private LocalDateTime createTime;
36 |
37 | /**
38 | * 文章总数
39 | */
40 | private Integer articlesTotal;
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/category/FindCategoryPageListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.category;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDateTime;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-09-15 14:07
14 | * @description: 分类分页
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindCategoryPageListRspVO {
21 | /**
22 | * 分类 ID
23 | */
24 | private Long id;
25 |
26 | /**
27 | * 分类名称
28 | */
29 | private String name;
30 |
31 | /**
32 | * 创建时间
33 | */
34 | private LocalDateTime createTime;
35 |
36 | /**
37 | * 文章总数
38 | */
39 | private Integer articlesTotal;
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/service/ArticleService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.service;
2 |
3 | import com.quanxiaoha.weblog.common.utils.Response;
4 | import com.quanxiaoha.weblog.web.model.vo.article.FindArticleDetailReqVO;
5 | import com.quanxiaoha.weblog.web.model.vo.article.FindIndexArticlePageListReqVO;
6 |
7 | /**
8 | * @author: 木萨·塔布提
9 | * @url: blog.arnasoft.site
10 | * @date: 2023-09-15 14:03
11 | * @description: 文章
12 | **/
13 | public interface ArticleService {
14 | /**
15 | * 获取首页文章分页数据
16 | * @param findIndexArticlePageListReqVO
17 | * @return
18 | */
19 | Response findArticlePageList(FindIndexArticlePageListReqVO findIndexArticlePageListReqVO);
20 |
21 | /**
22 | * 获取文章详情
23 | * @param findArticleDetailReqVO
24 | * @return
25 | */
26 | Response findArticleDetail(FindArticleDetailReqVO findArticleDetailReqVO);
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/convert/WikiConvert.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.convert;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.wiki.FindWikiPageListRspVO;
4 | import com.quanxiaoha.weblog.common.domain.dos.WikiDO;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.Mapping;
7 | import org.mapstruct.factory.Mappers;
8 |
9 | /**
10 | * @Author: 木萨·塔布提
11 | * @Date: 2024-04-01 13:06
12 | * @Version: v1.0.0
13 | * @Description: TODO
14 | **/
15 | @Mapper
16 | public interface WikiConvert {
17 | /**
18 | * 初始化 convert 实例
19 | */
20 | WikiConvert INSTANCE = Mappers.getMapper(WikiConvert.class);
21 |
22 | /**
23 | * WikiDO -> FindWikiPageListRspVO
24 | * @param bean
25 | * @return
26 | */
27 | @Mapping(target = "isTop", expression = "java(bean.getWeight() > 0)")
28 | FindWikiPageListRspVO convertDO2VO(WikiDO bean);
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/config/MinioConfig.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.config;
2 |
3 | import io.minio.MinioClient;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-05-11 8:49
12 | * @description: TODO
13 | **/
14 | @Configuration
15 | public class MinioConfig {
16 | @Autowired
17 | private MinioProperties minioProperties;
18 |
19 | @Bean
20 | public MinioClient minioClient() {
21 | // 构建 Minio 客户端
22 | return MinioClient.builder()
23 | .endpoint(minioProperties.getEndpoint())
24 | .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
25 | .build();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/resources/spy.properties:
--------------------------------------------------------------------------------
1 | #3.2.1????
2 | modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
3 | #3.2.1?????????
4 | #modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
5 | # ???????
6 | logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
7 | #????????
8 | appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
9 | # ???????? sql
10 | #appender=com.p6spy.engine.spy.appender.Slf4JLogger
11 | # ?? p6spy driver ??
12 | deregisterdrivers=true
13 | # ??JDBC URL??
14 | useprefix=true
15 | # ???? Log ??,????????error,info,batch,debug,statement,commit,rollback,result,resultset.
16 | excludecategories=info,debug,result,commit,resultset
17 | # ????
18 | dateformat=yyyy-MM-dd HH:mm:ss
19 | # ???????
20 | #driverlist=org.h2.Driver
21 | # ?????SQL??
22 | outagedetection=true
23 | # ?SQL???? 2 ?
24 | outagedetectioninterval=2
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/mapper/UserRoleMapper.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5 | import com.quanxiaoha.weblog.common.domain.dos.UserRoleDO;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author: 木萨·塔布提
11 | * @url: blog.arnasoft.site
12 | * @date: 2023-08-22 17:06
13 | * @description: TODO
14 | **/
15 | public interface UserRoleMapper extends BaseMapper {
16 | /**
17 | * 根据用户名查询
18 | * @param username
19 | * @return
20 | */
21 | default List selectByUsername(String username) {
22 | LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
23 | wrapper.eq(UserRoleDO::getUsername, username);
24 |
25 | return selectList(wrapper);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/weblog-vue3/src/components/CountTo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ d.num.toFixed(0) }}
4 |
5 |
6 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/user/UpdateAdminUserPasswordReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.user;
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 javax.validation.constraints.*;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-09-15 14:07
15 | * @description: TODO
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @ApiModel(value = "修改用户密码 VO")
22 | public class UpdateAdminUserPasswordReqVO {
23 |
24 | @NotBlank(message = "用户名不能为空")
25 | @ApiModelProperty(value = "用户名")
26 | private String username;
27 |
28 | @NotBlank(message = "密码不能为空")
29 | @ApiModelProperty(value = "密码")
30 | private String password;
31 | }
32 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/UpdateWikiCatalogReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.Valid;
10 | import javax.validation.constraints.NotNull;
11 | import java.util.List;
12 |
13 | /**
14 | * @Author: 木萨·塔布提
15 | * @Date: 2024-04-01 15:47
16 | * @Version: v1.0.0
17 | * @Description: TODO
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @ApiModel(value = "更新知识库目录数据入参 VO")
24 | public class UpdateWikiCatalogReqVO {
25 |
26 | /**
27 | * 知识库 ID
28 | */
29 | @NotNull(message = "知识库 ID 不能为空")
30 | private Long id;
31 |
32 | /**
33 | * 目录
34 | */
35 | @Valid
36 | private List catalogs;
37 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/comment/FindCommentPageListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.comment;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDateTime;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024/4/6 22:34
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 |
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | public class FindCommentPageListRspVO {
22 |
23 | private Long id;
24 |
25 | private String routerUrl;
26 |
27 | private String avatar;
28 |
29 | private String nickname;
30 |
31 | private String mail;
32 |
33 | private String website;
34 |
35 | private LocalDateTime createTime;
36 |
37 | private String content;
38 |
39 | private Integer status;
40 |
41 | private String reason;
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-jwt/src/main/java/com/quanxiaoha/weblog/jwt/config/PasswordEncoderConfig.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.jwt.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
5 | import org.springframework.security.crypto.password.PasswordEncoder;
6 | import org.springframework.stereotype.Component;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-08-24 9:17
12 | * @description: 密码加密
13 | **/
14 | @Component
15 | public class PasswordEncoderConfig {
16 |
17 | @Bean
18 | public PasswordEncoder passwordEncoder() {
19 | // BCrypt 是一种安全且适合密码存储的哈希算法,它在进行哈希时会自动加入“盐”,增加密码的安全性。
20 | return new BCryptPasswordEncoder();
21 | }
22 |
23 | public static void main(String[] args) {
24 | BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
25 | System.out.println(encoder.encode("111"));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/FindWikiPageListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import com.quanxiaoha.weblog.common.model.BasePageQuery;
4 | import io.swagger.annotations.ApiModel;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import java.time.LocalDate;
11 |
12 | /**
13 | * @Author: 木萨·塔布提
14 | * @Date: 2024-04-01 13:03
15 | * @Version: v1.0.0
16 | * @Description: TODO
17 | **/
18 | @Data
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @Builder
22 | @ApiModel(value = "查询知识库分页数据入参 VO")
23 | public class FindWikiPageListReqVO extends BasePageQuery {
24 |
25 | /**
26 | * 知识库标题
27 | */
28 | private String title;
29 |
30 | /**
31 | * 发布的起始日期
32 | */
33 | private LocalDate startDate;
34 |
35 | /**
36 | * 发布的结束日期
37 | */
38 | private LocalDate endDate;
39 |
40 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/composables/cookie.js:
--------------------------------------------------------------------------------
1 | import { useCookies } from '@vueuse/integrations/useCookies'
2 |
3 | const cookie = useCookies()
4 |
5 | // ============================== Token 令牌 ==============================
6 |
7 | // 存储在 Cookie 中的 Token 的 key
8 | const TOKEN_KEY = 'Authorization'
9 |
10 | // 获取 Token 值
11 | export function getToken() {
12 | return cookie.get(TOKEN_KEY)
13 | }
14 |
15 | // 设置 Token 到 Cookie 中
16 | export function setToken(token) {
17 | return cookie.set(TOKEN_KEY, token)
18 | }
19 |
20 | // 删除 Token
21 | export function removeToken() {
22 | return cookie.remove(TOKEN_KEY)
23 | }
24 |
25 | // ============================== 标签页 ==============================
26 |
27 | // 存储在 Cookie 中的标签页数据的 key
28 | const TAB_LIST_KEY = 'tabList'
29 |
30 | // 获取 TabList
31 | export function getTabList() {
32 | return cookie.get(TAB_LIST_KEY)
33 | }
34 |
35 | // 存储 TabList 到 Cookie 中
36 | export function setTabList(tabList) {
37 | return cookie.set(TAB_LIST_KEY, tabList)
38 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/article/FindArticlePageListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.article;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDateTime;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-09-15 14:07
14 | * @description: 文章分页
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindArticlePageListRspVO {
21 |
22 | /**
23 | * 文章 ID
24 | */
25 | private Long id;
26 |
27 | /**
28 | * 文章标题
29 | */
30 | private String title;
31 |
32 | /**
33 | * 文章封面
34 | */
35 | private String cover;
36 |
37 | /**
38 | * 发布时间
39 | */
40 | private LocalDateTime createTime;
41 |
42 | /**
43 | * 是否置顶
44 | */
45 | private Boolean isTop;
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/tag/FindTagPageListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.tag;
2 |
3 | import com.quanxiaoha.weblog.common.model.BasePageQuery;
4 | import io.swagger.annotations.ApiModel;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import java.time.LocalDate;
11 |
12 | /**
13 | * @author: 木萨·塔布提
14 | * @url: blog.arnasoft.site
15 | * @date: 2023-09-15 14:07
16 | * @description: 标签分页
17 | **/
18 | @Data
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @Builder
22 | @ApiModel(value = "查询标签分页数据入参 VO")
23 | public class FindTagPageListReqVO extends BasePageQuery {
24 |
25 | /**
26 | * 标签名称
27 | */
28 | private String name;
29 |
30 | /**
31 | * 创建的起始日期
32 | */
33 | private LocalDate startDate;
34 |
35 | /**
36 | * 创建的结束日期
37 | */
38 | private LocalDate endDate;
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/FindWikiCatalogListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024-04-01 13:38
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindWikiCatalogListRspVO {
21 |
22 | /**
23 | * 知识库 ID
24 | */
25 | private Long id;
26 |
27 | private Long articleId;
28 |
29 | private String title;
30 |
31 | private Integer sort;
32 |
33 | private Integer level;
34 |
35 | /**
36 | * 是否处于编辑状态(用于前端是否显示编辑输入框)
37 | */
38 | private Boolean editing;
39 |
40 | /**
41 | * 二级目录
42 | */
43 | private List children;
44 |
45 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/AddWikiReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 | import org.hibernate.validator.constraints.Length;
9 |
10 | import javax.validation.constraints.NotBlank;
11 |
12 | /**
13 | * @Author: 木萨·塔布提
14 | * @Date: 2024-04-01 12:07
15 | * @Version: v1.0.0
16 | * @Description: TODO
17 | **/
18 | @Data
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @Builder
22 | @ApiModel(value = "新增知识库 VO")
23 | public class AddWikiReqVO {
24 |
25 | @NotBlank(message = "知识库标题不能为空")
26 | @Length(min = 1, max = 20, message = "知识库标题字数需大于 1 小于 20")
27 | private String title;
28 |
29 | @NotBlank(message = "知识库摘要不能为空")
30 | private String summary;
31 |
32 | @NotBlank(message = "知识库封面不能为空")
33 | private String cover;
34 |
35 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/service/WikiService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.service;
2 |
3 | import com.quanxiaoha.weblog.common.utils.Response;
4 | import com.quanxiaoha.weblog.web.model.vo.wiki.FindWikiArticlePreNextReqVO;
5 | import com.quanxiaoha.weblog.web.model.vo.wiki.FindWikiCatalogListReqVO;
6 |
7 | /**
8 | * @Author: 木萨·塔布提
9 | * @Date: 2024-04-01 18:25
10 | * @Version: v1.0.0
11 | * @Description: TODO
12 | **/
13 | public interface WikiService {
14 | /**
15 | * 获取知识库
16 | * @return
17 | */
18 | Response findWikiList();
19 |
20 | /**
21 | * 获取知识库目录
22 | * @param findWikiCatalogListReqVO
23 | * @return
24 | */
25 | Response findWikiCatalogList(FindWikiCatalogListReqVO findWikiCatalogListReqVO);
26 |
27 | /**
28 | * 获取上下页
29 | * @param findWikiArticlePreNextReqVO
30 | * @return
31 | */
32 | Response findArticlePreNext(FindWikiArticlePreNextReqVO findWikiArticlePreNextReqVO);
33 | }
34 |
--------------------------------------------------------------------------------
/weblog-vue3/src/components/icons/IconTooling.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
20 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/TagDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
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 | * @author: 木萨·塔布提
15 | * @url: blog.arnasoft.site
16 | * @date: 2023-08-22 17:01
17 | * @description: 标签
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @TableName("t_tag")
24 | public class TagDO {
25 |
26 | @TableId(type = IdType.AUTO)
27 | private Long id;
28 |
29 | private String name;
30 |
31 | private LocalDateTime createTime;
32 |
33 | private LocalDateTime updateTime;
34 |
35 | private Boolean isDeleted;
36 |
37 | private Integer articlesTotal;
38 | }
39 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/UserDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
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 | * @author: 木萨·塔布提
15 | * @url: blog.arnasoft.site
16 | * @date: 2023-08-22 17:01
17 | * @description: 用户
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @TableName("t_user")
24 | public class UserDO {
25 |
26 | @TableId(type = IdType.AUTO)
27 | private Long id;
28 |
29 | private String username;
30 |
31 | private String password;
32 |
33 | private LocalDateTime createTime;
34 |
35 | private LocalDateTime updateTime;
36 |
37 | private Boolean isDeleted;
38 | }
39 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/CategoryDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
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 | * @author: 木萨·塔布提
15 | * @url: blog.arnasoft.site
16 | * @date: 2023-08-22 17:01
17 | * @description: 分类
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @TableName("t_category")
24 | public class CategoryDO {
25 |
26 | @TableId(type = IdType.AUTO)
27 | private Long id;
28 |
29 | private String name;
30 |
31 | private LocalDateTime createTime;
32 |
33 | private LocalDateTime updateTime;
34 |
35 | private Boolean isDeleted;
36 |
37 | private Integer articlesTotal;
38 | }
--------------------------------------------------------------------------------
/weblog-vue3/src/api/admin/wiki.js:
--------------------------------------------------------------------------------
1 | import axios from "@/axios";
2 |
3 | // 获取文章分页数据
4 | export function getWikiPageList(data) {
5 | return axios.post("/admin/wiki/list", data)
6 | }
7 |
8 | // 新增知识库
9 | export function addWiki(data) {
10 | return axios.post("/admin/wiki/add", data)
11 | }
12 |
13 | // 更新知识库置顶状态
14 | export function updateWikiIsTop(data) {
15 | return axios.post("/admin/wiki/isTop/update", data)
16 | }
17 |
18 | // 更新知识库发布状态
19 | export function updateWikiIsPublish(data) {
20 | return axios.post("/admin/wiki/isPublish/update", data)
21 | }
22 |
23 | // 删除知识库
24 | export function deleteWiki(id) {
25 | return axios.post("/admin/wiki/delete", { id })
26 | }
27 |
28 | // 更新知识库
29 | export function updateWiki(data) {
30 | return axios.post("/admin/wiki/update", data)
31 | }
32 |
33 | // 获取知识库目录
34 | export function getWikiCatalogs(id) {
35 | return axios.post("/admin/wiki/catalog/list", {id})
36 | }
37 |
38 | // 更新知识库目录
39 | export function updateWikiCatalogs(data) {
40 | return axios.post("/admin/wiki/catalog/update", data)
41 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/blogsettings/FindBlogSettingsRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.blogsettings;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * @author: 木萨·塔布提
10 | * @url: blog.arnasoft.site
11 | * @date: 2023-09-15 14:07
12 | * @description: 博客基础信息
13 | **/
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Builder
18 | public class FindBlogSettingsRspVO {
19 |
20 | private String logo;
21 |
22 | private String name;
23 |
24 | private String author;
25 |
26 | private String introduction;
27 |
28 | private String avatar;
29 |
30 | private String githubHomepage;
31 |
32 | private String csdnHomepage;
33 |
34 | private String giteeHomepage;
35 |
36 | private String zhihuHomepage;
37 |
38 | private String mail;
39 |
40 | private Boolean isCommentSensiWordOpen;
41 |
42 | private Boolean isCommentExamineOpen;
43 | }
44 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/comment/FindCommentPageListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.comment;
2 |
3 | import com.quanxiaoha.weblog.common.model.BasePageQuery;
4 | import io.swagger.annotations.ApiModel;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import java.time.LocalDate;
11 |
12 | /**
13 | * @Author: 木萨·塔布提
14 | * @Date: 2024/4/6 20:48
15 | * @Version: v1.0.0
16 | * @Description: TODO
17 | **/
18 | @Data
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @Builder
22 | @ApiModel(value = "查询评论分页数据入参 VO")
23 | public class FindCommentPageListReqVO extends BasePageQuery {
24 |
25 | /**
26 | * 路由地址
27 | */
28 | private String routerUrl;
29 |
30 | /**
31 | * 发布的起始日期
32 | */
33 | private LocalDate startDate;
34 |
35 | /**
36 | * 发布的结束日期
37 | */
38 | private LocalDate endDate;
39 |
40 | /**
41 | * 状态
42 | */
43 | private Integer status;
44 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/StatisticsArticlePVDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Builder;
8 | import lombok.Data;
9 | import lombok.NoArgsConstructor;
10 |
11 | import java.time.LocalDate;
12 | import java.time.LocalDateTime;
13 |
14 | /**
15 | * @author: 木萨·塔布提
16 | * @url: blog.arnasoft.site
17 | * @date: 2023-08-22 17:01
18 | * @description: 每日文章 PV 访问量统计
19 | **/
20 | @Data
21 | @AllArgsConstructor
22 | @NoArgsConstructor
23 | @Builder
24 | @TableName("t_statistics_article_pv")
25 | public class StatisticsArticlePVDO {
26 |
27 | @TableId(type = IdType.AUTO)
28 | private Long id;
29 |
30 | private LocalDate pvDate;
31 |
32 | private Long pvCount;
33 |
34 | private LocalDateTime createTime;
35 |
36 | private LocalDateTime updateTime;
37 | }
38 |
--------------------------------------------------------------------------------
/weblog-vue3/src/components/icons/IconCommunity.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/article/FindArticlePageListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.article;
2 |
3 | import com.quanxiaoha.weblog.common.model.BasePageQuery;
4 | import io.swagger.annotations.ApiModel;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import java.time.LocalDate;
11 |
12 | /**
13 | * @author: 木萨·塔布提
14 | * @url: blog.arnasoft.site
15 | * @date: 2023-09-15 14:07
16 | * @description: 文章分页
17 | **/
18 | @Data
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @Builder
22 | @ApiModel(value = "查询文章分页数据入参 VO")
23 | public class FindArticlePageListReqVO extends BasePageQuery {
24 |
25 | /**
26 | * 文章标题
27 | */
28 | private String title;
29 |
30 | /**
31 | * 发布的起始日期
32 | */
33 | private LocalDate startDate;
34 |
35 | /**
36 | * 发布的结束日期
37 | */
38 | private LocalDate endDate;
39 |
40 | /**
41 | * 文章类型
42 | */
43 | private Integer type;
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/runner/StatisticsTagArticleTotalRunner.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.runner;
2 |
3 | import com.quanxiaoha.weblog.admin.service.AdminStatisticsService;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.CommandLineRunner;
7 | import org.springframework.scheduling.annotation.Async;
8 | import org.springframework.stereotype.Component;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024/3/28 22:52
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 | @Component
17 | @Slf4j
18 | public class StatisticsTagArticleTotalRunner implements CommandLineRunner {
19 |
20 | @Autowired
21 | private AdminStatisticsService statisticsService;
22 |
23 | @Override
24 | @Async("threadPoolTaskExecutor")
25 | public void run(String... args) throws Exception {
26 | log.info("==> 开始统计各标签下文章数量...");
27 | statisticsService.statisticsTagArticleTotal();
28 | log.info("==> 结束统计各标签下文章数量...");
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/config/InsertBatchSqlInjector.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.config;
2 |
3 | import com.baomidou.mybatisplus.core.injector.AbstractMethod;
4 | import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
5 | import com.baomidou.mybatisplus.core.metadata.TableInfo;
6 | import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-06-13 22:46
14 | * @description: 批量插入 SQL 注入器
15 | **/
16 | public class InsertBatchSqlInjector extends DefaultSqlInjector {
17 |
18 | @Override
19 | public List getMethodList(Class> mapperClass, TableInfo tableInfo) {
20 | // super.getMethodList() 保留 Mybatis Plus 自带的方法
21 | List methodList = super.getMethodList(mapperClass, tableInfo);
22 | // 添加自定义方法:批量插入,方法名为 insertBatchSomeColumn
23 | methodList.add(new InsertBatchSomeColumn());
24 | return methodList;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/runner/StatisticsCategoryArticleTotalRunner.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.runner;
2 |
3 | import com.quanxiaoha.weblog.admin.service.AdminStatisticsService;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.CommandLineRunner;
7 | import org.springframework.scheduling.annotation.Async;
8 | import org.springframework.stereotype.Component;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024/3/28 20:40
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 | @Component
17 | @Slf4j
18 | public class StatisticsCategoryArticleTotalRunner implements CommandLineRunner {
19 |
20 | @Autowired
21 | private AdminStatisticsService statisticsService;
22 |
23 | @Override
24 | @Async("threadPoolTaskExecutor")
25 | public void run(String... args) throws Exception {
26 | log.info("==> 开始统计各分类下文章数量...");
27 | statisticsService.statisticsCategoryArticleTotal();
28 | log.info("==> 结束统计各分类下文章数量...");
29 | }
30 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/convert/BlogSettingsConvert.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.convert;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.blogsettings.FindBlogSettingsRspVO;
4 | import com.quanxiaoha.weblog.admin.model.vo.blogsettings.UpdateBlogSettingsReqVO;
5 | import com.quanxiaoha.weblog.common.domain.dos.BlogSettingsDO;
6 | import org.mapstruct.Mapper;
7 | import org.mapstruct.factory.Mappers;
8 |
9 | /**
10 | * @author: 木萨·塔布提
11 | * @url: blog.arnasoft.site
12 | * @date: 2023/10/8 14:57
13 | * @description: 博客设置转换
14 | **/
15 | @Mapper
16 | public interface BlogSettingsConvert {
17 | /**
18 | * 初始化 convert 实例
19 | */
20 | BlogSettingsConvert INSTANCE = Mappers.getMapper(BlogSettingsConvert.class);
21 |
22 | /**
23 | * 将 VO 转化为 DO
24 | * @param bean
25 | * @return
26 | */
27 | BlogSettingsDO convertVO2DO(UpdateBlogSettingsReqVO bean);
28 |
29 | /**
30 | * 将 DO 转化为 VO
31 | * @param bean
32 | * @return
33 | */
34 | FindBlogSettingsRspVO convertDO2VO(BlogSettingsDO bean);
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 MUSA
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/WikiDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
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 | * @Author: 木萨·塔布提
15 | * @Date: 2024-04-01 12:03
16 | * @Version: v1.0.0
17 | * @Description: TODO
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @TableName("t_wiki")
24 | public class WikiDO {
25 |
26 | @TableId(type = IdType.AUTO)
27 | private Long id;
28 |
29 | private String title;
30 |
31 | private String cover;
32 |
33 | private String summary;
34 |
35 | private LocalDateTime createTime;
36 |
37 | private LocalDateTime updateTime;
38 |
39 | private Boolean isDeleted;
40 |
41 | private Integer weight;
42 |
43 | private Boolean isPublish;
44 | }
45 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/UpdateWikiCatalogItemReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import javax.validation.Valid;
9 | import javax.validation.constraints.NotBlank;
10 | import javax.validation.constraints.NotNull;
11 | import java.util.List;
12 |
13 | /**
14 | * @Author: 木萨·塔布提
15 | * @Date: 2024-04-01 15:47
16 | * @Version: v1.0.0
17 | * @Description: TODO
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | public class UpdateWikiCatalogItemReqVO {
24 |
25 | /**
26 | * 目录 ID
27 | */
28 | @NotNull(message = "目录 ID 不能为空")
29 | private Long id;
30 |
31 | private Long articleId;
32 |
33 | @NotBlank(message = "目录标题不能为空")
34 | private String title;
35 |
36 | private Integer sort;
37 |
38 | private Integer level;
39 |
40 | /**
41 | * 子目录
42 | */
43 | @Valid
44 | private List children;
45 |
46 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/UpdateWikiReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 | import org.hibernate.validator.constraints.Length;
9 |
10 | import javax.validation.constraints.NotBlank;
11 | import javax.validation.constraints.NotNull;
12 |
13 | /**
14 | * @Author: 木萨·塔布提
15 | * @Date: 2024-04-01 13:27
16 | * @Version: v1.0.0
17 | * @Description: TODO
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @ApiModel(value = "更新知识库 VO")
24 | public class UpdateWikiReqVO {
25 |
26 | @NotNull(message = "ID 不能为空")
27 | private Long id;
28 |
29 | @NotBlank(message = "知识库标题不能为空")
30 | @Length(min = 1, max = 20, message = "知识库标题字数需大于 1 小于 20")
31 | private String title;
32 |
33 | @NotBlank(message = "知识库摘要不能为空")
34 | private String summary;
35 |
36 | @NotBlank(message = "知识库封面不能为空")
37 | private String cover;
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/service/CommentService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.service;
2 |
3 | import com.quanxiaoha.weblog.common.utils.Response;
4 | import com.quanxiaoha.weblog.web.model.vo.comment.FindCommentListReqVO;
5 | import com.quanxiaoha.weblog.web.model.vo.comment.FindQQUserInfoReqVO;
6 | import com.quanxiaoha.weblog.web.model.vo.comment.PublishCommentReqVO;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024/4/3 19:54
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 | public interface CommentService {
15 |
16 | /**
17 | * 根据 QQ 号获取用户信息
18 | * @param findQQUserInfoReqVO
19 | * @return
20 | */
21 | Response findQQUserInfo(FindQQUserInfoReqVO findQQUserInfoReqVO);
22 |
23 | /**
24 | * 发布评论
25 | * @param publishCommentReqVO
26 | * @return
27 | */
28 | Response publishComment(PublishCommentReqVO publishCommentReqVO);
29 |
30 | /**
31 | * 查询页面所有评论
32 | * @param findCommentListReqVO
33 | * @return
34 | */
35 | Response findCommentList(FindCommentListReqVO findCommentListReqVO);
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/config/TheadPoolConfig.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.scheduling.annotation.EnableAsync;
6 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
7 |
8 | import java.util.concurrent.Executor;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023/11/9 10:47
14 | * @description: 线程池配置
15 | **/
16 | @Configuration
17 | @EnableAsync
18 | public class TheadPoolConfig {
19 |
20 | @Bean("threadPoolTaskExecutor")
21 | public Executor threadPoolTaskExecutor() {
22 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
23 | executor.setCorePoolSize(10); // 核心线程数
24 | executor.setMaxPoolSize(20); // 最大线程数
25 | executor.setQueueCapacity(100); // 队列容量
26 | executor.setThreadNamePrefix("WeblogThreadPool-"); // 线程名前缀
27 | executor.initialize();
28 | return executor;
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/wiki/FindWikiPageListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.wiki;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDateTime;
9 |
10 | /**
11 | * @Author: 木萨·塔布提
12 | * @Date: 2024-04-01 13:04
13 | * @Version: v1.0.0
14 | * @Description: TODO
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindWikiPageListRspVO {
21 |
22 | /**
23 | * 知识库 ID
24 | */
25 | private Long id;
26 |
27 | /**
28 | * 知识库标题
29 | */
30 | private String title;
31 |
32 | /**
33 | * 知识库封面
34 | */
35 | private String cover;
36 |
37 | /**
38 | * 摘要
39 | */
40 | private String summary;
41 |
42 | /**
43 | * 发布时间
44 | */
45 | private LocalDateTime createTime;
46 |
47 | /**
48 | * 是否置顶
49 | */
50 | private Boolean isTop;
51 |
52 | /**
53 | * 是否发布
54 | */
55 | private Boolean isPublish;
56 |
57 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/article/FindArticleDetailRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.article;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-09-15 14:07
14 | * @description: 文章详情
15 | **/
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @Builder
20 | public class FindArticleDetailRspVO {
21 |
22 | /**
23 | * 文章 ID
24 | */
25 | private Long id;
26 |
27 | /**
28 | * 文章标题
29 | */
30 | private String title;
31 |
32 | /**
33 | * 文章封面
34 | */
35 | private String cover;
36 |
37 | /**
38 | * 文章内容
39 | */
40 | private String content;
41 |
42 | /**
43 | * 分类 ID
44 | */
45 | private Long categoryId;
46 |
47 | /**
48 | * 标签 ID 集合
49 | */
50 | private List tagIds;
51 |
52 | /**
53 | * 摘要
54 | */
55 | private String summary;
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/category/FindCategoryPageListReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.category;
2 |
3 | import com.quanxiaoha.weblog.common.model.BasePageQuery;
4 | import io.swagger.annotations.ApiModel;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 | import org.hibernate.validator.constraints.Length;
10 |
11 | import javax.validation.constraints.NotBlank;
12 | import java.time.LocalDate;
13 | import java.time.LocalDateTime;
14 |
15 | /**
16 | * @author: 木萨·塔布提
17 | * @url: blog.arnasoft.site
18 | * @date: 2023-09-15 14:07
19 | * @description: 分类分页
20 | **/
21 | @Data
22 | @AllArgsConstructor
23 | @NoArgsConstructor
24 | @Builder
25 | @ApiModel(value = "查询分类分页数据入参 VO")
26 | public class FindCategoryPageListReqVO extends BasePageQuery {
27 |
28 | /**
29 | * 分类名称
30 | */
31 | private String name;
32 |
33 | /**
34 | * 创建的起始日期
35 | */
36 | private LocalDate startDate;
37 |
38 | /**
39 | * 创建的结束日期
40 | */
41 | private LocalDate endDate;
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/service/AdminCommentService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.service;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.comment.DeleteCommentReqVO;
4 | import com.quanxiaoha.weblog.admin.model.vo.comment.ExamineCommentReqVO;
5 | import com.quanxiaoha.weblog.admin.model.vo.comment.FindCommentPageListReqVO;
6 | import com.quanxiaoha.weblog.common.utils.Response;
7 |
8 | /**
9 | * @Author: 木萨·塔布提
10 | * @Date: 2024/4/6 22:36
11 | * @Version: v1.0.0
12 | * @Description: TODO
13 | **/
14 | public interface AdminCommentService {
15 |
16 | /**
17 | * 查询评论分页数据
18 | * @param findCommentPageListReqVO
19 | * @return
20 | */
21 | Response findCommentPageList(FindCommentPageListReqVO findCommentPageListReqVO);
22 |
23 | /**
24 | * 删除评论
25 | * @param deleteCommentReqVO
26 | * @return
27 | */
28 | Response deleteComment(DeleteCommentReqVO deleteCommentReqVO);
29 |
30 | /**
31 | * 评论审核
32 | * @param examineCommentReqVO
33 | * @return
34 | */
35 | Response examine(ExamineCommentReqVO examineCommentReqVO);
36 | }
37 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/ArticleDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
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 | * @author: 木萨·塔布提
15 | * @url: blog.arnasoft.site
16 | * @date: 2023-08-22 17:01
17 | * @description: 文章
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @TableName("t_article")
24 | public class ArticleDO {
25 |
26 | @TableId(type = IdType.AUTO)
27 | private Long id;
28 |
29 | private String title;
30 |
31 | private String cover;
32 |
33 | private String summary;
34 |
35 | private LocalDateTime createTime;
36 |
37 | private LocalDateTime updateTime;
38 |
39 | private Boolean isDeleted;
40 |
41 | private Long readNum;
42 |
43 | private Integer weight;
44 |
45 | private Integer type;
46 | }
47 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/WikiCatalogDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
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 | * @Author: 木萨·塔布提
15 | * @Date: 2024-04-01 12:03
16 | * @Version: v1.0.0
17 | * @Description: TODO
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @TableName("t_wiki_catalog")
24 | public class WikiCatalogDO {
25 |
26 | @TableId(type = IdType.AUTO)
27 | private Long id;
28 |
29 | private Long wikiId;
30 |
31 | private Long articleId;
32 |
33 | private String title;
34 |
35 | private Integer level;
36 |
37 | private Long parentId;
38 |
39 | private Integer sort;
40 |
41 | private LocalDateTime createTime;
42 |
43 | private LocalDateTime updateTime;
44 |
45 | private Boolean isDeleted;
46 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/article/FindIndexArticlePageListRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.article;
2 |
3 | import com.quanxiaoha.weblog.web.model.vo.category.FindCategoryListRspVO;
4 | import com.quanxiaoha.weblog.web.model.vo.tag.FindTagListRspVO;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import java.time.LocalDate;
11 | import java.util.List;
12 |
13 | /**
14 | * @author: 木萨·塔布提
15 | * @url: blog.arnasoft.site
16 | * @date: 2023-09-15 14:07
17 | * @description: 首页-文章分页
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | public class FindIndexArticlePageListRspVO {
24 | private Long id;
25 | private String cover;
26 | private String title;
27 | private LocalDate createDate;
28 | private String summary;
29 | /**
30 | * 文章分类
31 | */
32 | private FindCategoryListRspVO category;
33 |
34 | /**
35 | * 文章标签
36 | */
37 | private List tags;
38 |
39 | /**
40 | * 是否置顶
41 | */
42 | private Boolean isTop;
43 | }
44 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/test/java/com/quanxiaoha/weblog/admin/WeblogModuleAdminApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin;
2 |
3 | import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
4 | import com.quanxiaoha.weblog.common.domain.dos.UserDO;
5 | import com.quanxiaoha.weblog.common.domain.mapper.UserMapper;
6 | import org.junit.jupiter.api.Test;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
9 | import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
10 | import org.springframework.boot.test.context.SpringBootTest;
11 | import org.springframework.context.annotation.Import;
12 |
13 | import java.time.LocalDateTime;
14 |
15 | @SpringBootTest(classes = WeblogModuleAdminApplicationTests.Application.class)
16 | class WeblogModuleAdminApplicationTests {
17 | // @Import({
18 | // DataSourceAutoConfiguration.class, // Spring DB 自动配置类
19 | // DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
20 | // MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
21 | // })
22 | public static class Application {
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/controller/StatisticsController.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.controller;
2 |
3 | import com.quanxiaoha.weblog.common.aspect.ApiOperationLog;
4 | import com.quanxiaoha.weblog.common.utils.Response;
5 | import com.quanxiaoha.weblog.web.service.StatisticsService;
6 | import io.swagger.annotations.Api;
7 | import io.swagger.annotations.ApiOperation;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.web.bind.annotation.PostMapping;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | /**
14 | * @Author: 木萨·塔布提
15 | * @Date: 2024-03-27 16:40
16 | * @Version: v1.0.0
17 | * @Description: TODO
18 | **/
19 | @RestController
20 | @RequestMapping("/statistics")
21 | @Api(tags = "统计信息")
22 | public class StatisticsController {
23 |
24 | @Autowired
25 | private StatisticsService statisticsService;
26 |
27 | @PostMapping("/info")
28 | @ApiOperation(value = "前台获取统计信息")
29 | @ApiOperationLog(description = "前台获取统计信息")
30 | public Response findInfo() {
31 | return statisticsService.findInfo();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/controller/BlogSettingsController.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.controller;
2 |
3 | import com.quanxiaoha.weblog.common.aspect.ApiOperationLog;
4 | import com.quanxiaoha.weblog.common.utils.Response;
5 | import com.quanxiaoha.weblog.web.service.BlogSettingsService;
6 | import io.swagger.annotations.Api;
7 | import io.swagger.annotations.ApiOperation;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.web.bind.annotation.PostMapping;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | /**
14 | * @author: 木萨·塔布提
15 | * @url: blog.arnasoft.site
16 | * @date: 2023-09-15 14:01
17 | * @description: 博客设置
18 | **/
19 | @RestController
20 | @RequestMapping("/blog/settings")
21 | @Api(tags = "博客设置")
22 | public class BlogSettingsController {
23 |
24 | @Autowired
25 | private BlogSettingsService blogSettingsService;
26 |
27 | @PostMapping("/detail")
28 | @ApiOperation(value = "前台获取博客详情")
29 | @ApiOperationLog(description = "前台获取博客详情")
30 | public Response findDetail() {
31 | return blogSettingsService.findDetail();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/weblog-vue3/src/components/icons/IconDocumentation.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/weblog-vue3/src/components/ArticlePVLineChat.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/config/MybatisPlusConfig.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.config;
2 |
3 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
4 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
5 | import org.mybatis.spring.annotation.MapperScan;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | /**
10 | * @author: 木萨·塔布提
11 | * @url: blog.arnasoft.site
12 | * @date: 2023-08-22 16:52
13 | * @description: Mybatis Plus 配置文件
14 | **/
15 | @Configuration
16 | @MapperScan("com.quanxiaoha.weblog.common.domain.mapper")
17 | public class MybatisPlusConfig {
18 |
19 | /**
20 | * 分页插件
21 | * @return
22 | */
23 | @Bean
24 | public MybatisPlusInterceptor mybatisPlusInterceptor(){
25 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
26 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
27 | return interceptor;
28 | }
29 |
30 | /**
31 | * 自定义批量插入 SQL 注入器
32 | */
33 | @Bean
34 | public InsertBatchSqlInjector insertBatchSqlInjector() {
35 | return new InsertBatchSqlInjector();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/BlogSettingsDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Builder;
8 | import lombok.Data;
9 | import lombok.NoArgsConstructor;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-08-22 17:01
15 | * @description: 博客设置
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @TableName("t_blog_settings")
22 | public class BlogSettingsDO {
23 |
24 | @TableId(type = IdType.AUTO)
25 | private Long id;
26 |
27 | private String logo;
28 |
29 | private String name;
30 |
31 | private String author;
32 |
33 | private String introduction;
34 |
35 | private String avatar;
36 |
37 | private String githubHomepage;
38 |
39 | private String csdnHomepage;
40 |
41 | private String giteeHomepage;
42 |
43 | private String zhihuHomepage;
44 |
45 | private String mail;
46 |
47 | private Boolean isCommentSensiWordOpen;
48 |
49 | private Boolean isCommentExamineOpen;
50 | }
51 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/dos/CommentDO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
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 | * @Author: 木萨·塔布提
15 | * @Date: 2024/4/3 20:39
16 | * @Version: v1.0.0
17 | * @Description: TODO
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @TableName("t_comment")
24 | public class CommentDO {
25 |
26 | @TableId(type = IdType.AUTO)
27 | private Long id;
28 |
29 | private String content;
30 |
31 | private String avatar;
32 |
33 | private String nickname;
34 |
35 | private String mail;
36 |
37 | private String website;
38 |
39 | private String routerUrl;
40 |
41 | private LocalDateTime createTime;
42 |
43 | private LocalDateTime updateTime;
44 |
45 | private Boolean isDeleted;
46 |
47 | private Long replyCommentId;
48 |
49 | private Long parentCommentId;
50 |
51 | private Integer status;
52 |
53 | private String reason;
54 | }
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/article/PublishArticleReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.article;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 | import org.hibernate.validator.constraints.Length;
9 | import org.hibernate.validator.constraints.NotEmpty;
10 |
11 | import javax.validation.constraints.NotBlank;
12 | import javax.validation.constraints.NotNull;
13 | import java.util.List;
14 |
15 | /**
16 | * @author: 木萨·塔布提
17 | * @url: blog.arnasoft.site
18 | * @date: 2023-09-15 14:07
19 | * @description: 文章发布
20 | **/
21 | @Data
22 | @AllArgsConstructor
23 | @NoArgsConstructor
24 | @Builder
25 | @ApiModel(value = "发布文章 VO")
26 | public class PublishArticleReqVO {
27 |
28 | @NotBlank(message = "文章标题不能为空")
29 | @Length(min = 1, max = 40, message = "文章标题字数需大于 1 小于 40")
30 | private String title;
31 |
32 | @NotBlank(message = "文章内容不能为空")
33 | private String content;
34 |
35 | @NotBlank(message = "文章封面不能为空")
36 | private String cover;
37 |
38 | private String summary;
39 |
40 | @NotNull(message = "文章分类不能为空")
41 | private Long categoryId;
42 |
43 | @NotEmpty(message = "文章标签不能为空")
44 | private List tags;
45 | }
46 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/mapper/UserMapper.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
6 | import com.quanxiaoha.weblog.common.domain.dos.UserDO;
7 |
8 | import java.time.LocalDateTime;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-08-22 17:06
14 | * @description: TODO
15 | **/
16 | public interface UserMapper extends BaseMapper {
17 | default UserDO findByUsername(String username) {
18 | LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
19 | wrapper.eq(UserDO::getUsername, username);
20 | return selectOne(wrapper);
21 | }
22 |
23 | default int updatePasswordByUsername(String username, String password) {
24 | LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
25 | // 设置要更新的字段
26 | wrapper.set(UserDO::getPassword, password);
27 | wrapper.set(UserDO::getUpdateTime, LocalDateTime.now());
28 | // 更新条件
29 | wrapper.eq(UserDO::getUsername, username);
30 |
31 | return update(null, wrapper);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/comment/FindCommentItemRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.comment;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.LocalDateTime;
9 | import java.util.List;
10 |
11 | /**
12 | * @Author: 木萨·塔布提
13 | * @Date: 2024/4/3 21:21
14 | * @Version: v1.0.0
15 | * @Description: TODO
16 | **/
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | public class FindCommentItemRspVO {
22 |
23 | /**
24 | * 主键
25 | */
26 | private Long id;
27 |
28 | /**
29 | * 头像
30 | */
31 | private String avatar;
32 |
33 | /**
34 | * 昵称
35 | */
36 | private String nickname;
37 |
38 | /**
39 | * 网址
40 | */
41 | private String website;
42 |
43 | /**
44 | * 评论内容
45 | */
46 | private String content;
47 |
48 | /**
49 | * 发布时间
50 | */
51 | private LocalDateTime createTime;
52 |
53 | /**
54 | * 回复用户的昵称
55 | */
56 | private String replyNickname;
57 |
58 | /**
59 | * 子评论集合
60 | */
61 | private List childComments;
62 |
63 | /**
64 | * 是否展示回复表单(默认 false)
65 | */
66 | private Boolean isShowReplyForm;
67 |
68 | }
--------------------------------------------------------------------------------
/weblog-vue3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "msblog-vue3",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "vite",
7 | "build": "vite build",
8 | "preview": "vite preview"
9 | },
10 | "dependencies": {
11 | "@element-plus/icons-vue": "^2.1.0",
12 | "@vueuse/core": "^10.4.1",
13 | "@vueuse/integrations": "^10.4.1",
14 | "animate.css": "^4.1.1",
15 | "axios": "^1.5.0",
16 | "date-fns": "^2.30.0",
17 | "echarts": "^5.4.2",
18 | "element-plus": "^2.3.9",
19 | "flowbite": "^1.8.1",
20 | "gsap": "^3.12.2",
21 | "highlight.js": "^11.9.0",
22 | "md-editor-v3": "^4.8.1",
23 | "moment": "^2.29.4",
24 | "nprogress": "^0.2.0",
25 | "pinia": "^2.1.6",
26 | "pinia-plugin-persistedstate": "^3.2.0",
27 | "universal-cookie": "^6.1.0",
28 | "v-viewer": "^3.0.11",
29 | "viewerjs": "^1.11.6",
30 | "vue": "^3.3.4",
31 | "vue-draggable-plus": "^0.4.0",
32 | "vue-router": "^4.2.4"
33 | },
34 | "devDependencies": {
35 | "@vitejs/plugin-vue": "^4.2.3",
36 | "autoprefixer": "^10.4.15",
37 | "postcss": "^8.4.28",
38 | "tailwindcss": "^3.3.3",
39 | "unplugin-auto-import": "^0.16.6",
40 | "unplugin-vue-components": "^0.25.1",
41 | "vite": "^4.4.6",
42 | "vite-plugin-cdn-import": "^0.3.5",
43 | "vite-plugin-compression": "^0.5.1"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-jwt/src/main/java/com/quanxiaoha/weblog/jwt/handler/RestAccessDeniedHandler.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.jwt.handler;
2 |
3 | import com.quanxiaoha.weblog.common.enums.ResponseCodeEnum;
4 | import com.quanxiaoha.weblog.common.utils.Response;
5 | import com.quanxiaoha.weblog.jwt.utils.ResultUtil;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.security.access.AccessDeniedException;
8 | import org.springframework.security.web.access.AccessDeniedHandler;
9 | import org.springframework.stereotype.Component;
10 |
11 | import javax.servlet.ServletException;
12 | import javax.servlet.http.HttpServletRequest;
13 | import javax.servlet.http.HttpServletResponse;
14 | import java.io.IOException;
15 |
16 | /**
17 | * @author: 木萨·塔布提
18 | * @url: blog.arnasoft.site
19 | * @date: 2023-08-27 17:32
20 | * @description: 登录成功访问收保护的资源,但是权限不够
21 | **/
22 | @Slf4j
23 | @Component
24 | public class RestAccessDeniedHandler implements AccessDeniedHandler {
25 |
26 | @Override
27 | public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
28 | log.warn("登录成功访问收保护的资源,但是权限不够: ", accessDeniedException);
29 | // 预留,后面引入多角色时会用到
30 | ResultUtil.fail(response, Response.fail(ResponseCodeEnum.FORBIDDEN));
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/resources/application-dev.yml:
--------------------------------------------------------------------------------
1 |
2 | spring:
3 | datasource:
4 | # 指定数据库驱动类
5 | driver-class-name: com.mysql.cj.jdbc.Driver
6 | # 数据库连接信息
7 | url: jdbc:mysql://localhost:3306/weblog?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
8 | username: root
9 | password: root
10 | hikari: # 数据库连接池使用 Hikari
11 | minimum-idle: 5 # 连接池中最小空闲连接数
12 | maximum-pool-size: 20 # 连接池中允许的最大连接数
13 | auto-commit: true # 是否自动提交事务
14 | idle-timeout: 30000 # 连接在连接池中闲置的最长时间,超过这个时间会被释放。
15 | pool-name: Weblog-HikariCP # 自定义连接池的名字
16 | max-lifetime: 1800000 # 连接在连接池中的最大存活时间,超过这个时间会被强制关闭。
17 | connection-timeout: 30000 # 连接的超时时间
18 | connection-test-query: SELECT 1 # 用于测试连接是否可用的SQL查询
19 |
20 |
21 | #=================================================================
22 | # minio (上传图片需要,需配置成自己的地址)
23 | #=================================================================
24 | minio:
25 | endpoint: #endpoint
26 | accessKey: #accessKey
27 | secretKey: #secretKey
28 | bucketName: # bucketName
29 |
30 | #=================================================================
31 | # Lucene 全文检索
32 | #=================================================================
33 | lucene:
34 |
35 | indexDir: E:\\java_workspace\\lucene-index # lucene 索引存放的位置
36 | server:
37 | port: 8080
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/mapper/StatisticsArticlePVMapper.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 | import com.baomidou.mybatisplus.core.toolkit.Wrappers;
5 | import com.quanxiaoha.weblog.common.domain.dos.StatisticsArticlePVDO;
6 |
7 | import java.time.LocalDate;
8 | import java.util.List;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-08-22 17:06
14 | * @description: 每日文章 PV 访问量统计
15 | **/
16 | public interface StatisticsArticlePVMapper extends BaseMapper {
17 |
18 | /**
19 | * 对指定日期的文章 PV 访问量进行 +1
20 | * @param date
21 | * @return
22 | */
23 | default int increasePVCount(LocalDate date) {
24 | return update(null, Wrappers.lambdaUpdate()
25 | .setSql("pv_count = pv_count + 1")
26 | .eq(StatisticsArticlePVDO::getPvDate, date));
27 | }
28 |
29 | /**
30 | * 查询最近一周的文章 PV 访问量记录
31 | * @return
32 | */
33 | default List selectLatestWeekRecords() {
34 | return selectList(Wrappers.lambdaQuery()
35 | .le(StatisticsArticlePVDO::getPvDate, LocalDate.now()) // 小于等于当前日期
36 | .last("limit 7")); // 仅查询七条
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/weblog-vue3/src/layouts/frontend/components/ScrollToTopButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
38 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/article/UpdateArticleReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.article;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 | import org.hibernate.validator.constraints.Length;
9 | import org.hibernate.validator.constraints.NotEmpty;
10 |
11 | import javax.validation.constraints.NotBlank;
12 | import javax.validation.constraints.NotNull;
13 | import java.util.List;
14 |
15 | /**
16 | * @author: 木萨·塔布提
17 | * @url: blog.arnasoft.site
18 | * @date: 2023-09-15 14:07
19 | * @description: 更新文章
20 | **/
21 | @Data
22 | @AllArgsConstructor
23 | @NoArgsConstructor
24 | @Builder
25 | @ApiModel(value = "更新文章 VO")
26 | public class UpdateArticleReqVO {
27 |
28 | @NotNull(message = "文章 ID 不能为空")
29 | private Long id;
30 |
31 | @NotBlank(message = "文章标题不能为空")
32 | @Length(min = 1, max = 40, message = "文章标题字数需大于 1 小于 40")
33 | private String title;
34 |
35 | @NotBlank(message = "文章内容不能为空")
36 | private String content;
37 |
38 | @NotBlank(message = "文章封面不能为空")
39 | private String cover;
40 |
41 | private String summary;
42 |
43 | @NotNull(message = "文章分类不能为空")
44 | private Long categoryId;
45 |
46 | @NotEmpty(message = "文章标签不能为空")
47 | private List tags;
48 | }
49 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/comment/PublishCommentReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.comment;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 | import org.hibernate.validator.constraints.Length;
8 |
9 | import javax.validation.constraints.Email;
10 | import javax.validation.constraints.NotBlank;
11 |
12 | /**
13 | * @Author: 木萨·塔布提
14 | * @Date: 2024/4/3 20:40
15 | * @Version: v1.0.0
16 | * @Description: TODO
17 | **/
18 | @Data
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @Builder
22 | public class PublishCommentReqVO {
23 |
24 | /**
25 | * 头像
26 | */
27 | private String avatar;
28 |
29 | @NotBlank(message = "昵称不能为空")
30 | private String nickname;
31 |
32 | @NotBlank(message = "邮箱不能为空")
33 | @Email(message = "邮箱格式错误")
34 | private String mail;
35 |
36 | /**
37 | * 网址
38 | */
39 | private String website;
40 |
41 | @NotBlank(message = "路由地址不能为空")
42 | private String routerUrl;
43 |
44 | @NotBlank(message = "评论内容不能为空")
45 | @Length(min = 1, max = 120, message = "评论内容需大于 1 小于 120 字符")
46 | private String content;
47 |
48 | /**
49 | * 回复的评论 ID
50 | */
51 | private Long replyCommentId;
52 |
53 | /**
54 | * 父评论 ID
55 | */
56 | private Long parentCommentId;
57 |
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/controller/SearchController.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.controller;
2 |
3 | import com.quanxiaoha.weblog.common.aspect.ApiOperationLog;
4 | import com.quanxiaoha.weblog.common.utils.Response;
5 | import com.quanxiaoha.weblog.web.model.vo.search.SearchArticlePageListReqVO;
6 | import com.quanxiaoha.weblog.web.service.SearchService;
7 | import io.swagger.annotations.Api;
8 | import io.swagger.annotations.ApiOperation;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.validation.annotation.Validated;
11 | import org.springframework.web.bind.annotation.PostMapping;
12 | import org.springframework.web.bind.annotation.RequestBody;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | /**
16 | * @Author: 木萨·塔布提
17 | * @Date: 2024-03-27 18:18
18 | * @Version: v1.0.0
19 | * @Description: TODO
20 | **/
21 | @RestController
22 | @Api(tags = "搜索")
23 | public class SearchController {
24 |
25 | @Autowired
26 | private SearchService searchService;
27 |
28 | @PostMapping("/article/search")
29 | @ApiOperation(value = "文章搜索")
30 | @ApiOperationLog(description = "文章搜索")
31 | public Response searchArticlePageList(@RequestBody @Validated SearchArticlePageListReqVO searchArticlePageListReqVO) {
32 | return searchService.searchArticlePageList(searchArticlePageListReqVO);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/weblog-vue3/src/permission.js:
--------------------------------------------------------------------------------
1 | import router from '@/router/index'
2 | import { getToken } from '@/composables/cookie'
3 | import { showMessage } from '@/composables/util'
4 | import { showPageLoading, hidePageLoading } from '@/composables/util'
5 | import { useBlogSettingsStore } from '@/stores/blogsettings'
6 |
7 | // 全局路由前置守卫
8 | router.beforeEach((to, from, next) => {
9 | console.log('==> 全局路由前置守卫')
10 |
11 | // 展示页面加载 Loading
12 | showPageLoading()
13 |
14 | let token = getToken()
15 |
16 | if (!token && to.path.startsWith('/admin')) {
17 | // 若用户想访问后台(以 /admin 为前缀的路由)
18 | // 未登录,则强制跳转登录页
19 | showMessage('请先登录', 'warning')
20 | next({ path: '/login' })
21 | } else if (token && to.path == '/login') {
22 | // 若用户已经登录,且重复访问登录页
23 | showMessage('请勿重复登录', 'warning')
24 | // 跳转后台首页
25 | next({ path: '/admin/index' })
26 | } else if (!to.path.startsWith('/admin')) {
27 | // 如果访问的非 /admin 前缀路由
28 | // 引入博客设置 store
29 | let blogSettingsStore = useBlogSettingsStore()
30 | // 获取博客设置信息并保存到全局状态中
31 | blogSettingsStore.getBlogSettings()
32 | next()
33 | } else {
34 | next()
35 | }
36 | })
37 |
38 | // 全局路由后置守卫
39 | router.afterEach((to, from) => {
40 | // 动态设置页面 Titile
41 | let title = (to.meta.title ? to.meta.title : '') + ' - 程序猿小萨'
42 | document.title = title
43 |
44 | // 隐藏页面加载 Loading
45 | hidePageLoading()
46 | })
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/service/impl/BlogSettingsServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.service.impl;
2 |
3 | import com.quanxiaoha.weblog.common.domain.dos.BlogSettingsDO;
4 | import com.quanxiaoha.weblog.common.domain.mapper.BlogSettingsMapper;
5 | import com.quanxiaoha.weblog.common.utils.Response;
6 | import com.quanxiaoha.weblog.web.convert.BlogSettingsConvert;
7 | import com.quanxiaoha.weblog.web.model.vo.blogsettings.FindBlogSettingsDetailRspVO;
8 | import com.quanxiaoha.weblog.web.service.BlogSettingsService;
9 | import lombok.extern.slf4j.Slf4j;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Service;
12 |
13 | /**
14 | * @author: 木萨·塔布提
15 | * @url: blog.arnasoft.site
16 | * @date: 2023-09-15 14:03
17 | * @description: 博客设置
18 | **/
19 | @Service
20 | @Slf4j
21 | public class BlogSettingsServiceImpl implements BlogSettingsService {
22 |
23 | @Autowired
24 | private BlogSettingsMapper blogSettingsMapper;
25 |
26 | /**
27 | * 获取博客设置信息
28 | *
29 | * @return
30 | */
31 | @Override
32 | public Response findDetail() {
33 | // 查询博客设置信息(约定的 ID 为 1)
34 | BlogSettingsDO blogSettingsDO = blogSettingsMapper.selectById(1L);
35 | // DO 转 VO
36 | FindBlogSettingsDetailRspVO vo = BlogSettingsConvert.INSTANCE.convertDO2VO(blogSettingsDO);
37 |
38 | return Response.success(vo);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/controller/ArchiveController.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.controller;
2 |
3 | import com.quanxiaoha.weblog.common.aspect.ApiOperationLog;
4 | import com.quanxiaoha.weblog.common.utils.Response;
5 | import com.quanxiaoha.weblog.web.model.vo.archive.FindArchiveArticlePageListReqVO;
6 | import com.quanxiaoha.weblog.web.service.ArchiveService;
7 | import io.swagger.annotations.Api;
8 | import io.swagger.annotations.ApiOperation;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.validation.annotation.Validated;
11 | import org.springframework.web.bind.annotation.PostMapping;
12 | import org.springframework.web.bind.annotation.RequestBody;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | /**
16 | * @author: 木萨·塔布提
17 | * @url: blog.arnasoft.site
18 | * @date: 2023-09-15 14:01
19 | * @description: 文章归档
20 | **/
21 | @RestController
22 | @Api(tags = "文章归档")
23 | public class ArchiveController {
24 |
25 | @Autowired
26 | private ArchiveService archiveService;
27 |
28 | @PostMapping("/archive/list")
29 | @ApiOperation(value = "获取文章归档分页数据")
30 | @ApiOperationLog(description = "获取文章归档分页数据")
31 | public Response findArchivePageList(@RequestBody @Validated FindArchiveArticlePageListReqVO findArchiveArticlePageListReqVO) {
32 | return archiveService.findArchivePageList(findArchiveArticlePageListReqVO);
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/service/AdminTagService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.service;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.tag.AddTagReqVO;
4 | import com.quanxiaoha.weblog.admin.model.vo.tag.DeleteTagReqVO;
5 | import com.quanxiaoha.weblog.admin.model.vo.tag.FindTagPageListReqVO;
6 | import com.quanxiaoha.weblog.admin.model.vo.tag.SearchTagsReqVO;
7 | import com.quanxiaoha.weblog.common.utils.PageResponse;
8 | import com.quanxiaoha.weblog.common.utils.Response;
9 |
10 | /**
11 | * @author: 木萨·塔布提
12 | * @url: blog.arnasoft.site
13 | * @date: 2023-09-15 14:03
14 | * @description: TODO
15 | **/
16 | public interface AdminTagService {
17 |
18 | /**
19 | * 添加标签集合
20 | * @param addTagReqVO
21 | * @return
22 | */
23 | Response addTags(AddTagReqVO addTagReqVO);
24 |
25 | /**
26 | * 查询标签分页
27 | * @param findTagPageListReqVO
28 | * @return
29 | */
30 | PageResponse findTagPageList(FindTagPageListReqVO findTagPageListReqVO);
31 |
32 | /**
33 | * 删除标签
34 | * @param deleteTagReqVO
35 | * @return
36 | */
37 | Response deleteTag(DeleteTagReqVO deleteTagReqVO);
38 |
39 | /**
40 | * 根据标签关键词模糊查询
41 | * @param searchTagsReqVO
42 | * @return
43 | */
44 | Response searchTags(SearchTagsReqVO searchTagsReqVO);
45 |
46 | /**
47 | * 查询标签 Select 列表数据
48 | * @return
49 | */
50 | Response findTagSelectList();
51 | }
52 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/service/AdminCategoryService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.service;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.category.AddCategoryReqVO;
4 | import com.quanxiaoha.weblog.admin.model.vo.category.DeleteCategoryReqVO;
5 | import com.quanxiaoha.weblog.admin.model.vo.category.FindCategoryPageListReqVO;
6 | import com.quanxiaoha.weblog.admin.model.vo.tag.AddTagReqVO;
7 | import com.quanxiaoha.weblog.admin.model.vo.user.UpdateAdminUserPasswordReqVO;
8 | import com.quanxiaoha.weblog.common.utils.PageResponse;
9 | import com.quanxiaoha.weblog.common.utils.Response;
10 |
11 | /**
12 | * @author: 木萨·塔布提
13 | * @url: blog.arnasoft.site
14 | * @date: 2023-09-15 14:03
15 | * @description: TODO
16 | **/
17 | public interface AdminCategoryService {
18 | /**
19 | * 添加分类
20 | * @param addCategoryReqVO
21 | * @return
22 | */
23 | Response addCategory(AddCategoryReqVO addCategoryReqVO);
24 |
25 | /**
26 | * 分类分页数据查询
27 | * @param findCategoryPageListReqVO
28 | * @return
29 | */
30 | PageResponse findCategoryPageList(FindCategoryPageListReqVO findCategoryPageListReqVO);
31 |
32 | /**
33 | * 删除分类
34 | * @param deleteCategoryReqVO
35 | * @return
36 | */
37 | Response deleteCategory(DeleteCategoryReqVO deleteCategoryReqVO);
38 |
39 | /**
40 | * 获取文章分类的 Select 列表数据
41 | * @return
42 | */
43 | Response findCategorySelectList();
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/controller/AdminFileController.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.controller;
2 |
3 | import com.quanxiaoha.weblog.admin.service.AdminFileService;
4 | import com.quanxiaoha.weblog.common.aspect.ApiOperationLog;
5 | import com.quanxiaoha.weblog.common.utils.Response;
6 | import io.swagger.annotations.Api;
7 | import io.swagger.annotations.ApiOperation;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.security.access.prepost.PreAuthorize;
10 | import org.springframework.web.bind.annotation.PostMapping;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.RequestParam;
13 | import org.springframework.web.bind.annotation.RestController;
14 | import org.springframework.web.multipart.MultipartFile;
15 |
16 | /**
17 | * @author: 木萨·塔布提
18 | * @url: blog.arnasoft.site
19 | * @date: 2023-09-15 14:01
20 | * @description: 文件模块
21 | **/
22 | @RestController
23 | @RequestMapping("/admin")
24 | @Api(tags = "Admin 文件模块")
25 | public class AdminFileController {
26 |
27 | @Autowired
28 | private AdminFileService fileService;
29 |
30 | @PostMapping("/file/upload")
31 | @ApiOperation(value = "文件上传")
32 | @ApiOperationLog(description = "文件上传")
33 | @PreAuthorize("hasRole('ROLE_ADMIN')")
34 | public Response uploadFile(@RequestParam MultipartFile file) {
35 | return fileService.uploadFile(file);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/service/AdminArticleService.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.service;
2 |
3 | import com.quanxiaoha.weblog.admin.model.vo.article.*;
4 | import com.quanxiaoha.weblog.common.utils.Response;
5 |
6 | /**
7 | * @author: 木萨·塔布提
8 | * @url: blog.arnasoft.site
9 | * @date: 2023-09-15 14:03
10 | * @description: 文章
11 | **/
12 | public interface AdminArticleService {
13 | /**
14 | * 更新文章是否置顶
15 | * @param updateArticleIsTopReqVO
16 | * @return
17 | */
18 | Response updateArticleIsTop(UpdateArticleIsTopReqVO updateArticleIsTopReqVO);
19 |
20 | /**
21 | * 发布文章
22 | * @param publishArticleReqVO
23 | * @return
24 | */
25 | Response publishArticle(PublishArticleReqVO publishArticleReqVO);
26 |
27 | /**
28 | * 删除文章
29 | * @param deleteArticleReqVO
30 | * @return
31 | */
32 | Response deleteArticle(DeleteArticleReqVO deleteArticleReqVO);
33 |
34 | /**
35 | * 查询文章分页数据
36 | * @param findArticlePageListReqVO
37 | * @return
38 | */
39 | Response findArticlePageList(FindArticlePageListReqVO findArticlePageListReqVO);
40 |
41 | /**
42 | * 查询文章详情
43 | * @param findArticleDetailReqVO
44 | * @return
45 | */
46 | Response findArticleDetail(FindArticleDetailReqVO findArticleDetailReqVO);
47 |
48 | /**
49 | * 更新文章
50 | * @param updateArticleReqVO
51 | * @return
52 | */
53 | Response updateArticle(UpdateArticleReqVO updateArticleReqVO);
54 | }
55 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/domain/mapper/ArticleContentMapper.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.domain.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 | import com.baomidou.mybatisplus.core.toolkit.Wrappers;
5 | import com.quanxiaoha.weblog.common.domain.dos.ArticleContentDO;
6 |
7 | /**
8 | * @author: 木萨·塔布提
9 | * @url: blog.arnasoft.site
10 | * @date: 2023-08-22 17:06
11 | * @description: 文章
12 | **/
13 | public interface ArticleContentMapper extends BaseMapper {
14 |
15 | /**
16 | * 根据文章 ID 删除记录
17 | * @param articleId
18 | * @return
19 | */
20 | default int deleteByArticleId(Long articleId) {
21 | return delete(Wrappers.lambdaQuery()
22 | .eq(ArticleContentDO::getArticleId, articleId));
23 | }
24 |
25 | /**
26 | * 根据文章 ID 查询
27 | * @param articleId
28 | * @return
29 | */
30 | default ArticleContentDO selectByArticleId(Long articleId) {
31 | return selectOne(Wrappers.lambdaQuery()
32 | .eq(ArticleContentDO::getArticleId, articleId));
33 | }
34 |
35 | /**
36 | * 通过文章 ID 更新
37 | * @param articleContentDO
38 | */
39 | default int updateByArticleId(ArticleContentDO articleContentDO) {
40 | return update(articleContentDO,
41 | Wrappers.lambdaQuery()
42 | .eq(ArticleContentDO::getArticleId, articleContentDO.getArticleId()));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/resources/application-prod.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8080
3 | spring:
4 | datasource:
5 | # 指定数据库驱动类
6 | driver-class-name: com.mysql.cj.jdbc.Driver
7 | # 数据库连接信息
8 | url: jdbc:mysql://172.17.0.1:3306/weblog?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
9 | username: root
10 | password: root
11 | hikari: # 数据库连接池使用 Hikari
12 | minimum-idle: 5 # 连接池中最小空闲连接数
13 | maximum-pool-size: 20 # 连接池中允许的最大连接数
14 | auto-commit: true # 是否自动提交事务
15 | idle-timeout: 30000 # 连接在连接池中闲置的最长时间,超过这个时间会被释放。
16 | pool-name: Weblog-HikariCP # 自定义连接池的名字
17 | max-lifetime: 1800000 # 连接在连接池中的最大存活时间,超过这个时间会被强制关闭。
18 | connection-timeout: 30000 # 连接的超时时间
19 | connection-test-query: SELECT 1 # 用于测试连接是否可用的SQL查询
20 |
21 | #=================================================================
22 | # log 日志
23 | #=================================================================
24 | logging:
25 | config: classpath:logback-weblog.xml
26 |
27 | #=================================================================
28 | # minio (上传图片需要,需配置成自己的地址)
29 | #=================================================================
30 | minio:
31 | endpoint: #endpoint
32 | accessKey: #accessKey
33 | secretKey: #secretKey
34 | bucketName: # bucketName
35 |
36 | #=================================================================
37 | # Lucene 全文检索
38 | #=================================================================
39 | lucene:
40 | indexDir: /app/weblog/lucene-index # lucene 索引存放的位置
--------------------------------------------------------------------------------
/weblog-vue3/src/axios.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import { getToken } from "@/composables/cookie"
3 | import { showMessage} from '@/composables/util'
4 | import { useUserStore } from '@/stores/user'
5 |
6 | // 创建 Axios 实例
7 | const instance = axios.create({
8 | baseURL: "/api", // 你的 API 基础 URL
9 | timeout: 7000, // 请求超时时间
10 | })
11 |
12 |
13 | // 添加请求拦截器
14 | instance.interceptors.request.use(function (config) {
15 | // 在发送请求之前做些什么
16 | const token = getToken()
17 | console.log('统一添加请求头中的 Token:' + token)
18 |
19 | // 当 token 不为空时
20 | if (token) {
21 | // 添加请求头, key 为 Authorization,value 值的前缀为 'Bearer '
22 | config.headers['Authorization'] = 'Bearer ' + token
23 | }
24 |
25 | return config;
26 | }, function (error) {
27 | // 对请求错误做些什么
28 | return Promise.reject(error)
29 | });
30 |
31 | // 添加响应拦截器
32 | instance.interceptors.response.use(function (response) {
33 | // 2xx 范围内的状态码都会触发该函数。
34 | // 对响应数据做点什么
35 | return response.data
36 | }, function (error) {
37 | // 超出 2xx 范围的状态码都会触发该函数。
38 | // 对响应错误做点什么
39 | let status = error.response.status
40 |
41 | // 状态码 401
42 | if (status == 401) {
43 | // 退出登录
44 | let userStore = useUserStore()
45 | userStore.logout()
46 | // 刷新页面
47 | location.reload()
48 | }
49 |
50 | // 若后台有错误提示就用提示文字,默认提示为 '请求失败'
51 | let errorMsg = error.response.data.message || '请求失败'
52 | // 弹错误提示
53 | showMessage(errorMsg, 'error')
54 |
55 | return Promise.reject(error)
56 | })
57 |
58 | // 暴露出去
59 | export default instance;
--------------------------------------------------------------------------------
/weblog-vue3/vite.config.js:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from 'node:url'
2 |
3 | import { defineConfig } from 'vite'
4 | import vue from '@vitejs/plugin-vue'
5 |
6 | import AutoImport from 'unplugin-auto-import/vite'
7 | import Components from 'unplugin-vue-components/vite'
8 | import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
9 | import ViteCompressionPlugin from 'vite-plugin-compression'
10 | import importToCDN from 'vite-plugin-cdn-import'
11 |
12 | // https://vitejs.dev/config/
13 | export default defineConfig({
14 | server: {
15 | proxy: {
16 | '/api': {
17 | target: 'http://47.98.119.250:8080',
18 | changeOrigin: true,
19 | rewrite: (path) => path.replace(/^\/api/, ''),
20 | },
21 | }
22 | },
23 | plugins: [
24 | vue(),
25 | AutoImport({
26 | resolvers: [ElementPlusResolver()],
27 | }),
28 | Components({
29 | resolvers: [ElementPlusResolver()],
30 | }),
31 | ViteCompressionPlugin({
32 | filter: /\.(js|css)$/i, // 只压缩 js 和 css 文件
33 | threshold: 1024, // 只压缩大于 1KB 的文件
34 | algorithm: 'gzip', // 使用 gzip 算法
35 | ext: '.gz', // 压缩文件的扩展名
36 | }),
37 | importToCDN({
38 | modules: [
39 | {
40 | name: 'echarts',
41 | var: 'echarts',
42 | path: 'https://cdn.bootcdn.net/ajax/libs/echarts/5.4.2/echarts.min.js',
43 | },
44 | ],
45 | }),
46 | ],
47 | resolve: {
48 | alias: {
49 | // 定义一个别名 '@',该别名对应于当前 JavaScript 模块文件所在目录下的 'src' 目录的绝对文件路径。
50 | '@': fileURLToPath(new URL('./src', import.meta.url))
51 | }
52 | }
53 | })
54 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/model/vo/blogsettings/UpdateBlogSettingsReqVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.model.vo.blogsettings;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.validation.constraints.Email;
10 | import javax.validation.constraints.NotBlank;
11 | import javax.validation.constraints.NotNull;
12 |
13 | /**
14 | * @author: 木萨·塔布提
15 | * @url: blog.arnasoft.site
16 | * @date: 2023-09-15 14:07
17 | * @description: 博客基础信息修改
18 | **/
19 | @Data
20 | @AllArgsConstructor
21 | @NoArgsConstructor
22 | @Builder
23 | @ApiModel(value = " 博客基础信息修改 VO")
24 | public class UpdateBlogSettingsReqVO {
25 |
26 | @NotBlank(message = "博客 LOGO 不能为空")
27 | private String logo;
28 |
29 | @NotBlank(message = "博客名称不能为空")
30 | private String name;
31 |
32 | @NotBlank(message = "博客作者不能为空")
33 | private String author;
34 |
35 | @NotBlank(message = "博客介绍语不能为空")
36 | private String introduction;
37 |
38 | @NotBlank(message = "博客头像不能为空")
39 | private String avatar;
40 |
41 | private String githubHomepage;
42 |
43 | private String csdnHomepage;
44 |
45 | private String giteeHomepage;
46 |
47 | private String zhihuHomepage;
48 |
49 | @Email(message = "邮箱格式不正确")
50 | private String mail;
51 |
52 | @NotNull(message = "请设置评论敏感词过滤是否开启")
53 | private Boolean isCommentSensiWordOpen;
54 |
55 | @NotNull(message = "请设置评论审核是否开启")
56 | private Boolean isCommentExamineOpen;
57 | }
58 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/model/vo/article/FindArticleDetailRspVO.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.model.vo.article;
2 |
3 | import com.quanxiaoha.weblog.web.model.vo.tag.FindTagListRspVO;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.time.LocalDateTime;
10 | import java.util.List;
11 |
12 | /**
13 | * @author: 木萨·塔布提
14 | * @url: blog.arnasoft.site
15 | * @date: 2023-09-15 14:07
16 | * @description: 文章详情
17 | **/
18 | @Data
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @Builder
22 | public class FindArticleDetailRspVO {
23 | /**
24 | * 文章标题
25 | */
26 | private String title;
27 | /**
28 | * 文章正文(HTML)
29 | */
30 | private String content;
31 | /**
32 | * 发布时间
33 | */
34 | private LocalDateTime createTime;
35 | /**
36 | * 分类 ID
37 | */
38 | private Long categoryId;
39 | /**
40 | * 分类名称
41 | */
42 | private String categoryName;
43 | /**
44 | * 阅读量
45 | */
46 | private Long readNum;
47 | /**
48 | * 标签集合
49 | */
50 | private List tags;
51 | /**
52 | * 上一篇文章
53 | */
54 | private FindPreNextArticleRspVO preArticle;
55 | /**
56 | * 下一篇文章
57 | */
58 | private FindPreNextArticleRspVO nextArticle;
59 | /**
60 | * 总字数
61 | */
62 | private Integer totalWords;
63 | /**
64 | * 阅读时长
65 | */
66 | private String readTime;
67 |
68 | /**
69 | * 最后更新时间
70 | */
71 | private LocalDateTime updateTime;
72 | }
73 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-admin/src/main/java/com/quanxiaoha/weblog/admin/schedule/InitPVRecordScheduledTask.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.admin.schedule;
2 |
3 | import com.quanxiaoha.weblog.common.domain.dos.StatisticsArticlePVDO;
4 | import com.quanxiaoha.weblog.common.domain.mapper.StatisticsArticlePVMapper;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.scheduling.annotation.Scheduled;
8 | import org.springframework.stereotype.Component;
9 |
10 | import java.time.LocalDate;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | * @author: 木萨·塔布提
15 | * @url: blog.arnasoft.site
16 | * @date: 2023/11/12 12:02
17 | * @description: 初始化 PV 访问量定时任务
18 | **/
19 | @Component
20 | @Slf4j
21 | public class InitPVRecordScheduledTask {
22 |
23 | @Autowired
24 | private StatisticsArticlePVMapper articlePVMapper;
25 |
26 | @Scheduled(cron = "0 0 23 * * ?") // 每天晚间 23 点执行
27 | // @Scheduled(cron = "0 * * * * ?") // 每一分钟执行一次
28 | public void execute() {
29 | // 定时任务执行的业务逻辑
30 | log.info("==> 开始执行初始化明日 PV 访问量记录定时任务");
31 |
32 | // 当日日期
33 | LocalDate currDate = LocalDate.now();
34 |
35 | // 明日
36 | LocalDate tomorrowDate = currDate.plusDays(1);
37 |
38 | // 组装插入的记录
39 | StatisticsArticlePVDO articlePVDO = StatisticsArticlePVDO.builder()
40 | .pvDate(tomorrowDate) // 明日的文章 pv 访问量
41 | .pvCount(0L) // 默认阅读量为 0
42 | .createTime(LocalDateTime.now())
43 | .updateTime(LocalDateTime.now())
44 | .build();
45 |
46 | articlePVMapper.insert(articlePVDO);
47 | log.info("==> 结束执行初始化明日 PV 访问量记录定时任务");
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/weblog-vue3/src/components/FormDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-jwt/src/main/java/com/quanxiaoha/weblog/jwt/handler/RestAuthenticationEntryPoint.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.jwt.handler;
2 |
3 | import com.quanxiaoha.weblog.common.enums.ResponseCodeEnum;
4 | import com.quanxiaoha.weblog.common.utils.Response;
5 | import com.quanxiaoha.weblog.jwt.utils.ResultUtil;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.http.HttpStatus;
8 | import org.springframework.security.authentication.BadCredentialsException;
9 | import org.springframework.security.authentication.InsufficientAuthenticationException;
10 | import org.springframework.security.core.AuthenticationException;
11 | import org.springframework.security.web.AuthenticationEntryPoint;
12 | import org.springframework.stereotype.Component;
13 |
14 | import javax.servlet.ServletException;
15 | import javax.servlet.http.HttpServletRequest;
16 | import javax.servlet.http.HttpServletResponse;
17 | import java.io.IOException;
18 |
19 | /**
20 | * @author: 木萨·塔布提
21 | * @url: blog.arnasoft.site
22 | * @date: 2023-08-27 17:27
23 | * @description: 用户未登录访问受保护的资源
24 | **/
25 | @Slf4j
26 | @Component
27 | public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
28 |
29 | @Override
30 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
31 | log.warn("用户未登录访问受保护的资源: ", authException);
32 | if (authException instanceof InsufficientAuthenticationException) {
33 | ResultUtil.fail(response, HttpStatus.UNAUTHORIZED.value(), Response.fail(ResponseCodeEnum.UNAUTHORIZED));
34 | }
35 |
36 | ResultUtil.fail(response, HttpStatus.UNAUTHORIZED.value(), Response.fail(authException.getMessage()));
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## 一、项目介绍
4 |
5 | `Weblog` 项目就是完成一个完整的前后端分离的博客项目,包含服务端接口API,管理后台以及部署上线流程。这个项目主要介绍使用 `SpringBoot2.6 ` 开发一套完整的 RESTful 风格服务端接口 API 和使用 `Vue2` 开发管理后台。(本项目只给小伙伴学习使用的,不能做任何开源商业使用,请尊重作者-🔜[犬小哈](https://www.quanxiaoha.com/))
6 |
7 | ### 1.1 项目展示
8 |
9 | - 前端线上展示地址:https://blog.arnasoft.site/#/
10 |
11 | - 首页
12 | 
13 |
14 | - 详情页
15 | 
16 |
17 | - 移动端
18 |  
19 |
20 |
21 | ## 二、使用项目
22 |
23 | ### 2.1 克隆项目
24 |
25 | ```
26 | # 克隆项目代码
27 |
28 | git clone git@github.com:programmer-xiaosa/weblog.git
29 | ```
30 |
31 | ### 2.2 项目部署
32 |
33 | 小伙伴们可以使用传统方式部署也可以使用 `docker jenkins` 自动化部署,推荐使用 `docker`
34 |
35 | - [Docker 教程](https://www.quanxiaoha.com/docker/docker-tutorial.html)
36 | - [Linux常用命令](https://www.quanxiaoha.com/linux-command/linux-shutdown.html)
37 |
38 | ## 三、FAQ
39 |
40 | 1. 没有yarn环境,npm 可以吗?
41 |
42 | > 答:可以的,建议使用 yarn,yarn 比 npm 速度快,主要是安装版本统一。
43 |
44 | 2. npm 下载依赖包失败,卡住?
45 |
46 | > 答:本项目采用的事vue3,建议使用 node版本是 v18.12.1.,小伙伴们可以使用 `n` 或者 `nvm` 来切换电脑上的node版本,这样可以使用多个版本的系统,不会冲突。
47 |
48 | 3. ... 更多问题请到 [Issues](https://github.com/programmer-xiaosa/weblog/issues)查阅,或者有问题请到 [Issues 提问](https://github.com/programmer-xiaosa/weblog/issues/new)。
49 | 4. 本项目学习[犬小哈老师](https://www.quanxiaoha.com/)的课程后开发的博客项目,代码基本跟源码一致,只做部分修改和优化,,修改和优化可以到生产环境看下,[点这里](https://blog.arnasoft.site/#/)。小伙伴们可以参考学习,希望大家多多支持犬小哈老师的课程,我个人认为犬小哈老师的图文教程是特别棒的,肯定会有收获
50 |
51 | ## License
52 |
53 | [MIT](https://github.com/programmer-xiaosa/Weblog/blob/main/LICENSE), by [programmer-xiaosa](https://github.com/programmer-xiaosa/Weblog/commits?author=programmer-xiaosa)
54 |
55 | 喜欢或对你有帮助的话,请你点一个星星 star 鼓励我,或者您有更好的建议和意见,请提出来告知我,可以留言 [Issues](https://github.com/programmer-xiaosa/weblog/issues/new)。希望能够帮助到你学习!Thanks
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/enums/ResponseCodeEnum.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.enums;
2 |
3 | import com.quanxiaoha.weblog.common.exception.BaseExceptionInterface;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 |
7 | /**
8 | * @author: 木萨·塔布提
9 | * @url: blog.arnasoft.site
10 | * @date: 2023-08-15 10:33
11 | * @description: 响应异常码
12 | **/
13 | @Getter
14 | @AllArgsConstructor
15 | public enum ResponseCodeEnum implements BaseExceptionInterface {
16 |
17 | // ----------- 通用异常状态码 -----------
18 | SYSTEM_ERROR("10000", "出错啦,后台小哥正在努力修复中..."),
19 | PARAM_NOT_VALID("10001", "参数错误"),
20 |
21 |
22 | // ----------- 业务异常状态码 -----------
23 | LOGIN_FAIL("20000", "登录失败"),
24 | USERNAME_OR_PWD_ERROR("20001", "用户名或密码错误"),
25 | UNAUTHORIZED("20002", "无访问权限,请先登录!"),
26 | USERNAME_NOT_FOUND("20003", "该用户不存在"),
27 | FORBIDDEN("20004", "演示账号仅支持查询操作!"),
28 | CATEGORY_NAME_IS_EXISTED("20005", "该分类已存在,请勿重复添加!"),
29 | TAG_CANT_DUPLICATE("20006", "请勿添加表中已存在的标签!"),
30 | TAG_NOT_EXISTED("20007", "该标签不存在!"),
31 | FILE_UPLOAD_FAILED("20008", "文件上传失败!"),
32 | CATEGORY_NOT_EXISTED("20009", "提交的分类不存在!"),
33 | ARTICLE_NOT_FOUND("20010", "该文章不存在!"),
34 | CATEGORY_CAN_NOT_DELETE("20011", "该分类下包含文章,请先删除对应文章,才能删除!"),
35 | TAG_CAN_NOT_DELETE("20012", "该标签下包含文章,请先删除对应文章,才能删除!"),
36 | WIKI_NOT_FOUND("20013", "该知识库不存在"),
37 | NOT_QQ_NUMBER("20014", "QQ 号格式不正确"),
38 | COMMENT_CONTAIN_SENSITIVE_WORD("20015", "评论内容中包含敏感词,请重新编辑后再提交"),
39 | COMMENT_WAIT_EXAMINE("20016", "评论已提交, 等待博主审核通过"),
40 | COMMENT_NOT_FOUND("20017", "该评论不存在"),
41 | COMMENT_STATUS_NOT_WAIT_EXAMINE("20018", "该评论未处于待审核状态"),
42 | ;
43 |
44 | // 异常码
45 | private String errorCode;
46 | // 错误信息
47 | private String errorMessage;
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-web/src/main/java/com/quanxiaoha/weblog/web/config/ToolGoodConfig.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.web.config;
2 |
3 | import com.google.common.collect.Lists;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.apache.commons.lang3.StringUtils;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.core.io.ResourceLoader;
9 | import toolgood.words.IllegalWordsSearch;
10 |
11 | import java.io.BufferedReader;
12 | import java.io.IOException;
13 | import java.io.InputStreamReader;
14 | import java.util.List;
15 |
16 | /**
17 | * @Author: 木萨·塔布提
18 | * @Date: 2024/4/3 21:06
19 | * @Version: v1.0.0
20 | * @Description: TODO
21 | **/
22 | @Configuration
23 | @Slf4j
24 | public class ToolGoodConfig {
25 |
26 | @Bean
27 | public IllegalWordsSearch illegalWordsSearch(ResourceLoader resourceLoader) throws IOException {
28 | log.info("==> 开始初初始化敏感词工具类 ...");
29 | IllegalWordsSearch illegalWordsSearch = new IllegalWordsSearch();
30 |
31 | log.info("==> 加载敏感词 txt 文件 ...");
32 | // 读取 /resource 目录下的敏感词 txt 文件
33 | List sensitiveWords = Lists.newArrayList();
34 | try (BufferedReader reader = new BufferedReader(
35 | new InputStreamReader(resourceLoader.getResource("classpath:word/sensi_words.txt").getInputStream()))) {
36 | String line;
37 | while ((line = reader.readLine()) != null) {
38 | if (StringUtils.isNotBlank(line.trim())) {
39 | sensitiveWords.add(line.trim());
40 | }
41 | }
42 | }
43 |
44 | // 设置敏感词
45 | illegalWordsSearch.SetKeywords(sensitiveWords);
46 | log.info("==> 初始化敏感词工具类成功 ...");
47 | return illegalWordsSearch;
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/weblog-springboot/weblog-module-common/src/main/java/com/quanxiaoha/weblog/common/mail/MailHelper.java:
--------------------------------------------------------------------------------
1 | package com.quanxiaoha.weblog.common.mail;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.boot.autoconfigure.mail.MailProperties;
6 | import org.springframework.mail.javamail.JavaMailSender;
7 | import org.springframework.mail.javamail.MimeMessageHelper;
8 | import org.springframework.stereotype.Component;
9 |
10 | import javax.mail.internet.MimeMessage;
11 |
12 | /**
13 | * @Author: 木萨·塔布提
14 | * @Date: 2024/4/3 21:40
15 | * @Version: v1.0.0
16 | * @Description: TODO
17 | **/
18 | @Component
19 | @Slf4j
20 | public class MailHelper {
21 |
22 | @Autowired
23 | private MailProperties mailProperties;
24 | @Autowired
25 | private JavaMailSender javaMailSender;
26 |
27 | public boolean sendHtml(String to, String title, String html) {
28 | log.info("==> 开始发送邮件 ...");
29 | MimeMessage mimeMessage = javaMailSender.createMimeMessage();
30 |
31 | MimeMessageHelper mimeMessageHelper = null;
32 | try {
33 | mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
34 | // 邮件发送来源
35 | mimeMessageHelper.setFrom(mailProperties.getUsername());
36 | // 邮件发送目标
37 | mimeMessageHelper.setTo(to);
38 | // 设置标题
39 | mimeMessageHelper.setSubject(title);
40 | // 设置内容,内容是否为 html 格式,值为 true
41 | mimeMessageHelper.setText(html, true);
42 |
43 | javaMailSender.send(mimeMessage);
44 | log.info("==> 邮件发送成功, to: {}, title: {}, content: {}", to, title, html);
45 | } catch (Exception e) {
46 | log.error("==> 发送邮件异常: ", e);
47 | return false;
48 | }
49 |
50 | return true;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------