refactor: ♻️ 控制台精简重构(访问统计调整和添加项目相关信息)

This commit is contained in:
Ray.Hao
2024-12-08 18:57:52 +08:00
parent e3e0bec22e
commit a7c1c4e14a
20 changed files with 287 additions and 283 deletions

View File

@@ -193,32 +193,14 @@ export default defineMock([
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
data: [ data: {
{ todayPvCount: 1629,
type: "pv", totalPvCount: 286086,
title: "浏览量", pvGrowthRate: -0.65,
todayCount: 1003, todayIpCount: 169,
totalCount: 36193, totalIpCount: 19985,
growthRate: -0.35, ipGrowthRate: -0.57,
granularityLabel: "日", },
},
{
type: "uv",
title: "访客数",
todayCount: 100,
totalCount: 2000,
growthRate: 0,
granularityLabel: "日",
},
{
type: "ip",
title: "IP数",
todayCount: 152,
totalCount: 3234,
growthRate: -0.2,
granularityLabel: "日",
},
],
msg: "一切ok", msg: "一切ok",
}, },
}, },

View File

@@ -37,7 +37,7 @@ const LogAPI = {
* @returns * @returns
*/ */
getVisitStats() { getVisitStats() {
return request<any, VisitStatsVO[]>({ return request<any, VisitStatsVO>({
url: `${LOG_BASE_URL}/visit-stats`, url: `${LOG_BASE_URL}/visit-stats`,
method: "get", method: "get",
}); });
@@ -106,15 +106,16 @@ export interface VisitTrendQuery {
/** 访问统计 */ /** 访问统计 */
export interface VisitStatsVO { export interface VisitStatsVO {
/** 标题 */ /** 今日访客数(UV) */
title: string; todayUvCount: number;
/** 类型 */ /** 总访客数 */
type: "pv" | "uv" | "ip"; totalUvCount: number;
/** 访客数同比增长率(相对于昨天同一时间段的增长率) */
/** 今日访问量 */ uvGrowthRate: number;
todayCount: number; /** 今日浏览量(PV) */
/** 总访问量 */ todayPvCount: number;
totalCount: number; /** 总浏览量 */
totalPvCount: number;
/** 同比增长率(相对于昨天同一时间段的增长率) */ /** 同比增长率(相对于昨天同一时间段的增长率) */
growthRate: number; pvGrowthRate: number;
} }

View File

@@ -0,0 +1 @@
<svg t="1733556119022" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="60026" width="128" height="128"><path d="M0 0m184.32 0l655.36 0q184.32 0 184.32 184.32l0 655.36q0 184.32-184.32 184.32l-655.36 0q-184.32 0-184.32-184.32l0-655.36q0-184.32 184.32-184.32Z" fill="#EC5D85" p-id="60027"></path><path d="M512 241.96096h52.224l65.06496-96.31744c49.63328-50.31936 89.64096 0.43008 63.85664 45.71136l-34.31424 51.5072c257.64864 5.02784 257.64864 43.008 257.64864 325.03808 0 325.94944 0 336.46592-404.48 336.46592S107.52 893.8496 107.52 567.90016c0-277.69856 0-318.80192 253.14304-324.95616l-39.43424-58.368c-31.26272-54.90688 37.33504-90.40896 64.68608-42.37312l60.416 99.80928c18.18624-0.0512 41.18528-0.0512 65.66912-0.0512z" fill="#EF85A7" p-id="60028"></path><path d="M512 338.5856c332.8 0 332.8 0 332.8 240.64s0 248.39168-332.8 248.39168-332.8-7.75168-332.8-248.39168 0-240.64 332.8-240.64z" fill="#EC5D85" p-id="60029"></path><path d="M281.6 558.08a30.72 30.72 0 0 1-27.47392-16.97792 30.72 30.72 0 0 1 13.73184-41.216l122.88-61.44a30.72 30.72 0 0 1 41.216 13.74208 30.72 30.72 0 0 1-13.74208 41.216l-122.88 61.44a30.59712 30.59712 0 0 1-13.73184 3.23584zM752.64 558.08a30.60736 30.60736 0 0 1-12.8512-2.83648l-133.12-61.44a30.72 30.72 0 0 1-15.04256-40.7552 30.72 30.72 0 0 1 40.76544-15.02208l133.12 61.44A30.72 30.72 0 0 1 752.64 558.08zM454.656 666.88a15.36 15.36 0 0 1-12.288-6.1952 15.36 15.36 0 0 1 3.072-21.49376l68.5056-50.91328 50.35008 52.62336a15.36 15.36 0 0 1-22.20032 21.23776l-31.5904-33.024-46.71488 34.72384a15.28832 15.28832 0 0 1-9.13408 3.04128z" fill="#EF85A7" p-id="60030"></path><path d="M65.536 369.31584c15.03232 101.90848 32.84992 147.17952 44.544 355.328 14.63296 2.18112 177.70496 10.04544 204.05248-74.62912a16.14848 16.14848 0 0 0 1.64864-10.87488c-30.60736-80.3328-169.216-60.416-169.216-60.416s-10.36288-146.50368-11.49952-238.83776zM362.25024 383.03744l34.816 303.17568h34.64192L405.23776 381.1328zM309.52448 536.28928h45.48608l16.09728 158.6176-31.82592 1.85344zM446.86336 542.98624h45.80352V705.3312h-33.87392zM296.6016 457.97376h21.39136l5.2736 58.99264-18.91328 2.26304zM326.99392 457.97376h21.39136l2.53952 55.808-17.408 1.61792zM470.62016 459.88864h19.456v62.27968h-19.456zM440.23808 459.88864h22.20032v62.27968h-16.62976z" fill="#FFFFFF" p-id="60031"></path><path d="M243.56864 645.51936a275.456 275.456 0 0 1-28.4672 23.74656 242.688 242.688 0 0 1-29.53216 17.52064 2.70336 2.70336 0 0 1-4.4032-1.95584 258.60096 258.60096 0 0 1-5.12-29.57312c-1.41312-12.1856-1.95584-25.68192-2.16064-36.36224 0-0.3072 0-2.5088 3.01056-1.90464a245.92384 245.92384 0 0 1 34.22208 9.5744 257.024 257.024 0 0 1 32.3584 15.17568c0.52224 0.256 2.51904 1.4848 0.09216 3.77856z" fill="#EB5480" p-id="60032"></path><path d="M513.29024 369.31584c15.03232 101.90848 32.84992 147.17952 44.544 355.328 14.63296 2.18112 177.70496 10.04544 204.05248-74.62912a16.14848 16.14848 0 0 0 1.64864-10.87488c-30.60736-80.3328-169.216-60.416-169.216-60.416s-10.36288-146.50368-11.49952-238.83776zM810.00448 383.03744l34.816 303.17568h34.64192L852.992 381.1328zM757.27872 536.28928h45.48608l16.09728 158.6176-31.82592 1.85344zM894.6176 542.98624h45.80352V705.3312H906.5472zM744.35584 457.97376h21.39136l5.2736 58.99264-18.91328 2.26304zM774.74816 457.97376h21.39136l2.53952 55.808-17.408 1.61792zM918.3744 459.88864h19.456v62.27968h-19.456zM887.99232 459.88864h22.20032v62.27968h-16.62976z" fill="#FFFFFF" p-id="60033"></path><path d="M691.32288 645.51936a275.456 275.456 0 0 1-28.4672 23.74656 242.688 242.688 0 0 1-29.53216 17.52064 2.70336 2.70336 0 0 1-4.4032-1.95584 258.60096 258.60096 0 0 1-5.12-29.57312c-1.41312-12.1856-1.95584-25.68192-2.16064-36.36224 0-0.3072 0-2.5088 3.01056-1.90464a245.92384 245.92384 0 0 1 34.22208 9.5744 257.024 257.024 0 0 1 32.3584 15.17568c0.52224 0.256 2.51904 1.4848 0.09216 3.77856z" fill="#EB5480" p-id="60034"></path></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1 @@
<svg t="1733620744216" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13366" width="128" height="128"><path d="M512.956 741.549c24.671-8.545 73.221-25.811 120.072-46.486 12.131-5.394 24.087-12.036 47.412-25.31a109.078 109.078 0 0 0 37.94-29.11 83.344 83.344 0 0 0 12.227-23.053V219.281c-0.096-24.831-20.211-44.936-45.045-45.043-9.34 1.573-22.76 4.209-38.757 8.543 24.439 62.406 18.146 132.708-17.021 189.792-34.498 55.993-92.88 92.712-158.098 99.992-1.275 0.137-2.499 0.463-3.776 0.585v223.354c0.11 24.835 20.213 44.934 45.046 45.045zM378.672 741.549c24.833-0.108 44.939-20.21 45.046-45.047V472.779a213.556 213.556 0 0 1-158.787-101.461c-34.357-56.592-40.495-125.929-16.655-187.697a423.782 423.782 0 0 0-42.873-9.482c-24.833 0.098-44.938 20.214-45.047 45.047v398.308a82.748 82.748 0 0 0 12.242 23.039c10.5 12.524 23.704 22.495 38.591 29.219 23.801 13.273 35.756 20.011 47.424 25.311 46.84 20.673 95.405 37.942 120.059 46.486z" fill="#FFBA00" opacity=".4" p-id="13367"></path><path d="M744.827 708.729a57 57 0 0 0 32.919-11.275 53.974 53.974 0 0 0 17.343-27.226V271.907c-0.066-23.054-17.548-42.33-40.493-44.667 0.528 2.635 0.815 5.297 0.855 7.974v398.309a82.915 82.915 0 0 1-12.227 23.037 108.602 108.602 0 0 1-37.941 29.126c-22.944 12.799-34.805 19.428-46.568 24.752 12.528 0.003 49.706 0.761 86.112-1.709zM141.202 227.432c-22.861 2.335-40.317 21.49-40.495 44.475V670.23a53.882 53.882 0 0 0 17.362 27.4 56.9 56.9 0 0 0 32.902 11.291c36.421 2.471 73.585 1.984 86.112 1.711-11.764-5.324-23.61-11.958-46.565-24.751a108.597 108.597 0 0 1-37.928-29.128 82.787 82.787 0 0 1-12.242-23.036V235.404c0.041-2.676 0.327-5.338 0.854-7.972z" fill="#FFBA00" opacity=".4" p-id="13368"></path><path d="M629.782 372.569c35.172-57.083 41.463-127.383 17.023-189.792-0.007-0.026-0.016-0.066-0.029-0.096-51.497 13.939-127.844 45.508-165.674 117.207a189.132 189.132 0 0 0-13.288 31.87v141.388c1.307-0.123 2.569-0.447 3.872-0.585 65.218-7.28 123.598-44 158.096-99.992zM248.658 183.62c-23.842 61.769-17.701 131.105 16.639 187.697 34.357 56.608 93.013 94.084 158.8 101.461h0.099v-141.02a190.385 190.385 0 0 0-13.273-31.87c-36.989-70.079-110.861-101.855-162.265-116.268z" fill="#FEC744" opacity=".4" p-id="13369"></path><path d="M593.104 570.52v223.357c0.105 24.83 20.215 44.938 45.05 45.046 24.668-8.544 73.218-25.811 120.071-46.488 12.127-5.392 24.086-12.036 47.409-25.306a109.116 109.116 0 0 0 37.941-29.114 83.408 83.408 0 0 0 12.225-23.051v-398.31c-0.092-24.833-20.21-44.938-45.045-45.047-9.481 1.602-23.134 4.265-39.446 8.723 24.355 62.297 18.091 132.42-16.915 189.423a213.388 213.388 0 0 1-161.29 100.767zM330.601 271.513c-24.833 0.094-44.939 20.214-45.048 45.045v398.31a82.678 82.678 0 0 0 12.24 23.039c10.502 12.524 23.708 22.493 38.595 29.22 23.799 13.271 35.753 20.013 47.422 25.307 46.841 20.677 95.404 37.944 120.062 46.488 24.831-0.109 44.938-20.216 45.045-45.046v-223.72c-65.791-7.377-124.448-44.86-158.79-101.463-34.354-56.591-40.496-125.93-16.655-187.696a423.057 423.057 0 0 0-42.871-9.484z" fill="#FFBA00" p-id="13370"></path><path d="M868.422 753.937a108.626 108.626 0 0 1-37.943 29.126c-22.944 12.796-34.805 19.428-46.567 24.75 12.526 0 49.702 0.765 86.112-1.71a56.988 56.988 0 0 0 32.916-11.274 54.009 54.009 0 0 0 17.346-27.228v-398.32c-0.069-23.053-17.552-42.328-40.496-44.667 0.529 2.635 0.815 5.299 0.855 7.974v398.31a83.035 83.035 0 0 1-12.223 23.039zM266.399 324.804c-22.863 2.338-40.319 21.491-40.496 44.477v398.323a53.886 53.886 0 0 0 17.361 27.4 56.879 56.879 0 0 0 32.901 11.291c36.419 2.471 73.587 1.983 86.111 1.708-11.764-5.323-23.608-11.953-46.566-24.75a108.578 108.578 0 0 1-37.928-29.124 82.698 82.698 0 0 1-12.238-23.039V332.779c0.039-2.675 0.326-5.338 0.855-7.975z" fill="#FFBA00" p-id="13371"></path><path d="M771.97 280.058c-51.497 13.939-127.844 45.508-165.675 117.207a188.947 188.947 0 0 0-13.289 31.871v141.386c66.797-6.206 126.786-43.472 161.969-100.58 35.184-57.11 41.473-127.45 16.995-189.884z" fill="#FFBA00" p-id="13372"></path><path d="M771.97 280.058c-51.497 13.939-127.844 45.508-165.675 117.207a188.947 188.947 0 0 0-13.289 31.871v141.386c66.797-6.206 126.786-43.472 161.969-100.58 35.184-57.11 41.473-127.45 16.995-189.884z" fill="#FEC744" p-id="13373"></path><path d="M549.294 570.155h0.095V429.132a189.948 189.948 0 0 0-13.271-31.871c-36.992-70.081-110.863-101.856-162.266-116.268-23.839 61.769-17.701 131.105 16.642 187.696 34.352 56.608 93.012 94.089 158.8 101.466z" fill="#FFBA00" p-id="13374"></path><path d="M549.294 570.155h0.095V429.132a189.948 189.948 0 0 0-13.271-31.871c-36.992-70.081-110.863-101.856-162.266-116.268-23.839 61.769-17.701 131.105 16.642 187.696 34.352 56.608 93.012 94.089 158.8 101.466z" fill="#FEC744" p-id="13375"></path></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1 @@
<svg t="1733555747788" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10924" width="128" height="128"><path d="M851.404 172.596c-187.462-187.461-491.346-187.461-678.808 0-187.461 187.462-187.461 491.346 0 678.808 187.462 187.461 491.346 187.461 678.808 0 187.461-187.462 187.461-491.346 0-678.808zM387.33 728.087a47.084 47.084 0 1 1-66.633-66.502 47.084 47.084 0 0 1 66.633 66.502z m205.527 1.397a38.75 38.75 0 0 1-76.625-11.52h-0.044a6.545 6.545 0 0 0-0.044 0.305v-0.349c0.306-2.618 2.051-20.727-2.967-44.99a174.24 174.24 0 0 0-48.567-89.28 172.102 172.102 0 0 0-88.8-48.305 156.698 156.698 0 0 0-42.458-2.923 38.662 38.662 0 0 1-35.39-65.324 38.618 38.618 0 0 1 21.12-10.822v-0.218c4.452-0.742 111.142-16.45 200.335 72.742 89.018 89.018 74.182 196.145 73.44 200.727z m175.2 7.592a38.75 38.75 0 0 1-65.673 21.382 39.49 39.49 0 0 1-11.65-33.73c0.087-0.35 5.105-37.484-5.062-88.975-13.31-67.375-45.295-126.895-94.953-176.902-50.007-49.702-109.527-81.644-176.945-94.953-51.491-10.167-88.582-5.193-89.019-5.149h0.219-0.044a39.927 39.927 0 0 1-44.684-32.902 38.836 38.836 0 0 1 32.204-44.378c1.92-0.305 47.869-7.33 111.273 4.364a411.753 411.753 0 0 1 106.254 34.952 425.76 425.76 0 0 1 114.633 82.255l0.916 0.96 0.96 0.873a425.89 425.89 0 0 1 82.255 114.72c16.407 33.6 28.145 69.294 34.996 106.21 11.651 63.404 4.67 109.353 4.32 111.273z" fill="#1296DB" p-id="10925"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="30px" height="30px" viewBox="0 0 30 30" version="1.1">
<title>ic/csdn</title>
<g id="ic/csdn" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M24.7385612,21.818791 C24.4728206,21.5662432 24.1090763,21.4267765 23.7575825,21.4343152 C23.3966653,21.4399693 23.0696724,21.5907441 22.8378562,21.8555424 C20.7581061,24.2349574 17.1347988,24.4922169 15.6732254,24.4922169 C12.9611634,24.4922169 10.886125,23.8043069 9.50559315,22.4501605 C8.19385225,21.1638629 7.50594216,19.2678696 7.46070972,16.8168365 C7.35516735,11.1345107 10.5732673,5.25806226 16.139685,5.25806226 C18.7980335,5.25806226 20.8627061,7.14368979 21.6260036,7.95410443 C21.8917442,8.23586486 22.2583155,8.39794779 22.6352525,8.39983247 C23.0131319,8.4092559 23.362741,8.24151892 23.599269,7.96164317 L23.8160078,7.70532598 C24.2607935,7.18232584 24.4605701,6.50572386 24.380471,5.80179394 C24.2984872,5.09126763 23.9422817,4.44293592 23.3778185,3.97459165 C22.0133064,2.84472288 19.6951436,1.5 16.3969445,1.5 C12.9715292,1.5 9.58757695,3.07465447 7.1129853,5.82441016 C4.51306208,8.71269021 3.1240491,12.6441435 3.20320588,16.895051 C3.26634283,20.3063311 4.38490349,23.1729373 6.44015269,25.1886081 C8.64806138,27.3550537 11.8821812,28.5 15.7947876,28.5 C20.3849384,28.5 23.2289283,27.1401996 24.8082945,26.0009074 C25.4198749,25.5608334 25.7845615,24.8644423 25.8128317,24.093606 C25.8392173,23.3190004 25.5225902,22.5604146 24.9430495,22.0119712 L24.7385612,21.818791 Z" id="Fill-1" fill="#FC5533"/>
</g>
<script xmlns=""/></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1 @@
<svg width="24" height="24" class="icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.4791 4.97677C15.6201 4.89789 15.7691 4.8145 15.93 4.72314C15.9494 4.82848 15.9683 4.92046 15.9854 5.00383C16.0157 5.15091 16.0406 5.2719 16.0525 5.39144C16.1479 6.4296 16.6697 7.1933 17.4092 7.36527C18.4908 7.61639 19.5106 7.20133 20.06 6.28555C20.72 5.18673 20.4334 3.84099 19.3097 3.03098C16.1851 0.777435 12.7523 0.155888 9.05448 1.24127C1.08137 3.59371 -1.64675 13.3884 4.01196 19.3949C6.43291 21.9642 9.50695 23.0727 12.9963 22.9889C17.4663 22.8839 20.6857 20.6563 22.7408 16.7954C24.1978 14.0561 22.6139 11.0619 19.5805 10.4396C17.8481 10.0908 16.0765 9.97756 14.3137 10.103C13.7272 10.1594 13.1579 10.3325 12.6394 10.6124C12.0592 10.9135 11.8915 11.5383 11.9565 12.1575C12.0171 12.7217 12.4498 13.0601 12.965 13.1453C14.0024 13.3077 15.0522 13.402 16.1 13.4881C16.4032 13.5136 16.7093 13.5166 17.0149 13.5197C17.4534 13.5241 17.8912 13.5285 18.3187 13.5991C19.5385 13.8007 19.9574 14.7905 19.33 15.8495C19.1763 16.1041 18.9971 16.3424 18.7951 16.5607C17.9745 17.4632 16.9014 18.0981 15.7152 18.3827C13.55 18.9127 11.3827 18.9425 9.22755 18.2617C6.77347 17.4875 5.31042 15.6849 5.25902 13.2584C5.2398 11.7619 5.61972 10.2874 6.35969 8.9865C6.694 8.38013 6.87751 7.75562 6.82593 7.06851C6.80422 6.77557 6.79219 6.48231 6.77927 6.16716C6.77239 5.99944 6.76526 5.82551 6.75628 5.64214C7.00484 5.69431 7.25032 5.76016 7.49161 5.83943C8.43027 6.21622 9.35415 6.38811 10.3702 6.11155C10.9481 5.97335 11.5455 5.93511 12.1363 5.9985C13.0877 6.07606 14.0387 5.84361 14.847 5.33586C15.0488 5.2176 15.2539 5.10279 15.4791 4.97677Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1 +0,0 @@
<svg t="1719843722868" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="226927" width="200" height="200"><path d="M276.854606 340.74413h468.523178v298.151114H276.854606z" fill="#0ee41c" p-id="226928"></path><path d="M511.116195 1.76761c-282.285215 0-511.116195 228.83098-511.116195 511.116195s228.83098 511.116195 511.116195 511.116195 511.116195-228.83098 511.116195-511.116195c0-282.263919-228.83098-511.116195-511.116195-511.116195z m276.854605 670.712227C787.9708 686.343864 759.284404 724.081276 745.420377 724.081276H575.005719v15.354782l42.593017 33.478111V787.9708H404.633654v-15.077927l42.593017-33.478111V724.081276h-170.414658C262.926689 724.081276 234.261589 686.343864 234.261589 672.479837V337.762619c0-13.864027 28.6651-39.611505 42.550424-39.611505h468.608364C759.284404 298.151114 787.9708 323.898592 787.9708 337.762619v334.717218z" fill="#0ee41c" p-id="226929"></path></svg>

Before

Width:  |  Height:  |  Size: 937 B

View File

@@ -0,0 +1 @@
<svg t="1733555774238" class="icon" viewBox="0 0 1316 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="46620" width="128" height="128"><path d="M643.181714 247.698286l154.916572-123.172572L643.181714 0.256 643.072 0l-154.660571 124.269714 154.660571 123.245715 0.109714 0.182857z m0 388.461714h0.109715l399.579428-315.245714-108.361143-87.04-291.218285 229.888h-0.146286l-0.109714 0.146285L351.817143 234.093714l-108.251429 87.04 399.433143 315.136 0.146286-0.146285z m-0.146285 215.552l0.146285-0.146286 534.893715-422.034285 108.397714 87.04-243.309714 192L643.145143 1024 10.422857 525.056 0 516.754286l108.251429-86.893715L643.035429 851.748571z" fill="#1E80FF" p-id="46621"></path></svg>

After

Width:  |  Height:  |  Size: 705 B

View File

@@ -1 +0,0 @@
<svg t="1719843111735" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="146261" width="200" height="200"><path d="M512 42.7C252.8 42.7 42.7 252.8 42.7 512c0 259.2 210.1 469.3 469.3 469.3S981.3 771.2 981.3 512c0-259.2-210.1-469.3-469.3-469.3z m93.3 225.9c16.1 0 29.1 13 29.1 29.1s-13.1 29.1-29.1 29.1c-16.1 0-29.1-13.1-29.1-29.1-0.1-16 13-29.1 29.1-29.1zM506.2 257c19.3 0 35 15.7 35 35s-15.7 35-35 35-35-15.7-35-35c0-19.4 15.7-35 35-35zM343 321.1c0-29 23.5-52.5 52.5-52.5s52.5 23.5 52.5 52.5-23.5 52.5-52.5 52.5c-29.1 0-52.5-23.5-52.5-52.5z m303.1 247.7c-11.7 35 11.7 81.6-11.7 128.2-23.3 46.6-58.3 69.9-93.3 69.9s-104.9 0-104.9-93.3c0-70 35-58.3 35-104.9s-23.3-23.3-58.3-81.6 0-93.3 0-93.3 58.3-58.3 174.9-23.3c116.6 35.1 69.9 163.4 58.3 198.3z m11.6-198.2c-12.9 0-23.3-10.4-23.3-23.3s10.4-23.3 23.3-23.3 23.3 10.4 23.3 23.3-10.4 23.3-23.3 23.3z" fill="#FFBD27" p-id="146262"></path></svg>

Before

Width:  |  Height:  |  Size: 933 B

View File

@@ -1 +0,0 @@
<svg t="1719764607585" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="61790" width="200" height="200"><path d="M597.8 316.59c-8.82 0-17.64 1.26-25.2 3.78 18.9 27.72 28.98 60.48 28.98 97.03 0 39.06-13.86 76.87-37.8 108.37l-2.52 2.52v1.26c-2.52 2.52-6.3 6.3-7.56 10.08 0 1.26 0 1.26 1.26 1.26 2.52 1.26 6.3 2.52 10.08 2.52h1.26l5.04 2.52c51.66 16.38 95.77 45.36 124.75 81.91 12.6 16.38 20.16 35.28 20.16 55.44 0 11.34-2.52 20.16-6.3 30.24h36.54c28.98 0 51.66-21.42 51.66-49.14-1.26-13.86-5.04-23.94-12.6-32.76-21.42-26.46-54.18-49.14-95.77-61.74 0 0-16.38-3.78-21.42-6.3-8.82-6.3-13.86-16.38-13.86-27.72 0-12.6 10.08-22.68 16.38-28.98 16.38-20.16 26.46-46.62 26.46-76.87 0-61.76-44.1-113.42-99.54-113.42z m-142.4-27.72c-61.74 0-112.15 57.96-112.15 128.53 0 34.02 11.34 64.26 28.98 86.95 11.34 6.3 18.9 20.16 18.9 34.02 0 12.6-6.3 23.94-16.38 31.5v1.26c-1.26 0-2.52 1.26-2.52 1.26-6.3 3.78-12.6 6.3-20.16 6.3-47.88 16.38-88.21 41.58-112.15 73.09h1.26c-6.3 8.82-8.82 18.9-8.82 28.98 0 30.24 25.2 55.44 56.7 55.44h332.67c32.76 0 57.96-23.94 57.96-55.44 0-12.6-5.04-23.94-11.34-34.02-23.94-31.5-61.74-55.44-108.37-70.57 0 0-3.47-0.93-7.84-2.18l-9.15-2.78c-2.94-0.96-5.51-1.88-6.95-2.6-10.08-6.3-16.38-18.9-16.38-31.5 0-13.86 11.34-25.2 18.9-34.02 18.9-22.68 28.98-52.92 28.98-86.95 0.01-70.57-50.39-127.27-112.14-127.27zM511.95 65.2c247.06 0 447.33 200.28 447.33 447.33S759.01 959.87 511.95 959.87 64.62 759.59 64.62 512.53 264.9 65.2 511.95 65.2z" fill="#FF6800" p-id="61791"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg t="1733620604471" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1596" width="128" height="128"><path d="M604.766 304.391c55.072 0 101.33 31.359 125.567 76.137v-94.054c0-51.505-41.856-91.812-92.513-91.812H250.118c-50.659 0-92.518 40.307-92.518 91.812v423.255c0 49.268 41.859 89.574 92.518 89.574h171.824c-30.848-11.195-48.466-33.586-50.672-71.662-4.402-85.105 48.465-161.231 90.321-197.066 6.608-6.728 11.01-11.194 17.616-15.685-8.813-20.149-15.421-42.548-15.421-67.176 0-78.385 61.679-143.323 140.98-143.323z" fill="#C4F7F0" p-id="1597"></path><path d="M804.423 349.242c0-51.507-41.855-91.814-92.515-91.814H324.204c-50.658 0-92.514 40.308-92.514 91.814v423.254c0 49.268 41.855 89.576 92.514 89.576h171.828c-30.846-11.197-48.466-33.587-50.67-71.668-4.404-85.101 48.462-161.239 90.319-197.063 6.608-6.727 11.009-11.196 17.617-15.682-8.813-20.152-15.422-42.549-15.422-67.182 0-78.384 61.68-143.318 140.977-143.318 55.071 0 101.336 31.356 125.57 76.133v-94.05zM394.702 638.123h-66.081c-6.612 0-11.024-4.474-11.024-11.187 0-6.729 4.413-11.2 11.024-11.2h66.081c6.608 0 11.008 4.471 11.008 11.2 0 6.713-4.4 11.187-11.008 11.187z m66.081-89.572H328.62c-4.417 0-11.025-4.477-11.025-11.199 0-6.707 4.413-11.189 11.025-11.189h132.163c6.609 0 11.01 4.482 11.01 11.189 0.001 6.72-4.401 11.199-11.01 11.199z m0-89.577H328.62c-4.417 0-11.025-4.481-11.025-11.2s6.608-11.198 11.025-11.198h132.163c6.609 0 11.01 4.481 11.01 11.198 0.001 6.719-4.401 11.2-11.01 11.2z" fill="#00DFC1" p-id="1598"></path><path d="M566.516 620.21c-33.043 26.875-72.692 85.096-70.484 152.288 2.193 67.177 72.686 67.177 176.216 67.177 103.535 0 174.03 0 176.228-67.177 2.205-67.192-39.651-123.183-70.485-152.288-24.239-22.396-44.066-26.868-50.672-26.868 28.64-15.683 46.256-47.039 46.256-82.861 0-53.743-41.841-96.294-94.722-96.294-52.863 0-94.707 42.551-92.511 96.294 0 35.822 17.628 64.951 46.253 82.861H621.59c-0.002 0-22.034 0-55.074 26.868z" fill="#00DFC1" p-id="1599"></path></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,49 +1,37 @@
<template> <template>
<div> <div>
<el-dropdown class="flex-center wh-full align-middle"> <el-dropdown class="wh-full">
<div class="wh-full"> <el-badge v-if="notices.length > 0" :offset="[-10, 15]" :value="notices.length" :max="99">
<el-badge <el-icon>
v-if="notices.length > 0" <Bell />
:offset="[-10, 15]" </el-icon>
:value="notices.length" </el-badge>
:max="99" <el-badge v-else>
class="wh-full" <el-icon>
> <Bell />
<el-icon class="notification-icon h-full"> </el-icon>
<Bell /> </el-badge>
</el-icon>
</el-badge>
<el-badge v-else class="wh-full">
<el-icon class="notification-icon h-full">
<Bell />
</el-icon>
</el-badge>
</div>
<template #dropdown> <template #dropdown>
<div class="p-2"> <div class="p-2">
<el-tabs v-model="activeTab"> <el-tabs v-model="activeTab">
<el-tab-pane label="通知" name="notice"> <el-tab-pane label="通知" name="notice">
<template v-if="notices.length > 0"> <template v-if="notices.length > 0">
<div <div v-for="(item, index) in notices" :key="index" class="w500px py-3">
v-for="(item, index) in notices" <div class="flex-y-center">
:key="index" <DictLabel v-model="item.type" code="notice_type" size="small" />
class="w400px flex-x-between p-1"
>
<div class="flex-center">
<DictLabel v-model="item.type" code="notice_type" size="small" class="mr-1" />
<el-text <el-text
type="primary"
size="small" size="small"
class="w200px cursor-pointer" class="w200px cursor-pointer !ml-2 !flex-1"
truncated truncated
@click="readNotice(item.id)" @click="handleReadNotice(item.id)"
> >
{{ item.title }} {{ item.title }}
</el-text> </el-text>
</div>
<div> <div class="text-xs text-gray">
{{ item.publishTime }} {{ item.publishTime }}
</div>
</div> </div>
</div> </div>
</template> </template>
@@ -54,7 +42,7 @@
</template> </template>
<el-divider /> <el-divider />
<div class="flex-x-between"> <div class="flex-x-between">
<el-link type="primary" :underline="false" @click="viewMore"> <el-link type="primary" :underline="false" @click="handleViewMore">
<span class="text-xs">查看更多</span> <span class="text-xs">查看更多</span>
<el-icon class="text-xs"> <el-icon class="text-xs">
<ArrowRight /> <ArrowRight />
@@ -77,14 +65,19 @@
:key="index" :key="index"
class="w400px flex-x-between p-1" class="w400px flex-x-between p-1"
> >
<div> <div class="flex-y-center">
<DictLabel v-model="item.type" code="notice_type" size="small" /> <DictLabel v-model="item.type" code="notice_type" size="small" />
<el-link type="primary" class="ml-1" @click="readNotice(item.id)"> <el-link
type="primary"
class="w200px cursor-pointer !ml-2 !flex-1"
@click="handleReadNotice(item.id)"
>
{{ item.title }} {{ item.title }}
</el-link> </el-link>
</div>
<div> <div class="text-xs text-gray-400">
{{ item.publishTime }} {{ item.publishTime }}
</div>
</div> </div>
</div> </div>
</template> </template>
@@ -95,7 +88,12 @@
</template> </template>
<el-divider /> <el-divider />
<div class="flex-x-between"> <div class="flex-x-between">
<el-link type="primary" :underline="false" @click="viewMore"> <el-link
v-if="tasks.length > 5"
type="primary"
:underline="false"
@click="handleViewMore"
>
<span class="text-xs">查看更多</span> <span class="text-xs">查看更多</span>
<el-icon class="text-xs"> <el-icon class="text-xs">
<ArrowRight /> <ArrowRight />
@@ -114,15 +112,19 @@
<el-tab-pane label="待办" name="task"> <el-tab-pane label="待办" name="task">
<template v-if="tasks.length > 0"> <template v-if="tasks.length > 0">
<div v-for="(item, index) in tasks" :key="index" class="w400px flex-x-between p-1"> <div v-for="(item, index) in tasks" :key="index" class="w500px py-3">
<div> <div class="flex-y-center">
<DictLabel v-model="item.type" code="notice_type" size="small" /> <DictLabel v-model="item.type" code="notice_type" size="small" />
<el-link type="primary" class="ml-1" @click="readNotice(item.id)"> <el-link
type="primary"
class="w200px cursor-pointer !ml-2 !flex-1"
@click="handleReadNotice(item.id)"
>
{{ item.title }} {{ item.title }}
</el-link> </el-link>
</div> <div class="text-xs text-gray-400">
<div> {{ item.publishTime }}
{{ item.publishTime }} </div>
</div> </div>
</div> </div>
</template> </template>
@@ -133,7 +135,12 @@
</template> </template>
<el-divider /> <el-divider />
<div class="flex-x-between"> <div class="flex-x-between">
<el-link type="primary" :underline="false" @click="viewMore"> <el-link
v-if="tasks.length > 5"
type="primary"
:underline="false"
@click="handleViewMore"
>
<span class="text-xs">查看更多</span> <span class="text-xs">查看更多</span>
<el-icon class="text-xs"> <el-icon class="text-xs">
<ArrowRight /> <ArrowRight />
@@ -198,7 +205,7 @@ onMounted(() => {
}); });
// 阅读通知公告 // 阅读通知公告
function readNotice(id: string) { function handleReadNotice(id: string) {
noticeDetailRef.value.openNotice(id); noticeDetailRef.value.openNotice(id);
const index = notices.value.findIndex((notice) => notice.id === id); const index = notices.value.findIndex((notice) => notice.id === id);
if (index >= 0) { if (index >= 0) {
@@ -207,7 +214,7 @@ function readNotice(id: string) {
} }
// 查看更多 // 查看更多
function viewMore() { function handleViewMore() {
router.push({ path: "/myNotice" }); router.push({ path: "/myNotice" });
} }
@@ -220,8 +227,11 @@ function markAllAsRead() {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.layout-top .notification-icon, :deep(.el-badge) {
.layout-mix .notification-icon { display: flex;
color: #fff; align-items: center;
justify-content: center;
width: 100%;
height: 100%;
} }
</style> </style>

View File

@@ -9,12 +9,6 @@
<el-dropdown-item @click="handleOpenUserProfile"> <el-dropdown-item @click="handleOpenUserProfile">
{{ $t("navbar.profile") }} {{ $t("navbar.profile") }}
</el-dropdown-item> </el-dropdown-item>
<a target="_blank" href="https://gitee.com/youlaiorg/vue3-element-admin">
<el-dropdown-item>{{ $t("navbar.gitee") }}</el-dropdown-item>
</a>
<a target="_blank" href="https://juejin.cn/post/7228990409909108793">
<el-dropdown-item>{{ $t("navbar.document") }}</el-dropdown-item>
</a>
<el-dropdown-item divided @click="logout"> <el-dropdown-item divided @click="logout">
{{ $t("navbar.logout") }} {{ $t("navbar.logout") }}
</el-dropdown-item> </el-dropdown-item>

View File

@@ -39,3 +39,20 @@ export function isExternal(path: string) {
const isExternal = /^(https?:|http?:|mailto:|tel:)/.test(path); const isExternal = /^(https?:|http?:|mailto:|tel:)/.test(path);
return isExternal; return isExternal;
} }
/**
* 格式化增长率,保留两位小数 并且去掉末尾的0 取绝对值
*
* @param growthRate
* @returns
*/
export function formatGrowthRate(growthRate: number) {
if (growthRate === 0) {
return "-";
}
const formattedRate = Math.abs(growthRate * 100)
.toFixed(2)
.replace(/\.?0+$/, "");
return formattedRate + "%";
}

View File

@@ -1,47 +1,91 @@
<template> <template>
<div class="dashboard-container"> <div class="dashboard-container">
<!-- github 角标 -->
<github-corner class="github-corner" /> <github-corner class="github-corner" />
<el-card shadow="never"> <el-card shadow="never">
<el-row justify="space-between"> <el-row class="h-80px">
<el-col :span="18" :xs="24"> <el-col :span="18" :xs="24">
<div class="flex h-full items-center"> <div class="flex-x-start">
<img <img
class="w-20 h-20 mr-5 rounded-full" class="wh-80px rounded-full"
:src="userStore.userInfo.avatar + '?imageView2/1/w/80/h/80'" :src="userStore.userInfo.avatar + '?imageView2/1/w/80/h/80'"
/> />
<div> <div class="ml-5">
<p>{{ greetings }}</p> <p>{{ greetings }}</p>
<p class="text-sm text-gray">今日天气晴朗气温在15至25之间东南风</p> <p class="text-sm text-gray">今日天气晴朗气温在15至25之间东南风</p>
</div> </div>
</div> </div>
</el-col> </el-col>
<el-col :span="6" :xs="24">
<el-row class="h-80px flex-y-center" :gutter="10">
<el-col :span="10">
<div class="font-bold color-#ff9a2e text-sm flex-y-center">
<el-icon class="mr-2px"><Folder /></el-icon>
仓库
</div>
<div class="mt-3">
<el-link href="https://gitee.com/youlaiorg/vue3-element-admin" target="_blank">
<SvgIcon icon-class="gitee" class="text-lg color-#f76560" />
</el-link>
<el-divider direction="vertical" />
<el-link href="https://github.com/youlaitech/vue3-element-admin" target="_blank">
<SvgIcon icon-class="github" class="text-lg color-#4080ff" />
</el-link>
<el-divider direction="vertical" />
<el-link href="https://gitcode.com/youlai/vue3-element-admin" target="_blank">
<SvgIcon icon-class="gitcode" class="text-lg color-#ff9a2e" />
</el-link>
</div>
</el-col>
<el-col :span="10">
<div class="font-bold color-#4080ff text-sm flex-y-center">
<el-icon class="mr-2px"><Document /></el-icon>
文档
</div>
<div class="mt-3">
<el-link href="https://juejin.cn/post/7228990409909108793" target="_blank">
<SvgIcon icon-class="juejin" class="text-lg" />
</el-link>
<el-divider direction="vertical" />
<el-link
href="https://youlai.blog.csdn.net/article/details/130191394"
target="_blank"
>
<SvgIcon icon-class="csdn" class="text-lg" />
</el-link>
<el-divider direction="vertical" />
<el-link href="https://www.cnblogs.com/haoxianrui/p/17331952.html" target="_blank">
<SvgIcon icon-class="cnblogs" class="text-lg" />
</el-link>
</div>
</el-col>
<el-col :span="4">
<div class="font-bold color-#f76560 text-sm flex-y-center">
<el-icon class="mr-2px"><VideoCamera /></el-icon>
视频
</div>
<div class="mt-3">
<el-link
href="https://space.bilibili.com/1731537706/channel/seriesdetail?sid=4459672"
target="_blank"
>
<SvgIcon icon-class="bilibili" class="text-lg" />
</el-link>
</div>
</el-col>
</el-row>
</el-col>
</el-row> </el-row>
</el-card> </el-card>
<!-- 数据卡片 --> <!-- 数据统计 -->
<el-row :gutter="10" class="mt-5"> <el-row :gutter="10" class="mt-5">
<el-col :xs="24" :sm="12" :lg="6"> <!-- 访客数(UV) -->
<el-card shadow="never"> <el-col :span="12">
<template #header>
<div class="flex-x-between">
<span class="text-[var(--el-text-color-secondary)]">在线用户</span>
<el-tag type="success" size="small">-</el-tag>
</div>
</template>
<div class="flex-x-between mt-2">
<span class="text-lg">{{ onlineUserCount }}</span>
<svg-icon icon-class="user" size="2em" />
</div>
<div class="flex-x-between mt-2 text-sm text-[var(--el-text-color-secondary)]">
<span>总用户数</span>
<span>5</span>
</div>
</el-card>
</el-col>
<el-col v-for="(item, index) in visitStatsList" :key="index" :xs="24" :sm="12" :lg="6">
<el-skeleton :loading="visitStatsLoading" :rows="5" animated> <el-skeleton :loading="visitStatsLoading" :rows="5" animated>
<template #template> <template #template>
<el-card> <el-card>
@@ -66,32 +110,86 @@
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<div class="flex-x-between"> <div class="flex-x-between">
<span class="text-[var(--el-text-color-secondary)]"> <span class="text-gray">访客数(UV)</span>
{{ item.title }} <el-tag type="success" size="small"></el-tag>
</span>
<el-tag :type="item.tagType" size="small">
{{ item.granularity }}
</el-tag>
</div> </div>
</template> </template>
<div class="flex-x-between mt-2"> <div class="flex-x-between mt-2">
<div class="flex-y-center"> <div class="flex-y-center">
<span class="text-lg">{{ item.todayCount }}</span> <span class="text-lg">{{ visitStatsData.todayUvCount }}</span>
<span :class="['text-xs', 'ml-2', getGrowthRateClass(item.growthRate)]"> <span
:class="['text-xs', 'ml-2', getGrowthRateClass(visitStatsData.uvGrowthRate)]"
>
<el-icon> <el-icon>
<Top v-if="item.growthRate > 0" /> <Top v-if="visitStatsData.uvGrowthRate > 0" />
<Bottom v-else-if="item.growthRate < 0" /> <Bottom v-else-if="visitStatsData.uvGrowthRate < 0" />
</el-icon> </el-icon>
{{ formatGrowthRate(item.growthRate) }} {{ formatGrowthRate(visitStatsData.uvGrowthRate) }}
</span> </span>
</div> </div>
<svg-icon :icon-class="item.icon" size="2em" /> <svg-icon icon-class="visitor" size="2em" />
</div> </div>
<div class="flex-x-between mt-2 text-sm text-[var(--el-text-color-secondary)]"> <div class="flex-x-between mt-2 text-sm text-gray">
<span>{{ item.title }}</span> <span>访客数</span>
<span>{{ item.totalCount }}</span> <span>{{ visitStatsData.totalUvCount }}</span>
</div>
</el-card>
</template>
</el-skeleton>
</el-col>
<!-- 浏览量(PV) -->
<el-col :span="12">
<el-skeleton :loading="visitStatsLoading" :rows="5" animated>
<template #template>
<el-card>
<template #header>
<div>
<el-skeleton-item variant="h3" style="width: 40%" />
<el-skeleton-item variant="rect" style="float: right; width: 1em; height: 1em" />
</div>
</template>
<div class="flex-x-between">
<el-skeleton-item variant="text" style="width: 30%" />
<el-skeleton-item variant="circle" style="width: 2em; height: 2em" />
</div>
<div class="mt-5 flex-x-between">
<el-skeleton-item variant="text" style="width: 50%" />
<el-skeleton-item variant="text" style="width: 1em" />
</div>
</el-card>
</template>
<template v-if="!visitStatsLoading">
<el-card shadow="never">
<template #header>
<div class="flex-x-between">
<span class="text-gray">浏览量(PV)</span>
<el-tag type="primary" size="small"></el-tag>
</div>
</template>
<div class="flex-x-between mt-2">
<div class="flex-y-center">
<span class="text-lg">{{ visitStatsData.todayPvCount }}</span>
<span
:class="['text-xs', 'ml-2', getGrowthRateClass(visitStatsData.pvGrowthRate)]"
>
<el-icon>
<Top v-if="visitStatsData.pvGrowthRate > 0" />
<Bottom v-else-if="visitStatsData.pvGrowthRate < 0" />
</el-icon>
{{ formatGrowthRate(visitStatsData.pvGrowthRate) }}
</span>
</div>
<svg-icon icon-class="browser" size="2em" />
</div>
<div class="flex-x-between mt-2 text-sm text-gray">
<span>总浏览量</span>
<span>{{ visitStatsData.totalPvCount }}</span>
</div> </div>
</el-card> </el-card>
</template> </template>
@@ -100,32 +198,30 @@
</el-row> </el-row>
<el-row :gutter="10" class="mt-5"> <el-row :gutter="10" class="mt-5">
<!-- 访问趋势统计图 -->
<el-col :xs="24" :span="16"> <el-col :xs="24" :span="16">
<!-- 访问趋势统计图 -->
<VisitTrend id="VisitTrend" width="100%" height="400px" /> <VisitTrend id="VisitTrend" width="100%" height="400px" />
</el-col> </el-col>
<!-- 通知公告 -->
<el-col :xs="24" :span="8"> <el-col :xs="24" :span="8">
<el-card> <el-card>
<template #header> <template #header>
<div class="flex-x-between"> <div class="flex-x-between">
<div class="flex-y-center">通知公告</div> <div class="flex-y-center">通知公告</div>
<el-link type="primary"> <el-link type="primary">
<span class="text-xs" @click="viewMoreNotice">查看更多</span> <span class="text-xs" @click="handleViewMoreNotice">查看更多</span>
<el-icon class="text-xs"><ArrowRight /></el-icon> <el-icon class="text-xs"><ArrowRight /></el-icon>
</el-link> </el-link>
</div> </div>
</template> </template>
<el-scrollbar height="400px"> <el-scrollbar height="400px">
<div v-for="(item, index) in notices" :key="index" class="flex-y-center py-3"> <div v-for="(item, index) in notices" :key="index" class="flex-y-center py-4">
<DictLabel v-model="item.type" code="notice_type" size="small" /> <DictLabel v-model="item.type" code="notice_type" size="small" />
<el-text <el-text truncated class="!mx-2 flex-1 !text-xs !text-gray">
truncated
class="!mx-2 flex-1 !text-xs !text-[var(--el-text-color-secondary)]"
>
{{ item.title }} {{ item.title }}
</el-text> </el-text>
<el-link @click="viewNoticeDetail(item.id)"> <el-link @click="handleOpenNoticeDetail(item.id)">
<el-icon class="text-sm"><View /></el-icon> <el-icon class="text-sm"><View /></el-icon>
</el-link> </el-link>
</div> </div>
@@ -144,29 +240,20 @@ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}); });
import VisitTrend from "./components/VisitTrend.vue"; import VisitTrend from "./components/visit-trend.vue";
import WebSocketManager from "@/utils/websocket";
import router from "@/router"; import router from "@/router";
import { useUserStore } from "@/store/modules/user";
import StatsAPI, { VisitStatsVO } from "@/api/system/log"; import StatsAPI, { VisitStatsVO } from "@/api/system/log";
import NoticeAPI, { NoticePageVO } from "@/api/system/notice"; import NoticeAPI, { NoticePageVO } from "@/api/system/notice";
interface VisitStats { import { useUserStore } from "@/store/modules/user";
title: string; import { formatGrowthRate } from "@/utils";
icon: string;
tagType: "primary" | "success" | "warning";
growthRate: number;
// 粒度
granularity: string;
// 今日数量
todayCount: number;
totalCount: number;
}
const noticeDetailRef = ref(); const noticeDetailRef = ref();
const notices = ref<NoticePageVO[]>([]);
const userStore = useUserStore(); const userStore = useUserStore();
const date: Date = new Date(); const date: Date = new Date();
const greetings = computed(() => { const greetings = computed(() => {
@@ -184,45 +271,33 @@ const greetings = computed(() => {
} }
}); });
const onlineUserCount = ref(0);
const visitStatsLoading = ref(true); const visitStatsLoading = ref(true);
const visitStatsList = ref<VisitStats[] | null>(Array(3).fill({})); const visitStatsData = ref<VisitStatsVO>({
todayUvCount: 0,
uvGrowthRate: 0,
totalUvCount: 0,
todayPvCount: 0,
pvGrowthRate: 0,
totalPvCount: 0,
});
// 加载访问统计数据 // 加载访问统计数据
const loadVisitStatsData = async () => { const loadVisitStatsData = async () => {
const list: VisitStatsVO[] = await StatsAPI.getVisitStats(); StatsAPI.getVisitStats()
.then((data) => {
if (list) { visitStatsData.value = data;
const tagTypes: ("primary" | "success" | "warning")[] = ["primary", "success", "warning"]; })
const transformedList: VisitStats[] = list.map((item, index) => ({ .finally(() => {
title: item.title, visitStatsLoading.value = false;
icon: getVisitStatsIcon(item.type), });
tagType: tagTypes[index % tagTypes.length],
growthRate: item.growthRate,
granularity: "日",
todayCount: item.todayCount,
totalCount: item.totalCount,
}));
visitStatsList.value = transformedList;
visitStatsLoading.value = false;
}
}; };
// 格式化增长率 // 根据增长率获取样式
const formatGrowthRate = (growthRate: number): string => { const getGrowthRateClass = (growthRate?: number): string => {
if (growthRate === 0) { if (!growthRate) {
return "-"; return "color-[--el-color-info]";
} }
const formattedRate = Math.abs(growthRate * 100)
.toFixed(2)
.replace(/\.?0+$/, "");
return formattedRate + "%";
};
/** 获取增长率文本颜色类 */
const getGrowthRateClass = (growthRate: number): string => {
if (growthRate > 0) { if (growthRate > 0) {
return "color-[--el-color-danger]"; return "color-[--el-color-danger]";
} else if (growthRate < 0) { } else if (growthRate < 0) {
@@ -232,44 +307,25 @@ const getGrowthRateClass = (growthRate: number): string => {
} }
}; };
/** 获取访问统计图标 */ const loadMyNotice = () => {
const getVisitStatsIcon = (type: string) => { NoticeAPI.getMyNoticePage({ pageNum: 1, pageSize: 10 }).then((data) => {
switch (type) { notices.value = data.list;
case "pv": });
return "pv";
case "uv":
return "uv";
case "ip":
return "ip";
default:
return "pv";
}
}; };
const notices = ref<NoticePageVO[]>([]);
// 查看更多 // 查看更多
function viewMoreNotice() { function handleViewMoreNotice() {
router.push({ path: "/myNotice" }); router.push({ path: "/myNotice" });
} }
// 阅读通知公告 // 打开通知公告
function viewNoticeDetail(id: string) { function handleOpenNoticeDetail(id: string) {
noticeDetailRef.value.openNotice(id); noticeDetailRef.value.openNotice(id);
} }
onMounted(() => { onMounted(() => {
loadVisitStatsData(); loadVisitStatsData();
loadMyNotice();
// 获取我的通知公告
NoticeAPI.getMyNoticePage({ pageNum: 1, pageSize: 10 }).then((data) => {
notices.value = data.list;
});
WebSocketManager.subscribeToTopic("/topic/onlineUserCount", (data) => {
console.log("收到在线用户数量:", data);
onlineUserCount.value = JSON.parse(data);
});
}); });
</script> </script>

View File

@@ -1,22 +0,0 @@
<!-- 接口文档 -->
<template>
<div class="app-container">
<iframe src="http://vapi.youlai.tech/doc.html" width="100%" height="100%" frameborder="0" />
</div>
</template>
<style lang="scss" scoped>
/** 关闭tag标签 */
.app-container {
/* 50px = navbar = 50px */
height: calc(100vh - 50px);
}
/** 开启tag标签 */
.hasTagsView {
.app-container {
/* 84px = navbar + tags-view = 50px + 34px */
height: calc(100vh - 84px);
}
}
</style>

View File

@@ -1,27 +0,0 @@
<!-- 接口文档 -->
<template>
<div class="app-container">
<iframe
src="http://vapi.youlai.tech/swagger-ui.html"
width="100%"
height="100%"
frameborder="0"
/>
</div>
</template>
<style lang="scss" scoped>
/** 关闭tag标签 */
.app-container {
/* 50px = navbar = 50px */
height: calc(100vh - 50px);
}
/** 开启tag标签 */
.hasTagsView {
.app-container {
/* 84px = navbar + tags-view = 50px + 34px */
height: calc(100vh - 84px);
}
}
</style>

View File

@@ -1,16 +0,0 @@
<template>
<div>路由参数{{ query }}</div>
</template>
<script setup lang="ts">
defineOptions({
name: "Other",
inheritAttrs: false,
});
import { useRoute } from "vue-router";
// 获取query参数
const query = useRoute().query.type as string;
</script>
<style lang="scss" scoped></style>