|
@@ -58,19 +58,187 @@
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
+ <el-row class="mt-3">
|
|
|
+ <el-col :span="24" class="card-box" shadow="hover">
|
|
|
+ <el-card>
|
|
|
+ <el-table v-loading="keyListLoad" :data="keyList" row-key="id" @row-click="openKeyTemplate">
|
|
|
+ <el-table-column prop="keyTemplate" label="Key 模板" width="200" />
|
|
|
+ <el-table-column prop="keyType" label="Key 类型" width="100" />
|
|
|
+ <el-table-column prop="valueType" label="Value 类型" />
|
|
|
+ <el-table-column prop="timeoutType" label="超时时间" width="200">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <DictTag :type="DICT_TYPE.INFRA_REDIS_TIMEOUT_TYPE" :value="row?.timeoutType" />
|
|
|
+ <span v-if="row?.timeout > 0">({{ row?.timeout / 1000 }} 秒)</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="memo" label="备注" />
|
|
|
+ </el-table>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
</el-scrollbar>
|
|
|
+ <XModal v-model="dialogVisible" :title="keyTemplate + ' 模板'">
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="14" class="mt-3">
|
|
|
+ <el-card shadow="always">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>键名列表</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <el-table :data="cacheKeys" style="width: 100%" @row-click="handleKeyValue">
|
|
|
+ <el-table-column label="缓存键名" align="center" :show-overflow-tooltip="true">
|
|
|
+ <template #default="{ row }">
|
|
|
+ {{ row }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" align="right" width="60">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <XTextButton preIcon="ep:delete" @click="handleDeleteKey(row)" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="10" class="mt-3">
|
|
|
+ <el-card shadow="always">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>缓存内容</span>
|
|
|
+ <XTextButton preIcon="ep:refresh" title="清理全部" @click="handleDeleteKeys(keyTemplate)"
|
|
|
+ class="float-right p-1" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <el-descriptions :column="1">
|
|
|
+ <el-descriptions-item label="缓存键名:">{{ cacheForm.key }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="缓存内容:">{{ cacheForm.value }}</el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </XModal>
|
|
|
</template>
|
|
|
<script setup lang="ts">
|
|
|
+// import * as echarts from 'echarts'
|
|
|
import * as RedisApi from '@/api/infra/redis'
|
|
|
-import { RedisMonitorInfoVO } from '@/api/infra/redis/types'
|
|
|
+import { RedisKeyInfo, RedisMonitorInfoVO } from '@/api/infra/redis/types'
|
|
|
+import { DICT_TYPE } from '@/utils/dict'
|
|
|
+const { t } = useI18n() // 国际化
|
|
|
+const message = useMessage() // 消息弹窗
|
|
|
+const keyListLoad = ref(true)
|
|
|
+const keyList = ref<RedisKeyInfo[]>([])
|
|
|
const cache = ref<RedisMonitorInfoVO>()
|
|
|
-
|
|
|
// 基本信息
|
|
|
const readRedisInfo = async () => {
|
|
|
const data = await RedisApi.getCacheApi()
|
|
|
cache.value = data
|
|
|
+ // loadEchartOptions(data.commandStats)
|
|
|
+ const redisKeysInfo = await RedisApi.getKeyDefineListApi()
|
|
|
+ keyList.value = redisKeysInfo
|
|
|
+ keyListLoad.value = false //加载完成
|
|
|
}
|
|
|
+// 图表
|
|
|
+// const commandStatsRef = ref<HTMLElement>()
|
|
|
+// const usedmemory = ref<HTMLDivElement>()
|
|
|
+// const loadEchartOptions = (stats) => {
|
|
|
+// const commandStats = [] as any[]
|
|
|
+// const nameList = [] as string[]
|
|
|
+// stats.forEach((row) => {
|
|
|
+// commandStats.push({
|
|
|
+// name: row.command,
|
|
|
+// value: row.calls
|
|
|
+// })
|
|
|
+// nameList.push(row.command)
|
|
|
+// })
|
|
|
+
|
|
|
+// const commandStatsInstance = echarts.init(commandStatsRef.value!, 'macarons')
|
|
|
|
|
|
+// commandStatsInstance.setOption({
|
|
|
+// title: {
|
|
|
+// text: '命令统计',
|
|
|
+// left: 'center'
|
|
|
+// },
|
|
|
+// tooltip: {
|
|
|
+// trigger: 'item',
|
|
|
+// formatter: '{a} <br/>{b} : {c} ({d}%)'
|
|
|
+// },
|
|
|
+// legend: {
|
|
|
+// type: 'scroll',
|
|
|
+// orient: 'vertical',
|
|
|
+// right: 30,
|
|
|
+// top: 10,
|
|
|
+// bottom: 20,
|
|
|
+// data: nameList,
|
|
|
+// textStyle: {
|
|
|
+// color: '#a1a1a1'
|
|
|
+// }
|
|
|
+// },
|
|
|
+// series: [
|
|
|
+// {
|
|
|
+// name: '命令',
|
|
|
+// type: 'pie',
|
|
|
+// radius: [20, 120],
|
|
|
+// center: ['40%', '60%'],
|
|
|
+// data: commandStats,
|
|
|
+// roseType: 'radius',
|
|
|
+// label: {
|
|
|
+// show: true
|
|
|
+// },
|
|
|
+// emphasis: {
|
|
|
+// label: {
|
|
|
+// show: true
|
|
|
+// },
|
|
|
+// itemStyle: {
|
|
|
+// shadowBlur: 10,
|
|
|
+// shadowOffsetX: 0,
|
|
|
+// shadowColor: 'rgba(0, 0, 0, 0.5)'
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// ]
|
|
|
+// })
|
|
|
+
|
|
|
+// const usedMemoryInstance = echarts.init(usedmemory.value!, 'macarons')
|
|
|
+// usedMemoryInstance.setOption({
|
|
|
+// title: {
|
|
|
+// text: '内存使用情况',
|
|
|
+// left: 'center'
|
|
|
+// },
|
|
|
+// tooltip: {
|
|
|
+// formatter: '{b} <br/>{a} : ' + cache.value!.info.used_memory_human
|
|
|
+// },
|
|
|
+// series: [
|
|
|
+// {
|
|
|
+// name: '峰值',
|
|
|
+// type: 'gauge',
|
|
|
+// min: 0,
|
|
|
+// max: 100,
|
|
|
+// progress: {
|
|
|
+// show: true
|
|
|
+// },
|
|
|
+// detail: {
|
|
|
+// formatter: cache.value!.info.used_memory_human
|
|
|
+// },
|
|
|
+// data: [
|
|
|
+// {
|
|
|
+// value: parseFloat(cache.value!.info.used_memory_human),
|
|
|
+// name: '内存消耗'
|
|
|
+// }
|
|
|
+// ]
|
|
|
+// }
|
|
|
+// ]
|
|
|
+// })
|
|
|
+// }
|
|
|
+const dialogVisible = ref(false)
|
|
|
+const keyTemplate = ref('')
|
|
|
+const cacheKeys = ref()
|
|
|
+const cacheForm = ref<{
|
|
|
+ key: string
|
|
|
+ value: string
|
|
|
+}>({
|
|
|
+ key: '',
|
|
|
+ value: ''
|
|
|
+})
|
|
|
// 内存使用情况
|
|
|
const usedmemoryEchartChika = reactive<any>({
|
|
|
title: {
|
|
@@ -230,7 +398,7 @@ const initCommandStatsChart = async () => {
|
|
|
})
|
|
|
commandStatsRefChika.legend.data = nameList
|
|
|
commandStatsRefChika.series[0].data = commandStats
|
|
|
- } catch {}
|
|
|
+ } catch { }
|
|
|
}
|
|
|
const usedMemoryInstance = async () => {
|
|
|
try {
|
|
@@ -253,7 +421,7 @@ const usedMemoryInstance = async () => {
|
|
|
usedmemoryEchartChika.tooltip = {
|
|
|
formatter: '{b} <br/>{a} : ' + cache.value!.info.used_memory_human
|
|
|
}
|
|
|
- } catch {}
|
|
|
+ } catch { }
|
|
|
}
|
|
|
|
|
|
/** 初始化 **/
|
|
@@ -263,4 +431,24 @@ onMounted(() => {
|
|
|
// 加载数据
|
|
|
getSummary()
|
|
|
})
|
|
|
+const openKeyTemplate = async (row: RedisKeyInfo) => {
|
|
|
+ keyTemplate.value = row.keyTemplate
|
|
|
+ cacheKeys.value = await RedisApi.getKeyListApi(row.keyTemplate)
|
|
|
+ dialogVisible.value = true
|
|
|
+}
|
|
|
+const handleDeleteKey = async (row) => {
|
|
|
+ RedisApi.deleteKeyApi(row)
|
|
|
+ message.success(t('common.delSuccess'))
|
|
|
+}
|
|
|
+const handleDeleteKeys = async (row) => {
|
|
|
+ RedisApi.deleteKeysApi(row)
|
|
|
+ message.success(t('common.delSuccess'))
|
|
|
+}
|
|
|
+const handleKeyValue = async (row) => {
|
|
|
+ const res = await RedisApi.getKeyValueApi(row)
|
|
|
+ cacheForm.value = res
|
|
|
+}
|
|
|
+onBeforeMount(() => {
|
|
|
+ readRedisInfo()
|
|
|
+})
|
|
|
</script>
|