wip: 字典 websocket 实时更新
This commit is contained in:
@@ -23,12 +23,7 @@
|
|||||||
:style="style"
|
:style="style"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
>
|
>
|
||||||
<el-radio
|
<el-radio v-for="option in options" :key="option.value" :value="option.value">
|
||||||
v-for="option in options"
|
|
||||||
:key="option.value"
|
|
||||||
:label="option.label"
|
|
||||||
:value="option.value"
|
|
||||||
>
|
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
@@ -40,12 +35,7 @@
|
|||||||
:style="style"
|
:style="style"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
>
|
>
|
||||||
<el-checkbox
|
<el-checkbox v-for="option in options" :key="option.value" :value="option.value">
|
||||||
v-for="option in options"
|
|
||||||
:key="option.value"
|
|
||||||
:label="option.label"
|
|
||||||
:value="option.value"
|
|
||||||
>
|
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
|
|||||||
@@ -77,20 +77,44 @@ export function useWebSocketDict() {
|
|||||||
try {
|
try {
|
||||||
// 尝试解析消息
|
// 尝试解析消息
|
||||||
const eventData = JSON.parse(message.body) as DictEvent;
|
const eventData = JSON.parse(message.body) as DictEvent;
|
||||||
|
console.log(
|
||||||
|
`[WebSocket] 接收到字典事件: ${eventData.type}, 字典编码: ${eventData.dictCode}`,
|
||||||
|
eventData
|
||||||
|
);
|
||||||
|
|
||||||
if (eventData.type === "DICT_UPDATED") {
|
if (eventData.type === "DICT_UPDATED") {
|
||||||
// 删除缓存,强制重新加载
|
// 删除缓存,强制重新加载
|
||||||
dictStore.removeDictItem(eventData.dictCode);
|
dictStore.removeDictItem(eventData.dictCode);
|
||||||
console.log(`字典 ${eventData.dictCode} 已更新,缓存已清除`);
|
console.log(`[WebSocket] 字典 ${eventData.dictCode} 已更新,缓存已清除`);
|
||||||
ElMessage.success(`字典 ${eventData.dictCode} 已更新`);
|
ElMessage.success(`字典 ${eventData.dictCode} 已更新`);
|
||||||
|
|
||||||
|
// 派发自定义事件,通知组件刷新数据
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent("dict-updated", {
|
||||||
|
detail: {
|
||||||
|
dictCode: eventData.dictCode,
|
||||||
|
timestamp: eventData.timestamp,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
} else if (eventData.type === "DICT_DELETED") {
|
} else if (eventData.type === "DICT_DELETED") {
|
||||||
// 删除缓存
|
// 删除缓存
|
||||||
dictStore.removeDictItem(eventData.dictCode);
|
dictStore.removeDictItem(eventData.dictCode);
|
||||||
console.log(`字典 ${eventData.dictCode} 已删除,缓存已清除`);
|
console.log(`[WebSocket] 字典 ${eventData.dictCode} 已删除,缓存已清除`);
|
||||||
ElMessage.warning(`字典 ${eventData.dictCode} 已删除`);
|
ElMessage.warning(`字典 ${eventData.dictCode} 已删除`);
|
||||||
|
|
||||||
|
// 派发自定义事件,通知组件刷新数据
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent("dict-deleted", {
|
||||||
|
detail: {
|
||||||
|
dictCode: eventData.dictCode,
|
||||||
|
timestamp: eventData.timestamp,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("解析字典WebSocket消息失败:", error);
|
console.error("[WebSocket] 解析字典WebSocket消息失败:", error, message.body);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -210,8 +210,8 @@
|
|||||||
<div class="flex-x-between">
|
<div class="flex-x-between">
|
||||||
<span>访问趋势</span>
|
<span>访问趋势</span>
|
||||||
<el-radio-group v-model="visitTrendDateRange" size="small">
|
<el-radio-group v-model="visitTrendDateRange" size="small">
|
||||||
<el-radio-button label="近7天" :value="7" />
|
<el-radio-button :value="7">近7天</el-radio-button>
|
||||||
<el-radio-button label="近30天" :value="30" />
|
<el-radio-button :value="30">近30天</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -3,124 +3,160 @@
|
|||||||
<el-card class="box-card">
|
<el-card class="box-card">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span>字典WebSocket实时更新演示</span>
|
<span>性别字典WebSocket实时更新演示</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-alert type="info" :closable="false">
|
|
||||||
<p>本示例展示了当字典数据在服务端更新时,如何通过WebSocket实时更新前端缓存。</p>
|
<el-alert type="info" :closable="false" class="mb-4">
|
||||||
<p class="mt-2">
|
本示例展示WebSocket实时更新字典缓存的效果。您可以编辑"男"性别字典项,保存后后端将通过WebSocket通知所有客户端刷新缓存。
|
||||||
当管理员修改字典数据后,其他在线用户的字典缓存将自动刷新,无需手动刷新页面。
|
|
||||||
</p>
|
|
||||||
</el-alert>
|
</el-alert>
|
||||||
|
|
||||||
<div class="mt-4">
|
<el-row :gutter="16">
|
||||||
<el-row :gutter="20">
|
<!-- 列1: 性别字典项编辑 -->
|
||||||
<el-col :span="12">
|
<el-col :span="8">
|
||||||
<el-card shadow="hover">
|
<el-card shadow="hover" class="dict-card">
|
||||||
<template #header>字典选择</template>
|
<template #header>
|
||||||
<div>
|
<div class="flex justify-between items-center">
|
||||||
<el-form>
|
<span>性别字典项 - 男</span>
|
||||||
<el-form-item label="选择字典">
|
<el-button type="warning" size="small" @click="loadMaleDict">重新加载</el-button>
|
||||||
<el-select v-model="selectedDict" placeholder="请选择字典" @change="loadDict">
|
</div>
|
||||||
<el-option
|
</template>
|
||||||
v-for="item in dictList"
|
<div v-loading="formLoading">
|
||||||
:key="item.value"
|
<div v-if="dictForm" class="dict-form">
|
||||||
:label="item.label"
|
<el-form :model="dictForm" label-width="80px">
|
||||||
:value="item.value"
|
<el-form-item label="字典编码">
|
||||||
/>
|
<el-input v-model="dictForm.dictCode" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="字典标签">
|
||||||
|
<el-input v-model="dictForm.label" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="字典值">
|
||||||
|
<el-input v-model="dictForm.value" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="标记颜色">
|
||||||
|
<el-select
|
||||||
|
v-model="dictForm.tagType"
|
||||||
|
placeholder="选择标签类型"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-option value="success" label="success">
|
||||||
|
<el-tag type="success">success</el-tag>
|
||||||
|
</el-option>
|
||||||
|
<el-option value="warning" label="warning">
|
||||||
|
<el-tag type="warning">warning</el-tag>
|
||||||
|
</el-option>
|
||||||
|
<el-option value="danger" label="danger">
|
||||||
|
<el-tag type="danger">danger</el-tag>
|
||||||
|
</el-option>
|
||||||
|
<el-option value="info" label="info">
|
||||||
|
<el-tag type="info">info</el-tag>
|
||||||
|
</el-option>
|
||||||
|
<el-option value="primary" label="primary">
|
||||||
|
<el-tag type="primary">primary</el-tag>
|
||||||
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" :loading="saving" @click="saveDict">保存</el-button>
|
||||||
|
<el-button @click="loadMaleDict">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<el-table v-if="dictItems.length > 0" :data="dictItems" border>
|
|
||||||
<el-table-column prop="label" label="字典标签" />
|
|
||||||
<el-table-column prop="value" label="字典值" />
|
|
||||||
</el-table>
|
|
||||||
<el-empty v-else description="请选择字典类型" />
|
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
<el-empty v-else description="暂无字典数据" />
|
||||||
</el-col>
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12">
|
<!-- 列2: WebSocket消息 -->
|
||||||
<el-card shadow="hover">
|
<el-col :span="8">
|
||||||
<template #header>WebSocket消息</template>
|
<el-card shadow="hover" class="dict-card">
|
||||||
<div class="websocket-log">
|
<template #header>
|
||||||
<div v-if="logMessages.length === 0" class="text-center py-4 text-gray-400">
|
<div class="flex justify-between items-center">
|
||||||
暂无WebSocket消息
|
<span>WebSocket消息</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
</template>
|
||||||
<div
|
<div class="websocket-log">
|
||||||
v-for="(msg, index) in logMessages"
|
<div v-if="logMessages.length === 0" class="text-center py-4 text-gray-400">
|
||||||
:key="index"
|
暂无WebSocket消息
|
||||||
class="log-message"
|
</div>
|
||||||
:class="{
|
<div v-else>
|
||||||
'bg-blue-50': msg.type === 'info',
|
<div
|
||||||
'bg-green-50': msg.type === 'success',
|
v-for="(msg, index) in logMessages"
|
||||||
'bg-red-50': msg.type === 'error',
|
:key="index"
|
||||||
}"
|
class="log-message"
|
||||||
>
|
:class="{
|
||||||
<div class="flex justify-between">
|
'bg-blue-50': msg.type === 'info',
|
||||||
<span class="font-bold">{{ msg.title }}</span>
|
'bg-green-50': msg.type === 'success',
|
||||||
<span class="text-gray-500 text-sm">{{ formatTime(msg.time) }}</span>
|
'bg-red-50': msg.type === 'error',
|
||||||
</div>
|
}"
|
||||||
<pre class="text-sm mt-1">{{ JSON.stringify(msg.data, null, 2) }}</pre>
|
>
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="font-bold">{{ msg.title }}</span>
|
||||||
|
<span class="text-gray-500 text-sm">{{ formatTime(msg.time) }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<pre class="text-sm mt-1">{{ JSON.stringify(msg.data, null, 2) }}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</div>
|
||||||
</el-col>
|
</el-card>
|
||||||
</el-row>
|
</el-col>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
<!-- 列3: 字典缓存数据 -->
|
||||||
<el-card shadow="hover">
|
<el-col :span="8">
|
||||||
<template #header>模拟服务端更新字典</template>
|
<el-card shadow="hover" class="dict-card">
|
||||||
<p>这里模拟后端管理员更新字典数据后发送WebSocket通知</p>
|
<template #header>
|
||||||
<p class="mt-2 mb-4 text-gray-500">注意:这只是前端模拟,实际应用中由后端触发</p>
|
<div class="flex justify-between items-center">
|
||||||
|
<span>字典缓存数据</span>
|
||||||
<el-form :model="simulateForm" label-width="100px" class="demo-form">
|
<div>
|
||||||
<el-form-item label="字典编码">
|
<span class="text-sm text-gray-500">最后更新: {{ lastUpdateTime }}</span>
|
||||||
<el-input v-model="simulateForm.dictCode" />
|
<el-tag v-if="dictCacheStatus" type="success" class="ml-2" size="small">
|
||||||
</el-form-item>
|
已缓存
|
||||||
<el-form-item label="事件类型">
|
</el-tag>
|
||||||
<el-radio-group v-model="simulateForm.eventType">
|
<el-tag v-else type="danger" class="ml-2" size="small">未缓存</el-tag>
|
||||||
<el-radio label="DICT_UPDATED">字典更新</el-radio>
|
</div>
|
||||||
<el-radio label="DICT_DELETED">字典删除</el-radio>
|
</div>
|
||||||
</el-radio-group>
|
</template>
|
||||||
</el-form-item>
|
<div class="cache-content">
|
||||||
<el-form-item>
|
<pre class="cache-data">{{
|
||||||
<el-button type="primary" @click="simulateDictEvent">模拟发送WebSocket消息</el-button>
|
JSON.stringify(dictStore.getDictItems("gender"), null, 2)
|
||||||
<el-button type="danger" @click="clearCache">清空字典缓存</el-button>
|
}}</pre>
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-form>
|
</el-card>
|
||||||
</el-card>
|
</el-col>
|
||||||
</div>
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useDictStoreHook } from "@/store/modules/dict.store";
|
import { useDictStoreHook } from "@/store/modules/dict.store";
|
||||||
import { DictWebSocketEvent } from "@/types/websocket";
|
import { ref, computed, onMounted } from "vue";
|
||||||
import { ref, reactive } from "vue";
|
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { DictItemOption } from "@/api/system/dict.api";
|
|
||||||
import { useDateFormat } from "@vueuse/core";
|
import { useDateFormat } from "@vueuse/core";
|
||||||
import { useWebSocketDict } from "@/hooks/useWebSocketDict";
|
import DictAPI from "@/api/system/dict.api";
|
||||||
|
|
||||||
// 字典列表
|
// 性别字典编码
|
||||||
const dictList = ref([
|
const DICT_CODE = "gender";
|
||||||
{ label: "性别", value: "gender" },
|
// 男性字典项ID
|
||||||
{ label: "状态", value: "status" },
|
const MALE_ITEM_ID = 1;
|
||||||
{ label: "用户类型", value: "user_type" },
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 选中的字典
|
|
||||||
const selectedDict = ref("");
|
|
||||||
// 字典项列表
|
|
||||||
const dictItems = ref<DictItemOption[]>([]);
|
|
||||||
// 字典store
|
// 字典store
|
||||||
const dictStore = useDictStoreHook();
|
const dictStore = useDictStoreHook();
|
||||||
|
// 表单加载状态
|
||||||
|
const formLoading = ref(false);
|
||||||
|
// 保存状态
|
||||||
|
const saving = ref(false);
|
||||||
|
// 最后更新时间
|
||||||
|
const lastUpdateTime = ref("-");
|
||||||
|
// 字典表单数据
|
||||||
|
const dictForm = ref<{
|
||||||
|
id?: number;
|
||||||
|
dictCode: string;
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
tagType?: string;
|
||||||
|
status?: number;
|
||||||
|
} | null>(null);
|
||||||
|
|
||||||
// 日志消息类型
|
// 日志消息类型
|
||||||
interface LogMessage {
|
interface LogMessage {
|
||||||
@@ -130,92 +166,131 @@ interface LogMessage {
|
|||||||
time: Date;
|
time: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 当前选中字典的缓存状态
|
||||||
|
const dictCacheStatus = computed(() => {
|
||||||
|
// 检查字典是否在缓存中
|
||||||
|
return dictStore.getDictItems(DICT_CODE).length > 0;
|
||||||
|
});
|
||||||
|
|
||||||
// WebSocket日志消息
|
// WebSocket日志消息
|
||||||
const logMessages = ref<LogMessage[]>([]);
|
const logMessages = ref<LogMessage[]>([]);
|
||||||
|
|
||||||
// 模拟表单
|
// 加载男性字典表单数据
|
||||||
const simulateForm = reactive({
|
const loadMaleDict = async () => {
|
||||||
dictCode: "",
|
formLoading.value = true;
|
||||||
eventType: "DICT_UPDATED",
|
try {
|
||||||
});
|
// 先确保字典缓存已加载
|
||||||
|
if (!dictCacheStatus.value) {
|
||||||
|
await dictStore.loadDictItems(DICT_CODE);
|
||||||
|
}
|
||||||
|
|
||||||
// 加载字典数据
|
// 获取男性字典项表单数据 - 使用接口 /dicts/gender/items/1/form
|
||||||
const loadDict = async (dictCode: string) => {
|
const data = await DictAPI.getDictItemFormData(DICT_CODE, MALE_ITEM_ID);
|
||||||
await dictStore.loadDictItems(dictCode);
|
|
||||||
dictItems.value = dictStore.getDictItems(dictCode);
|
|
||||||
|
|
||||||
// 添加日志
|
// 调试日志
|
||||||
addLogMessage({
|
console.log("表单数据响应:", data);
|
||||||
title: "加载字典数据",
|
|
||||||
type: "info",
|
if (data) {
|
||||||
data: {
|
dictForm.value = data;
|
||||||
dictCode,
|
// 确保字典值类型为字符串
|
||||||
items: dictItems.value,
|
if (dictForm.value && dictForm.value.value) {
|
||||||
},
|
dictForm.value.value = String(dictForm.value.value);
|
||||||
});
|
}
|
||||||
|
} else {
|
||||||
|
// 创建一个默认的表单数据用于显示
|
||||||
|
dictForm.value = {
|
||||||
|
dictCode: DICT_CODE,
|
||||||
|
label: "男",
|
||||||
|
value: "1",
|
||||||
|
tagType: "primary",
|
||||||
|
status: 1,
|
||||||
|
};
|
||||||
|
ElMessage.warning("未获取到表单数据,已创建默认数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新时间
|
||||||
|
lastUpdateTime.value = useDateFormat(new Date(), "YYYY-MM-DD HH:mm:ss").value;
|
||||||
|
|
||||||
|
// 添加WebSocket连接日志
|
||||||
|
addLogMessage({
|
||||||
|
title: "WebSocket连接成功",
|
||||||
|
type: "success",
|
||||||
|
data: {
|
||||||
|
message: "已与服务器建立WebSocket连接",
|
||||||
|
time: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("加载字典数据失败:", error);
|
||||||
|
ElMessage.error("加载字典数据失败: " + (error.message || "未知错误"));
|
||||||
|
// 创建一个默认的表单数据用于显示
|
||||||
|
dictForm.value = {
|
||||||
|
dictCode: DICT_CODE,
|
||||||
|
label: "男",
|
||||||
|
value: "1",
|
||||||
|
tagType: "primary",
|
||||||
|
status: 1,
|
||||||
|
};
|
||||||
|
ElMessage.warning("加载失败,已创建默认数据");
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 模拟字典事件
|
// 保存字典项
|
||||||
const simulateDictEvent = () => {
|
const saveDict = async () => {
|
||||||
const { dictCode, eventType } = simulateForm;
|
if (!dictForm.value) return;
|
||||||
|
|
||||||
if (!dictCode) {
|
saving.value = true;
|
||||||
ElMessage.warning("请输入字典编码");
|
try {
|
||||||
return;
|
// 调用API保存
|
||||||
}
|
await DictAPI.updateDictItem(DICT_CODE, MALE_ITEM_ID, dictForm.value);
|
||||||
|
|
||||||
// 构造字典事件
|
// 清除缓存
|
||||||
const event: DictWebSocketEvent = {
|
dictStore.removeDictItem(DICT_CODE);
|
||||||
type: eventType as "DICT_UPDATED" | "DICT_DELETED",
|
|
||||||
dictCode,
|
|
||||||
timestamp: Date.now(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// 添加日志
|
// 更新时间
|
||||||
addLogMessage({
|
lastUpdateTime.value = useDateFormat(new Date(), "YYYY-MM-DD HH:mm:ss").value;
|
||||||
title: "模拟WebSocket消息",
|
|
||||||
type: "success",
|
|
||||||
data: event,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 导入WebSocket字典钩子
|
// 添加WebSocket消息推送日志
|
||||||
const { handleDictEvent } = useWebSocketDict();
|
addLogMessage({
|
||||||
|
title: "接收到WebSocket消息",
|
||||||
// 手动调用处理函数,模拟收到WebSocket消息
|
type: "info",
|
||||||
handleDictEvent(event);
|
data: {
|
||||||
|
type: "DICT_UPDATED",
|
||||||
// 如果是当前选中的字典被更新,则刷新显示
|
dictCode: DICT_CODE,
|
||||||
if (selectedDict.value === dictCode) {
|
item: {
|
||||||
setTimeout(() => {
|
id: MALE_ITEM_ID,
|
||||||
dictItems.value = dictStore.getDictItems(dictCode);
|
label: dictForm.value.label,
|
||||||
|
value: dictForm.value.value,
|
||||||
addLogMessage({
|
|
||||||
title: "字典数据已更新",
|
|
||||||
type: "info",
|
|
||||||
data: {
|
|
||||||
dictCode,
|
|
||||||
items: dictItems.value,
|
|
||||||
},
|
},
|
||||||
});
|
timestamp: Date.now(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
ElMessage.success("保存成功,后端已触发WebSocket通知");
|
||||||
|
|
||||||
|
// 重新加载字典数据以显示最新缓存
|
||||||
|
setTimeout(() => {
|
||||||
|
dictStore.loadDictItems(DICT_CODE);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("保存字典项失败:", error);
|
||||||
|
ElMessage.error("保存失败: " + (error.message || "未知错误"));
|
||||||
|
|
||||||
|
addLogMessage({
|
||||||
|
title: "保存字典项失败",
|
||||||
|
type: "error",
|
||||||
|
data: {
|
||||||
|
dictCode: DICT_CODE,
|
||||||
|
error: error.message || "未知错误",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
saving.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 清空字典缓存
|
|
||||||
const clearCache = () => {
|
|
||||||
dictStore.clearDictCache();
|
|
||||||
dictItems.value = [];
|
|
||||||
selectedDict.value = "";
|
|
||||||
|
|
||||||
addLogMessage({
|
|
||||||
title: "字典缓存已清空",
|
|
||||||
type: "error",
|
|
||||||
data: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
ElMessage.success("字典缓存已清空");
|
|
||||||
};
|
|
||||||
|
|
||||||
// 添加日志消息
|
// 添加日志消息
|
||||||
const addLogMessage = (message: { title: string; type: string; data: any }) => {
|
const addLogMessage = (message: { title: string; type: string; data: any }) => {
|
||||||
logMessages.value.unshift({
|
logMessages.value.unshift({
|
||||||
@@ -233,11 +308,28 @@ const addLogMessage = (message: { title: string; type: string; data: any }) => {
|
|||||||
const formatTime = (date: Date) => {
|
const formatTime = (date: Date) => {
|
||||||
return useDateFormat(date, "HH:mm:ss").value;
|
return useDateFormat(date, "HH:mm:ss").value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 组件挂载时加载性别字典
|
||||||
|
onMounted(() => {
|
||||||
|
loadMaleDict();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.dict-card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 600px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-card :deep(.el-card__body) {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.websocket-log {
|
.websocket-log {
|
||||||
max-height: 400px;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,8 +344,30 @@ const formatTime = (date: Date) => {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cache-content {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
|
padding: 8px;
|
||||||
|
overflow-y: auto;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cache-data {
|
||||||
|
height: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
overflow-y: auto;
|
||||||
|
font-size: 12px;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dict-form {
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user