Compare commits

..

3 Commits

Author SHA1 Message Date
cbe5851a00 feat:增加查询类别分页博客功能 2025-11-04 15:50:22 +08:00
38db5cbc07 feat:更新card-item样式 2025-10-29 16:11:14 +08:00
0053d6c3e0 feat:增加日志管理模块 2025-10-28 16:21:00 +08:00
13 changed files with 170 additions and 103 deletions

View File

@@ -15,11 +15,12 @@ export const uploadBlogImageApi = (md5: string, form: FormData): Promise<string>
data: form
})
export const queryBlogApi = (currentPage: number, pageSize: number): Promise<IPageRecord<IBlog>> =>
export const queryBlogApi = (currentPage: number, pageSize: number,
category: string): Promise<IPageRecord<IBlog>> =>
cloudService({
url: '/blog-api/blog/all/page',
url: '/blog-api/blog/condition/page',
method: 'get',
params: { currentPage, pageSize }
params: { currentPage, pageSize, category }
})
export const queryUnapprovedBlogApi = (): Promise<IBlog[]> =>
@@ -92,3 +93,11 @@ export const queryBlogVisitApi = (currentPage: number,
method: 'get',
params: { currentPage, pageSize }
})
export const queryBlogAlterApi = (name: string): Promise<any> =>
cloudService({
url: '/alter-api/log-alter/name',
method: 'get',
params: { name }
})

View File

@@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1728286912539" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9408" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M960 512c0-59.5-40.9-109.7-96.1-124v68.6c-9.4-5.5-20.4-8.6-32-8.6-35.3 0-64.1 28.7-64.1 64s28.7 64 64.1 64c11.7 0 22.6-3.1 32-8.6V636c-10.2 2.6-21 4.1-32 4.1-70.7 0-128.1-57.4-128.1-128s57.5-128 128.1-128c11.1 0 21.8 1.4 32 4V192c0-52.9-41.8-96-93.1-96H221.2c-51.3 0-93.1 43.1-93.1 96v159.5h128.1v64H128.1V352H64v64h64.1v191.5h128.1v64H127.1V608H64v64h64.1v160c0 52.9 41.8 96 93.1 96h549.6c51.3 0 93.1-43.1 93.1-96V635.9C919.1 621.7 960 571.5 960 512zM320.3 288h384.4v64H320.3v-64z m0 192h318.4v64H320.3v-64z m384.4 256H320.3v-64h384.4v64z m164.4-276z m4.9 3.9l-0.1-0.1s0.1 0 0.1 0.1zM869.1 564z m4.9-3.9l-0.1 0.1s0.1 0 0.1-0.1z m21.9-45.2c0-1 0.1-1.9 0.1-2.9s0-2-0.1-2.9c0 1 0.1 1.9 0.1 2.9s-0.1 2-0.1 2.9z m-17.7 41.2l0.3-0.3-0.3 0.3z m1.6-1.7l0.1-0.1-0.1 0.1z m2.3-2.8c0.2-0.2 0.3-0.4 0.5-0.6-0.2 0.2-0.3 0.4-0.5 0.6z m1.5-1.9c0.2-0.2 0.4-0.5 0.5-0.7-0.2 0.2-0.3 0.4-0.5 0.7z m2-2.9c0.2-0.3 0.4-0.6 0.6-1-0.2 0.4-0.4 0.7-0.6 1z m1.3-2.2c0.3-0.4 0.5-0.9 0.8-1.4-0.2 0.5-0.5 1-0.8 1.4z m1.7-2.9c0.2-0.5 0.5-0.9 0.7-1.4-0.2 0.5-0.5 0.9-0.7 1.4z m1.2-2.5c0.3-0.6 0.6-1.3 0.9-1.9-0.3 0.7-0.6 1.3-0.9 1.9z m1.3-2.9c0.2-0.6 0.5-1.2 0.7-1.8-0.2 0.6-0.4 1.2-0.7 1.8z m1.1-2.8c0.3-0.8 0.5-1.6 0.8-2.4-0.3 0.9-0.5 1.7-0.8 2.4z m1-2.9c0.2-0.7 0.4-1.5 0.6-2.2-0.2 0.8-0.4 1.5-0.6 2.2z m0.8-3c0.2-0.9 0.4-1.8 0.6-2.6-0.2 0.8-0.4 1.7-0.6 2.6z m0.7-2.9c0.2-0.8 0.3-1.7 0.5-2.5-0.2 0.8-0.4 1.6-0.5 2.5z m0.5-3.3c0.1-0.9 0.3-1.9 0.4-2.8-0.1 0.9-0.2 1.8-0.4 2.8z m0.4-3c0.1-0.9 0.2-1.9 0.2-2.8 0 1-0.1 1.9-0.2 2.8z m-17.4-50.5l0.3 0.3-0.3-0.3z m1.6 1.7l0.1 0.1-0.1-0.1z m2.3 2.8c0.2 0.2 0.3 0.4 0.5 0.6-0.2-0.2-0.3-0.4-0.5-0.6z m1.5 1.9c0.2 0.2 0.4 0.5 0.5 0.7-0.2-0.2-0.3-0.4-0.5-0.7z m2 2.9c0.2 0.3 0.4 0.7 0.6 1-0.2-0.4-0.4-0.7-0.6-1z m1.3 2.2c0.3 0.4 0.5 0.9 0.8 1.4-0.2-0.5-0.5-1-0.8-1.4z m1.7 2.9c0.2 0.5 0.5 0.9 0.7 1.4-0.2-0.5-0.5-0.9-0.7-1.4z m1.2 2.5c0.3 0.6 0.6 1.3 0.9 1.9-0.3-0.7-0.6-1.3-0.9-1.9z m1.3 2.9c0.2 0.6 0.5 1.2 0.7 1.8-0.2-0.6-0.4-1.2-0.7-1.8z m1.1 2.8c0.3 0.8 0.5 1.6 0.8 2.4-0.3-0.9-0.5-1.7-0.8-2.4z m1 2.9c0.2 0.7 0.4 1.5 0.6 2.2-0.2-0.8-0.4-1.5-0.6-2.2z m0.8 3c0.2 0.9 0.4 1.8 0.6 2.6-0.2-0.8-0.4-1.7-0.6-2.6z m0.7 2.9c0.2 0.8 0.3 1.7 0.5 2.5-0.2-0.8-0.4-1.6-0.5-2.5z m0.5 3.3c0.1 0.9 0.3 1.9 0.4 2.8-0.1-0.9-0.2-1.8-0.4-2.8z m0.4 3c0.1 0.9 0.2 1.9 0.2 2.8 0-1-0.1-1.9-0.2-2.8z" fill="#47444F" p-id="9409"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1728286912539" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9408" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M960 512c0-59.5-40.9-109.7-96.1-124v68.6c-9.4-5.5-20.4-8.6-32-8.6-35.3 0-64.1 28.7-64.1 64s28.7 64 64.1 64c11.7 0 22.6-3.1 32-8.6V636c-10.2 2.6-21 4.1-32 4.1-70.7 0-128.1-57.4-128.1-128s57.5-128 128.1-128c11.1 0 21.8 1.4 32 4V192c0-52.9-41.8-96-93.1-96H221.2c-51.3 0-93.1 43.1-93.1 96v159.5h128.1v64H128.1V352H64v64h64.1v191.5h128.1v64H127.1V608H64v64h64.1v160c0 52.9 41.8 96 93.1 96h549.6c51.3 0 93.1-43.1 93.1-96V635.9C919.1 621.7 960 571.5 960 512zM320.3 288h384.4v64H320.3v-64z m0 192h318.4v64H320.3v-64z m384.4 256H320.3v-64h384.4v64z m164.4-276z m4.9 3.9l-0.1-0.1s0.1 0 0.1 0.1zM869.1 564z m4.9-3.9l-0.1 0.1s0.1 0 0.1-0.1z m21.9-45.2c0-1 0.1-1.9 0.1-2.9s0-2-0.1-2.9c0 1 0.1 1.9 0.1 2.9s-0.1 2-0.1 2.9z m-17.7 41.2l0.3-0.3-0.3 0.3z m1.6-1.7l0.1-0.1-0.1 0.1z m2.3-2.8c0.2-0.2 0.3-0.4 0.5-0.6-0.2 0.2-0.3 0.4-0.5 0.6z m1.5-1.9c0.2-0.2 0.4-0.5 0.5-0.7-0.2 0.2-0.3 0.4-0.5 0.7z m2-2.9c0.2-0.3 0.4-0.6 0.6-1-0.2 0.4-0.4 0.7-0.6 1z m1.3-2.2c0.3-0.4 0.5-0.9 0.8-1.4-0.2 0.5-0.5 1-0.8 1.4z m1.7-2.9c0.2-0.5 0.5-0.9 0.7-1.4-0.2 0.5-0.5 0.9-0.7 1.4z m1.2-2.5c0.3-0.6 0.6-1.3 0.9-1.9-0.3 0.7-0.6 1.3-0.9 1.9z m1.3-2.9c0.2-0.6 0.5-1.2 0.7-1.8-0.2 0.6-0.4 1.2-0.7 1.8z m1.1-2.8c0.3-0.8 0.5-1.6 0.8-2.4-0.3 0.9-0.5 1.7-0.8 2.4z m1-2.9c0.2-0.7 0.4-1.5 0.6-2.2-0.2 0.8-0.4 1.5-0.6 2.2z m0.8-3c0.2-0.9 0.4-1.8 0.6-2.6-0.2 0.8-0.4 1.7-0.6 2.6z m0.7-2.9c0.2-0.8 0.3-1.7 0.5-2.5-0.2 0.8-0.4 1.6-0.5 2.5z m0.5-3.3c0.1-0.9 0.3-1.9 0.4-2.8-0.1 0.9-0.2 1.8-0.4 2.8z m0.4-3c0.1-0.9 0.2-1.9 0.2-2.8 0 1-0.1 1.9-0.2 2.8z m-17.4-50.5l0.3 0.3-0.3-0.3z m1.6 1.7l0.1 0.1-0.1-0.1z m2.3 2.8c0.2 0.2 0.3 0.4 0.5 0.6-0.2-0.2-0.3-0.4-0.5-0.6z m1.5 1.9c0.2 0.2 0.4 0.5 0.5 0.7-0.2-0.2-0.3-0.4-0.5-0.7z m2 2.9c0.2 0.3 0.4 0.7 0.6 1-0.2-0.4-0.4-0.7-0.6-1z m1.3 2.2c0.3 0.4 0.5 0.9 0.8 1.4-0.2-0.5-0.5-1-0.8-1.4z m1.7 2.9c0.2 0.5 0.5 0.9 0.7 1.4-0.2-0.5-0.5-0.9-0.7-1.4z m1.2 2.5c0.3 0.6 0.6 1.3 0.9 1.9-0.3-0.7-0.6-1.3-0.9-1.9z m1.3 2.9c0.2 0.6 0.5 1.2 0.7 1.8-0.2-0.6-0.4-1.2-0.7-1.8z m1.1 2.8c0.3 0.8 0.5 1.6 0.8 2.4-0.3-0.9-0.5-1.7-0.8-2.4z m1 2.9c0.2 0.7 0.4 1.5 0.6 2.2-0.2-0.8-0.4-1.5-0.6-2.2z m0.8 3c0.2 0.9 0.4 1.8 0.6 2.6-0.2-0.8-0.4-1.7-0.6-2.6z m0.7 2.9c0.2 0.8 0.3 1.7 0.5 2.5-0.2-0.8-0.4-1.6-0.5-2.5z m0.5 3.3c0.1 0.9 0.3 1.9 0.4 2.8-0.1-0.9-0.2-1.8-0.4-2.8z m0.4 3c0.1 0.9 0.2 1.9 0.2 2.8 0-1-0.1-1.9-0.2-2.8z" fill="" p-id="9409"></path></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1761638922713" class="icon" viewBox="0 0 1080 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7439" xmlns:xlink="http://www.w3.org/1999/xlink" width="210.9375" height="200"><path d="M941.34455136 32H93.25188261A82.58521594 82.58521594 0 0 0 10.66666667 114.58521594v603.15623906a82.58521594 82.58521594 0 0 0 82.58521594 82.58521594H941.34455136a82.58521594 82.58521594 0 0 0 82.58521687-82.58521594V114.58521594A82.58521594 82.58521594 0 0 0 941.34455136 32zM533.05004417 684.347135c-139.89814781 0-253.31577562-111.66120937-253.31577562-249.47850469s113.41762687-249.47850469 253.31577562-249.47850562 253.31577562 111.69477094 253.31577562 249.47850562-113.40643969 249.47850469-253.31577562 249.47850469z" p-id="7440"></path><path d="M457.72543573 283.66004375a75.83922844 75.83922844 0 1 1-75.82804125 75.8392275 75.82804031 75.82804031 0 0 1 75.82804125-75.8392275zM157.24367886 913.68836187h712.63590937c18.88429219 0 34.19981156 13.72691156 34.19981063 30.65341219v17.00481282c0 16.92650156-15.31551937 30.65341312-34.19981063 30.65341312h-712.63590937c-18.88429219 0-34.19981156-13.72691156-34.19981156-30.65341313v-17.02718718c0-16.92650156 15.30433125-30.63103781 34.19981156-30.63103782z" p-id="7441"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1761548520883" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1595" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M729.301333 42.666667c79.552 0 142.72 69.504 145.28 154.666666L874.666667 202.666667V576h32a74.666667 74.666667 0 0 1 74.56 70.570667L981.333333 650.666667v256a74.666667 74.666667 0 0 1-74.666666 74.666666h-789.333334A74.666667 74.666667 0 0 1 42.666667 906.666667v-256A74.666667 74.666667 0 0 1 117.333333 576H149.333333V202.666667c0-85.76 61.568-157.034667 140.416-159.914667L294.698667 42.666667h434.602666zM216.832 640H117.333333a10.666667 10.666667 0 0 0-10.666666 10.666667v256a10.666667 10.666667 0 0 0 10.666666 10.666666h789.333334a10.666667 10.666667 0 0 0 10.666666-10.666666v-256a10.666667 10.666667 0 0 0-10.666666-10.666667h-78.421334a10.666667 10.666667 0 0 0-6.912 2.538667l-126.890666 107.733333a74.666667 74.666667 0 0 1-48.32 17.728H381.226667a74.666667 74.666667 0 0 1-52.522667-21.589333l-104.405333-103.317334a10.666667 10.666667 0 0 0-7.488-3.093333zM729.301333 106.666667H294.698667c-42.666667 0-79.104 39.658667-81.28 91.136L213.333333 202.666667V576h3.498667a74.666667 74.666667 0 0 1 49.194667 18.517333l3.328 3.072 104.384 103.317334a10.666667 10.666667 0 0 0 7.509333 3.093333h264.874667a10.666667 10.666667 0 0 0 6.890666-2.538667l126.912-107.733333a74.666667 74.666667 0 0 1 30.72-15.637333L810.666667 202.666667c0-52.202667-35.114667-93.44-77.397334-95.893334L729.301333 106.666667zM629.333333 448a32 32 0 0 1 0 64h-234.666666a32 32 0 0 1 0-64h234.666666z m64-192a32 32 0 0 1 0 64h-362.666666a32 32 0 0 1 0-64h362.666666z" fill="" p-id="1596"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1761638996401" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9280" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M960 1024H69.487A69.487 69.487 0 0 1 0 954.513V577.5a5.487 5.487 0 0 1 0.738-2.75l126.525-219.175a5.487 5.487 0 0 0 0.737-2.75V69.488A69.487 69.487 0 0 1 197.5 0h504.225a5.487 5.487 0 0 1 3.888 1.613l188.75 188.75a5.487 5.487 0 0 1 1.612 3.887v188.088a5.487 5.487 0 0 0 0.925 3.05l126.175 189.225a5.487 5.487 0 0 1 0.925 3.05V960a64 64 0 0 1-64 64zM117.975 496.987l-48.112 70.425A5.487 5.487 0 0 0 74.4 576h48.1a5.487 5.487 0 0 0 5.487-5.488v-70.437a5.487 5.487 0 0 0-10.012-3.088zM704 122.5a69.5 69.5 0 0 0 69.5 69.5 5.487 5.487 0 0 0 3.888-9.375l-64.013-64A5.487 5.487 0 0 0 704 122.5zM826.5 256H709.487A69.487 69.487 0 0 1 640 186.512V69.487A5.487 5.487 0 0 0 634.513 64H261.487A69.487 69.487 0 0 0 192 133.487v437.025a5.487 5.487 0 0 0 5.5 5.488h117.1a5.475 5.475 0 0 1 5.475 5.325 192 192 0 0 0 383.85 0A5.475 5.475 0 0 1 709.4 576h117.1a5.487 5.487 0 0 0 5.488-5.487V261.487a5.487 5.487 0 0 0-5.475-5.487zM896 525.262v45.25a5.487 5.487 0 0 0 5.487 5.488h45.25a5.487 5.487 0 0 0 3.888-9.375l-45.25-45.25a5.487 5.487 0 0 0-9.375 3.888z m-570.513-141.25h373.025A5.487 5.487 0 0 1 704 389.5v53a5.487 5.487 0 0 1-5.488 5.487H325.488A5.487 5.487 0 0 1 320 442.5v-53.013a5.487 5.487 0 0 1 5.487-5.487z m0-128h245a5.487 5.487 0 0 1 5.488 5.488v53.013a5.487 5.487 0 0 1-5.488 5.487h-245a5.487 5.487 0 0 1-5.487-5.487v-53.025a5.487 5.487 0 0 1 5.487-5.488z m-5.487 0" p-id="9281"></path></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,12 +1,13 @@
import { defineStore } from 'pinia'
import {
IAlterLog,
IBlog, IBlogCategory, IBlogComment,
IBlogLatest, IBlogNestedComment, IBlogStats, INewBlog, IQueryBlog
} from '@/types/blog'
import {
addBlogApi,
addBlogCommentApi,
deleteBlogApi,
deleteBlogApi, queryBlogAlterApi,
queryBlogApi,
queryBlogByIdApi,
queryBlogCategoryApi,
@@ -27,6 +28,7 @@ export const useBlogStore = defineStore('blog', {
unapprovedBlogList: [] as IBlog[],
blogCommentList: [] as IBlogComment[],
blogNestedCommentList: [] as IBlogNestedComment[],
alterLogList: [] as IAlterLog[],
currentBlogComment: {
id: 0,
blogId: 0,
@@ -66,7 +68,9 @@ export const useBlogStore = defineStore('blog', {
blogCategoryList: [] as IBlogCategory[],
blogStats: {} as IBlogStats,
latestBlogList: [] as IBlogLatest[],
queryBlog: {} as IQueryBlog,
queryBlog: {
category: ''
} as IQueryBlog,
blogImagePath: ImagePathEnum.BLOG,
blogApiType: 'ADD' as IHandleApi,
pageInfo: {
@@ -81,13 +85,16 @@ export const useBlogStore = defineStore('blog', {
actions: {
async queryBlogList() {
const { currentPage, pageSize } = this.pageInfo
const result = await queryBlogApi(currentPage, pageSize)
const result = await queryBlogApi(currentPage, pageSize, this.queryBlog.category)
this.blogList = result.records
this.pageInfo.totalSize = result.total
},
async queryUnapprovedBlogList() {
this.unapprovedBlogList = await queryUnapprovedBlogApi()
},
async queryBlogAlterLogList() {
this.alterLogList = await queryBlogAlterApi('puppy-service')
},
async queryBlogById(id: number) {
this.currentBlog = await queryBlogByIdApi(id)
await this.queryBlogComment(this.currentBlogId)

View File

@@ -194,9 +194,9 @@ $transition-time: 0.28s;
.card-item {
background-color: #FFFFFF;
border: 1px solid #FFFFFF;
border: 1px solid #CFCFCF;
border-radius: 10px;
box-shadow: 1px 1px 2px #CFCFCF;
// box-shadow: 1px 1px 2px #CFCFCF;
}
}

View File

@@ -92,3 +92,12 @@ export interface IBlogOverview {
greatCount: number;
visitCount: number;
}
export interface IAlterLog {
alterName: string;
alterTime: string;
logTime: string;
logTopic: string;
logMessage: string;
logStatus: string;
}

View File

@@ -4,6 +4,14 @@
<el-button type="primary" @click="addNewBlogClick">新增文章</el-button>
</div>
<el-form :inline="true" :model="blogStore.queryBlog">
<el-form-item label="类别" style="margin-bottom: 0;">
<el-input v-model="blogStore.queryBlog.category"
placeholder="请输入博客类别" clearable
@input="changeCategoryClick"/>
</el-form-item>
</el-form>
<el-table
:data="blogStore.blogList"
border stripe
@@ -78,6 +86,10 @@ const changePageClick = async (page: number, pageSize: number) => {
await blogStore.queryBlogList()
}
const changeCategoryClick = async () => {
await blogStore.queryBlogList()
}
/**
* 点击新增博客按钮
*/

View File

@@ -1,82 +0,0 @@
<template>
<div class="admin-module">
<div class="button-container">
<el-button type="primary" @click="addNewCategoryClick">新增类别</el-button>
</div>
<el-table
:data="blogStore.blogCategoryList"
border stripe
:header-cell-style="tableHeaderStyle()"
:cell-style="tableCellStyle()"
:row-style="tableRowStyle()"
style="width: 50%"
class="card-item">
<el-table-column type="index" align="center" width="50" />
<el-table-column prop="name" label="名称" align="center" min-width="10%"/>
<el-table-column prop="count" label="数量" align="center" min-width="10%" />
<el-table-column fixed="right" label="操作" align="center" width="200">
<template #default="scope">
<el-button type="primary" @click="editCategoryClick(scope.row)">编辑</el-button>
<el-button type="danger" @click="deleteCategoryClick(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script lang="ts" setup>
import { onMounted } from 'vue'
import { useBlogStore } from '@/store/blog.ts'
import { IBlogCategory } from '@/types/blog.ts'
import { ElMessageBox } from 'element-plus'
import { tableCellStyle, tableHeaderStyle, tableRowStyle } from 'vue3-common/utils/elUtil'
const blogStore = useBlogStore()
onMounted(async () => {
await blogStore.queryBlogCategory()
})
/**
* 点击新增类别按钮
*/
const addNewCategoryClick = () => {
ElMessageBox.prompt('请输入类别名称', '新增类别', {
confirmButtonText: '确认',
cancelButtonText: '取消',
inputPlaceholder: '请输入类别名称',
inputPattern: /^.{0,10}$/,
inputErrorMessage: '请输入10字以内的类别名称'
})
.then(({ value }) => {
console.log(value)
})
}
/**
* 点击编辑类别按钮
* @param category 类别
*/
const editCategoryClick = async (category: IBlogCategory) => {
ElMessageBox.prompt('请输入类别名称', '编辑类别', {
confirmButtonText: '确认',
cancelButtonText: '取消',
inputValue: category.name,
inputPlaceholder: '请输入类别名称',
inputPattern: /^.{0,10}$/,
inputErrorMessage: '请输入10字以内的类别名称'
})
.then(({ value }) => {
console.log(value)
})
}
/**
* 点击删除类别按钮
* @param category 类别
*/
const deleteCategoryClick = (category: IBlogCategory) => {
}
</script>

View File

@@ -1,13 +1,18 @@
<template>
<div class="admin-module blog-dashboard">
<div class="blog-overview">
<el-statistic class="card-item" title="博客总数" :value="blogDashboard.overview.blogCount" />
<el-statistic class="card-item" title="博客总数" suffix="篇"
:value="blogDashboard.overview.blogCount"
/>
<el-statistic class="card-item" title="类别总数" :value="blogDashboard.overview.categoryCount" />
<el-statistic class="card-item" title="类别总数" suffix="个"
:value="blogDashboard.overview.categoryCount"/>
<el-statistic class="card-item" title="字数计" :value="blogDashboard.overview.wordCount" />
<el-statistic class="card-item" title="字数计" suffix="字"
:value="blogDashboard.overview.wordCount" />
<el-statistic class="card-item" title="访问计" :value="blogDashboard.overview.visitCount" />
<el-statistic class="card-item" title="访问计" suffix="人"
:value="blogDashboard.overview.visitCount" />
</div>
<div class="blog-chart">

View File

@@ -21,10 +21,6 @@ export const metaList: IRouteMetaConfig = {
title: '文章管理',
icon: 'admin-blogArticle'
},
'/blog/category': {
title: '类别管理',
icon: 'admin-blogCategory'
},
'/blog/unapproved': {
title: '草稿箱',
icon: 'admin-blogUnapproved'
@@ -41,12 +37,16 @@ export const metaList: IRouteMetaConfig = {
},
'/monitor': {
title: '监控管理',
icon: 'admin-blogVisit',
icon: 'admin-blogMonitor',
order: 3,
redirect: '/monitor/visit'
},
'/monitor/visit': {
title: '监控管理',
icon: ''
title: '访问记录',
icon: 'admin-blogVisit'
},
'/monitor/alter': {
title: '告警记录',
icon: 'admin-blogLog'
}
}

101
src/views/monitor/alter.vue Normal file
View File

@@ -0,0 +1,101 @@
<template>
<div class="admin-module">
<el-table
:data="blogStore.alterLogList"
border stripe
:span-method="handleSpanMethod"
:header-cell-style="tableHeaderStyle()"
:cell-style="tableCellStyle()"
:row-style="tableRowStyle()"
style="width: 100%"
class="card-item">
<el-table-column type="index" align="center" width="50" />
<el-table-column prop="alterTime" label="告警时间" align="center" width="150px" />
<el-table-column prop="logTime" label="日志时间" align="center" width="150px" />
<el-table-column prop="logTopic" label="日志话题" align="center" width="150px" />
<el-table-column prop="logMessage" label="日志消息" align="center"/>
<el-table-column prop="logStatus" label="告警状态" align="center" width="100px">
<template #default="scope">
<el-tag v-if="scope.row.logStatus === 'pending'" type="danger">待处理</el-tag>
<el-tag v-if="scope.row.logStatus === 'complete'" type="success">已完成</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200px" align="center">
<template #default="scope">
<el-button type="primary">下载</el-button>
<el-button type="primary" :disabled="scope.row.logStatus === 'pending'">
已处理
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script lang="ts" setup>
import { onMounted } from 'vue'
import { tableCellStyle, tableHeaderStyle, tableRowStyle } from 'vue3-common/utils/elUtil'
import { useBlogStore } from '@/store/blog'
const blogStore = useBlogStore()
onMounted(async () => {
await blogStore.queryBlogAlterLogList()
})
const handleSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
const data = blogStore.alterLogList
// 合并规则:相同 alterTime + logStatus 的行合并
if (column.property === 'alterTime' || column.property === 'logStatus') {
const currentAlterTime = row.alterTime
const currentLogStatus = row.logStatus
// 检查是否和上一行的告警时间和状态相同
if (rowIndex > 0) {
const prevRow = data[rowIndex - 1]
if (prevRow.alterTime === currentAlterTime && prevRow.logStatus === currentLogStatus) {
return { rowspan: 0, colspan: 0 } // 隐藏当前单元格
}
}
// 计算连续相同 alterTime + logStatus 的行数
let rowspan = 1
for (let i = rowIndex + 1; i < data.length; i++) {
const nextRow = data[i]
if (nextRow.alterTime === currentAlterTime && nextRow.logStatus === currentLogStatus) {
rowspan++
} else {
break
}
}
return { rowspan, colspan: 1 }
}
// 合并操作列(最后一列)
if (columnIndex === 6) { // 操作列是第7列索引从0开始
const currentAlterTime = row.alterTime
const currentLogStatus = row.logStatus
// 检查是否和上一行的告警时间和状态相同
if (rowIndex > 0) {
const prevRow = data[rowIndex - 1]
if (prevRow.alterTime === currentAlterTime && prevRow.logStatus === currentLogStatus) {
return { rowspan: 0, colspan: 0 }
}
}
// 计算连续相同 alterTime + logStatus 的行数
let rowspan = 1
for (let i = rowIndex + 1; i < data.length; i++) {
const nextRow = data[i]
if (nextRow.alterTime === currentAlterTime && nextRow.logStatus === currentLogStatus) {
rowspan++
} else {
break
}
}
return { rowspan, colspan: 1 }
}
}
</script>

View File

@@ -40,6 +40,11 @@ export default defineConfig({
target: `http://${API_HOST}:8082`,
changeOrigin: true,
rewrite: (item) => item.replace(/^\/blog-api/, '')
},
'/alter-api': {
target: `http://${API_HOST}:8000`,
changeOrigin: true,
rewrite: (item) => item.replace(/^\/alter-api/, '')
}
}
}