From 1ba0e6c40bc3007e5a06610d51ace94d80827557 Mon Sep 17 00:00:00 2001 From: Cxx0822 <1556464090@qq.com> Date: Mon, 27 Oct 2025 15:03:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0=E5=8D=9A=E5=AE=A2?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/blog.ts | 6 + src/apis/stats.ts | 54 +++++++ src/icons/svg/admin/blogUnapproved.svg | 1 + src/store/blog.ts | 21 ++- src/styles/admin.layout.module.scss | 2 +- src/types/blog.ts | 8 ++ src/views/blog/unapproved.vue | 96 +++++++++++++ src/views/dashboard/index.vue | 191 ++++++++++++++++++++++++- src/views/meta.ts | 4 + 9 files changed, 375 insertions(+), 8 deletions(-) create mode 100644 src/apis/stats.ts create mode 100644 src/icons/svg/admin/blogUnapproved.svg create mode 100644 src/views/blog/unapproved.vue diff --git a/src/apis/blog.ts b/src/apis/blog.ts index ad39101..f1cccd6 100644 --- a/src/apis/blog.ts +++ b/src/apis/blog.ts @@ -10,6 +10,12 @@ export const queryBlogApi = (currentPage: number, pageSize: number): Promise => + cloudService({ + url: '/blog-api/blog/unapproved', + method: 'get' + }) + export const queryBlogByIdApi = (id: number): Promise => cloudService({ url: `/blog-api/blog/${id}/content`, diff --git a/src/apis/stats.ts b/src/apis/stats.ts new file mode 100644 index 0000000..a2f6e26 --- /dev/null +++ b/src/apis/stats.ts @@ -0,0 +1,54 @@ +import { cloudService } from './index' + +import { IStatsChart } from 'vue3-common/types' +import { IBlogOverview } from '@/types/blog' + +export const queryOverviewStatsApi = (): Promise => + cloudService({ + url: '/blog-api/stats/overview', + method: 'get' + }) + + +export const queryCategoryStatsApi = (): Promise => + cloudService({ + url: '/blog-api/stats/category', + method: 'get' + }) + + +export const queryApprovedMonthlyStatsApi = (year: number): Promise => + cloudService({ + url: '/blog-api/stats/approved/monthly', + method: 'get', + params: { year } + }) + + +export const queryVisitMonthlyStatsApi = (year: number): Promise => + cloudService({ + url: '/blog-api/stats/visit/monthly', + method: 'get', + params: { year } + }) + + +export const queryVisitRankStatsApi = (): Promise => + cloudService({ + url: '/blog-api/stats/visit/rank', + method: 'get' + }) + + +export const queryReadRankStatsApi = (): Promise => + cloudService({ + url: '/blog-api/stats/read/rank', + method: 'get' + }) + + +export const queryCommentRankStatsApi = (): Promise => + cloudService({ + url: '/blog-api/stats/comment/rank', + method: 'get' + }) diff --git a/src/icons/svg/admin/blogUnapproved.svg b/src/icons/svg/admin/blogUnapproved.svg new file mode 100644 index 0000000..e74be3e --- /dev/null +++ b/src/icons/svg/admin/blogUnapproved.svg @@ -0,0 +1 @@ + diff --git a/src/store/blog.ts b/src/store/blog.ts index 4cac976..5e5d369 100644 --- a/src/store/blog.ts +++ b/src/store/blog.ts @@ -4,9 +4,17 @@ import { IBlogLatest, IBlogNestedComment, IBlogStats, INewBlog, IQueryBlog } from '@/types/blog' import { - addBlogApi, addBlogCommentApi, deleteBlogApi, - queryBlogApi, queryBlogByIdApi, - queryBlogCategoryApi, queryBlogCommentApi, queryBlogStatsApi, queryLatestBlogApi, updateBlogApi + addBlogApi, + addBlogCommentApi, + deleteBlogApi, + queryBlogApi, + queryBlogByIdApi, + queryBlogCategoryApi, + queryBlogCommentApi, + queryBlogStatsApi, + queryLatestBlogApi, + queryUnapprovedBlogApi, + updateBlogApi } from '@/apis/blog.ts' import { IHandleApi } from 'vue3-common/types' import { ElMessage } from 'element-plus' @@ -16,6 +24,7 @@ import { flattenToTwoLevel } from '@/utils/blog/blogUtil.ts' export const useBlogStore = defineStore('blog', { state: () => ({ blogList: [] as IBlog[], + unapprovedBlogList: [] as IBlog[], blogCommentList: [] as IBlogComment[], blogNestedCommentList: [] as IBlogNestedComment[], currentBlogComment: { @@ -66,7 +75,8 @@ export const useBlogStore = defineStore('blog', { totalSize: 1 }, isScrollEnd: false, - progressValue: '0%' + progressValue: '0%', + isRefresh: false }), actions: { async queryBlogList() { @@ -75,6 +85,9 @@ export const useBlogStore = defineStore('blog', { this.blogList = result.records this.pageInfo.totalSize = result.total }, + async queryUnapprovedBlogList() { + this.unapprovedBlogList = await queryUnapprovedBlogApi() + }, async queryBlogById(id: number) { this.currentBlog = await queryBlogByIdApi(id) await this.queryBlogComment(this.currentBlogId) diff --git a/src/styles/admin.layout.module.scss b/src/styles/admin.layout.module.scss index 60f48dc..1747a4e 100644 --- a/src/styles/admin.layout.module.scss +++ b/src/styles/admin.layout.module.scss @@ -196,7 +196,7 @@ $transition-time: 0.28s; background-color: #FFFFFF; border: 1px solid #FFFFFF; border-radius: 10px; - box-shadow: 5px 5px 5px #CFCFCF; + box-shadow: 1px 1px 2px #CFCFCF; } } diff --git a/src/types/blog.ts b/src/types/blog.ts index 56784d4..f47ca48 100644 --- a/src/types/blog.ts +++ b/src/types/blog.ts @@ -84,3 +84,11 @@ export interface IBlogNestedComment { comment: IBlogComment; replies: IBlogComment[]; } + +export interface IBlogOverview { + blogCount: number; + categoryCount: number; + wordCount: number; + greatCount: number; + visitCount: number; +} diff --git a/src/views/blog/unapproved.vue b/src/views/blog/unapproved.vue new file mode 100644 index 0000000..40967dc --- /dev/null +++ b/src/views/blog/unapproved.vue @@ -0,0 +1,96 @@ + + + diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index 7f2521e..0c442dc 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -1,13 +1,198 @@ - diff --git a/src/views/meta.ts b/src/views/meta.ts index 271874d..3e2a38a 100644 --- a/src/views/meta.ts +++ b/src/views/meta.ts @@ -25,6 +25,10 @@ export const metaList: IRouteMetaConfig = { title: '类别管理', icon: 'admin-blogCategory' }, + '/blog/unapproved': { + title: '草稿箱', + icon: 'admin-blogUnapproved' + }, '/blog/detail/:id': { title: '', icon: '',