diff --git a/src/components/ECharts/index.vue b/src/components/ECharts/index.vue
new file mode 100644
index 00000000..f4afa719
--- /dev/null
+++ b/src/components/ECharts/index.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
diff --git a/src/types/components.d.ts b/src/types/components.d.ts
index a0d61654..d9ef9c47 100644
--- a/src/types/components.d.ts
+++ b/src/types/components.d.ts
@@ -13,6 +13,7 @@ declare module "vue" {
CURD: (typeof import("./../components/CURD/index.vue"))["default"];
Dict: (typeof import("./../components/Dict/index.vue"))["default"];
DictLabel: (typeof import("./../components/Dict/DictLabel.vue"))["default"];
+ ECharts: (typeof import("./../components/ECharts/index.vue"))["default"];
ElBacktop: (typeof import("element-plus/es"))["ElBacktop"];
ElBreadcrumb: (typeof import("element-plus/es"))["ElBreadcrumb"];
ElBreadcrumbItem: (typeof import("element-plus/es"))["ElBreadcrumbItem"];
diff --git a/src/views/dashboard/components/visit-trend.vue b/src/views/dashboard/components/visit-trend.vue
deleted file mode 100644
index b2ac7bad..00000000
--- a/src/views/dashboard/components/visit-trend.vue
+++ /dev/null
@@ -1,199 +0,0 @@
-
-
-
-
-
-
- 访问趋势
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue
index f2621f78..f784e3e2 100644
--- a/src/views/dashboard/index.vue
+++ b/src/views/dashboard/index.vue
@@ -8,7 +8,7 @@
@@ -116,7 +116,11 @@
{{ visitStatsData.todayUvCount }}
@@ -172,7 +176,11 @@
{{ visitStatsData.todayPvCount }}
@@ -197,7 +205,18 @@
-
+
+
+
+ 访问趋势
+
+
+
+
+
+
+
+
@@ -206,7 +225,7 @@
@@ -218,7 +237,7 @@
{{ item.title }}
-
+
@@ -236,38 +255,44 @@ defineOptions({
name: "Dashboard",
inheritAttrs: false,
});
-import VisitTrend from "./components/visit-trend.vue";
+import { dayjs } from "element-plus";
import router from "@/router";
-
-import LogAPI, { VisitStatsVO } from "@/api/system/log";
+import LogAPI, { VisitStatsVO, VisitTrendVO } from "@/api/system/log";
import NoticeAPI, { NoticePageVO } from "@/api/system/notice";
-
import { useUserStore } from "@/store/modules/user";
import { formatGrowthRate } from "@/utils";
+const userStore = useUserStore();
+
const noticeDetailRef = ref();
+// 当前通知公告列表
const notices = ref([]);
-const userStore = useUserStore();
-const date: Date = new Date();
+// 当前时间(用于计算问候语)
+const currentDate = new Date();
+
+// 问候语:根据当前小时返回不同问候语
const greetings = computed(() => {
- const hours = date.getHours();
+ const hours = currentDate.getHours();
+ const nickname = userStore.userInfo.nickname;
if (hours >= 6 && hours < 8) {
return "晨起披衣出草堂,轩窗已自喜微凉🌅!";
} else if (hours >= 8 && hours < 12) {
- return "上午好," + userStore.userInfo.nickname + "!";
+ return `上午好,${nickname}!`;
} else if (hours >= 12 && hours < 18) {
- return "下午好," + userStore.userInfo.nickname + "!";
+ return `下午好,${nickname}!`;
} else if (hours >= 18 && hours < 24) {
- return "晚上好," + userStore.userInfo.nickname + "!";
+ return `晚上好,${nickname}!`;
} else {
return "偷偷向银河要了一把碎星,只等你闭上眼睛撒入你的梦中,晚安🌛!";
}
});
+// 访客统计数据加载状态
const visitStatsLoading = ref(true);
+// 访客统计数据
const visitStatsData = ref({
todayUvCount: 0,
uvGrowthRate: 0,
@@ -277,8 +302,15 @@ const visitStatsData = ref({
totalPvCount: 0,
});
-// 加载访问统计数据
-const loadVisitStatsData = async () => {
+// 访问趋势日期范围(单位:天)
+const visitTrendDateRange = ref(7);
+// 访问趋势图表配置
+const visitTrendChartOptions = ref();
+
+/**
+ * 获取访客统计数据
+ */
+const fetchVisitStatsData = () => {
LogAPI.getVisitStats()
.then((data) => {
visitStatsData.value = data;
@@ -288,12 +320,102 @@ const loadVisitStatsData = async () => {
});
};
-// 根据增长率获取样式
-const getGrowthRateClass = (growthRate?: number): string => {
+/**
+ * 获取访问趋势数据,并更新图表配置
+ */
+const fetchVisitTrendData = () => {
+ const startDate = dayjs()
+ .subtract(visitTrendDateRange.value - 1, "day")
+ .toDate();
+ const endDate = new Date();
+
+ LogAPI.getVisitTrend({
+ startDate: dayjs(startDate).format("YYYY-MM-DD"),
+ endDate: dayjs(endDate).format("YYYY-MM-DD"),
+ }).then((data) => {
+ updateVisitTrendChartOptions(data);
+ });
+};
+
+/**
+ * 更新访问趋势图表的配置项
+ *
+ * @param data - 访问趋势数据
+ */
+const updateVisitTrendChartOptions = (data: VisitTrendVO) => {
+ console.log("Updating visit trend chart options");
+
+ visitTrendChartOptions.value = {
+ tooltip: {
+ trigger: "axis",
+ },
+ legend: {
+ data: ["浏览量(PV)", "访客数(UV)"],
+ bottom: 0,
+ },
+ grid: {
+ left: "1%",
+ right: "5%",
+ bottom: "10%",
+ containLabel: true,
+ },
+ xAxis: {
+ type: "category",
+ data: data.dates,
+ },
+ yAxis: {
+ type: "value",
+ splitLine: {
+ show: true,
+ lineStyle: {
+ type: "dashed",
+ },
+ },
+ },
+ series: [
+ {
+ name: "浏览量(PV)",
+ type: "line",
+ data: data.pvList,
+ areaStyle: {
+ color: "rgba(64, 158, 255, 0.1)",
+ },
+ smooth: true,
+ itemStyle: {
+ color: "#4080FF",
+ },
+ lineStyle: {
+ color: "#4080FF",
+ },
+ },
+ {
+ name: "访客数(UV)",
+ type: "line",
+ data: data.ipList,
+ areaStyle: {
+ color: "rgba(103, 194, 58, 0.1)",
+ },
+ smooth: true,
+ itemStyle: {
+ color: "#67C23A",
+ },
+ lineStyle: {
+ color: "#67C23A",
+ },
+ },
+ ],
+ };
+};
+
+/**
+ * 根据增长率计算对应的 CSS 类名
+ *
+ * @param growthRate - 增长率数值
+ */
+const computeGrowthRateClass = (growthRate?: number): string => {
if (!growthRate) {
return "color-[--el-color-info]";
}
-
if (growthRate > 0) {
return "color-[--el-color-danger]";
} else if (growthRate < 0) {
@@ -303,25 +425,45 @@ const getGrowthRateClass = (growthRate?: number): string => {
}
};
-const loadMyNotice = () => {
+/**
+ * 获取当前用户的通知公告数据
+ */
+const fetchMyNotices = () => {
NoticeAPI.getMyNoticePage({ pageNum: 1, pageSize: 10 }).then((data) => {
notices.value = data.list;
});
};
-// 查看更多
-function handleViewMoreNotice() {
+/**
+ * 跳转至通知公告详情页面(查看更多通知)
+ */
+function navigateToNoticePage() {
router.push({ path: "/myNotice" });
}
-// 打开通知公告
-function handleOpenNoticeDetail(id: string) {
+/**
+ * 打开指定通知详情
+ *
+ * @param id - 通知 ID
+ */
+function openNoticeDetail(id: string) {
noticeDetailRef.value.openNotice(id);
}
+// 监听访问趋势日期范围的变化,重新获取趋势数据
+watch(
+ () => visitTrendDateRange.value,
+ (newVal) => {
+ console.log("Visit trend date range changed:", newVal);
+ fetchVisitTrendData();
+ },
+ { immediate: true }
+);
+
+// 组件挂载后加载访客统计数据和通知公告数据
onMounted(() => {
- loadVisitStatsData();
- loadMyNotice();
+ fetchVisitStatsData();
+ fetchMyNotices();
});