fix: 修复提交冲突引发的问题

This commit is contained in:
Ray.Hao
2026-03-24 08:18:40 +08:00
parent 4eea3ed6cb
commit dd52225378
25 changed files with 573 additions and 1199 deletions

View File

@@ -130,25 +130,19 @@
<template #header>
<div class="flex-x-between">
<span class="text-xs font-medium text-[--el-text-color-secondary]">在线用户</span>
<div class="flex items-center gap-2">
<span
class="inline-flex items-center gap-1.5 px-2.5 py-0.5 text-xs leading-5 rounded-full border select-none"
:class="wsStatusClass"
>
<el-icon class="text-sm">
<Loading
v-if="
!isConnected &&
(connectionState === 'CONNECTING' || connectionState === 'RECONNECTING')
"
/>
<CircleCheck v-else-if="isConnected" />
<CircleClose v-else />
</el-icon>
<span class="text-[--el-text-color-secondary]">WebSocket</span>
<span class="font-medium">{{ wsStatusText }}</span>
</span>
</div>
<el-tag
:type="
isConnected ? 'success' : connectionState === 'CONNECTING' ? 'warning' : 'danger'
"
size="small"
>
<el-icon class="mr-1">
<Loading v-if="!isConnected && connectionState === 'CONNECTING'" />
<CircleCheck v-else-if="isConnected" />
<CircleClose v-else />
</el-icon>
SSE {{ sseStatusText }}
</el-tag>
</div>
</template>
@@ -391,7 +385,7 @@ defineOptions({
import { dayjs } from "element-plus";
import { ref } from "vue";
import { useRouter } from "vue-router";
import StatisticsAPI from "@/api/system/statistics";
import LogAPI from "@/api/system/log";
import type { VisitStatsDetail, VisitTrendDetail } from "@/types/api";
import { useUserStore } from "@/store/modules/user";
import { formatGrowthRate } from "@/utils";
@@ -413,23 +407,13 @@ const formattedTime = computed(() => {
return useDateFormat(lastUpdateTime, "HH:mm:ss").value;
});
const wsStatusText = computed(() => {
const sseStatusText = computed(() => {
if (!isConnected.value) {
return connectionState.value === "CONNECTING" || connectionState.value === "RECONNECTING"
? "连接中"
: "未连接";
return connectionState.value === "CONNECTING" ? "连接中" : "未连接";
}
return "已连接";
});
const wsStatusClass = computed(() => {
if (isConnected.value)
return "text-[--el-color-success] bg-[--el-color-success-light-9] border-[--el-color-success-light-7]";
return connectionState.value === "CONNECTING" || connectionState.value === "RECONNECTING"
? "text-[--el-color-warning] bg-[--el-color-warning-light-9] border-[--el-color-warning-light-7]"
: "text-[--el-color-danger] bg-[--el-color-danger-light-9] border-[--el-color-danger-light-7]";
});
const userStore = useUserStore();
// 当前时间(用于计算问候语)
@@ -540,7 +524,7 @@ const visitTrendChartOptions = ref();
* 获取访客统计数据
*/
const fetchVisitStatsData = () => {
StatisticsAPI.getVisitOverview()
LogAPI.getVisitOverview()
.then((data) => {
visitStatsData.value = data;
})
@@ -558,7 +542,7 @@ const fetchVisitTrendData = () => {
.toDate();
const endDate = new Date();
StatisticsAPI.getVisitTrend({
LogAPI.getVisitTrend({
startDate: dayjs(startDate).format("YYYY-MM-DD"),
endDate: dayjs(endDate).format("YYYY-MM-DD"),
}).then((data) => {

View File

@@ -3,15 +3,16 @@
<el-card class="box-card">
<template #header>
<div class="card-header">
<span>字典WebSocket实时更新演示</span>
<el-tag :type="wsConnected ? 'success' : 'danger'" size="small" class="ml-2">
WebSocket {{ wsStatusText }}
<span>字典 SSE 实时更新演示</span>
<el-tag :type="sseConnected ? 'success' : 'danger'" size="small" class="ml-2">
SSE {{ sseStatusText }}
</el-tag>
</div>
</template>
<el-alert type="info" :closable="false" class="mb-4">
本示例展示WebSocket实时更新字典缓存的效果您可以编辑"男"性别字典项保存后后端将通过WebSocket通知所有客户端刷新缓存
本示例展示 SSE 实时更新字典缓存的效果您可以编辑"男"性别字典项保存后后端将通过 SSE
通知所有客户端刷新缓存
</el-alert>
<el-row :gutter="16">
@@ -161,16 +162,16 @@ const dictForm = ref<DictItemForm | null>(null);
// 选中的性别
const selectedGender = ref("");
// 初始化WebSocket
const dictWebSocket = useDictSync();
// 初始化 SSE
const dictSse = useDictSync();
// 获取连接状态
const wsConnected = computed(() => dictWebSocket.isConnected);
const sseConnected = computed(() => dictSse.isConnected.value);
// WebSocket连接状态显示文本
const wsStatusText = computed(() => (wsConnected.value ? "已连接" : "未连接"));
// SSE 连接状态显示文本
const sseStatusText = computed(() => (sseConnected.value ? "已连接" : "未连接"));
// 保存WebSocket清理函数
// 保存 SSE 清理函数
let unregisterCallback: (() => void) | null = null;
// 当前选中字典的缓存状态
@@ -179,13 +180,13 @@ const dictCacheStatus = computed(() => {
return dictStore.getDictItems(DICT_CODE).length > 0;
});
// 设置WebSocket
const setupWebSocket = () => {
// 初始化WebSocket连接
dictWebSocket.initialize();
// 设置 SSE
const setupSse = () => {
// 初始化 SSE 连接
dictSse.initialize();
// 注册字典消息回调
unregisterCallback = dictWebSocket.onDictChange((message: DictMessage) => {
unregisterCallback = dictSse.onDictChange((message: DictMessage) => {
// 只有当消息是关于性别字典的更新时才处理
if (message.dictCode === DICT_CODE) {
// 更新最后更新时间
@@ -224,7 +225,7 @@ const saveDict = async () => {
// 更新时间
lastUpdateTime.value = useDateFormat(new Date(), "YYYY-MM-DD HH:mm:ss").value;
ElMessage.success("保存成功,后端将通过WebSocket通知所有客户端");
ElMessage.success("保存成功,后端将通过 SSE 通知所有客户端");
saving.value = false;
};
@@ -235,11 +236,11 @@ onMounted(async () => {
await dictStore.loadDictItems(DICT_CODE);
// 初始化选中性别为男
selectedGender.value = "1";
// 设置WebSocket
setupWebSocket();
// 设置 SSE
setupSse();
});
// 组件卸载时清理WebSocket
// 组件卸载时清理 SSE
onUnmounted(() => {
unregisterCallback?.();
});