|
@@ -3,17 +3,23 @@
|
|
|
<!-- Redis状态概览 -->
|
|
|
<el-row :gutter="15" class="dashboard-row">
|
|
|
<el-col :span="6" class="marg-b-15">
|
|
|
- <el-card shadow="hover" class="status-card memory-card">
|
|
|
- <div class="status-value">{{ sysInfo.memory ? memorySizeFormat(sysInfo.memory.used_memory) : '加载中...' }}</div>
|
|
|
- <div class="status-label">内存使用</div>
|
|
|
- <el-progress
|
|
|
- v-if="sysInfo.memory"
|
|
|
- :percentage="sysInfo.memory.maxmemory && sysInfo.memory.maxmemory > 0 ? parseFloat(((sysInfo.memory.used_memory / sysInfo.memory.maxmemory) * 100).toFixed(1)) : 0"
|
|
|
- :color="memoryColorGetter"
|
|
|
- :stroke-width="8"
|
|
|
- class="memory-progress"
|
|
|
- />
|
|
|
- <div class="status-icon"><i class="el-icon-cpu"></i></div>
|
|
|
+ <el-card shadow="hover" class="status-card uptime-card">
|
|
|
+ <div class="status-value">{{ sysInfo.server ? timeFormat(sysInfo.server.uptime_in_seconds) : '加载中...' }}</div>
|
|
|
+ <div class="status-label">服务运行时间</div>
|
|
|
+ <div class="uptime-info" v-if="sysInfo.server">
|
|
|
+ <span>版本: {{ sysInfo.server.redis_version }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="status-icon"><i class="el-icon-time"></i></div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6" class="marg-b-15">
|
|
|
+ <el-card shadow="hover" class="status-card clients-card">
|
|
|
+ <div class="status-value">{{ sysInfo.clients ? sysInfo.clients.connected_clients : '加载中...' }}</div>
|
|
|
+ <div class="status-label">客户端连接数</div>
|
|
|
+ <div class="clients-info" v-if="sysInfo.clients">
|
|
|
+ <span>阻塞: {{ sysInfo.clients.blocked_clients }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="status-icon"><i class="el-icon-user"></i></div>
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
<el-col :span="6" class="marg-b-15">
|
|
@@ -30,23 +36,17 @@
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
<el-col :span="6" class="marg-b-15">
|
|
|
- <el-card shadow="hover" class="status-card clients-card">
|
|
|
- <div class="status-value">{{ sysInfo.clients ? sysInfo.clients.connected_clients : '加载中...' }}</div>
|
|
|
- <div class="status-label">客户端连接数</div>
|
|
|
- <div class="clients-info" v-if="sysInfo.clients">
|
|
|
- <span>阻塞: {{ sysInfo.clients.blocked_clients }}</span>
|
|
|
- </div>
|
|
|
- <div class="status-icon"><i class="el-icon-user"></i></div>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- <el-col :span="6" class="marg-b-15">
|
|
|
- <el-card shadow="hover" class="status-card uptime-card">
|
|
|
- <div class="status-value">{{ sysInfo.server ? timeFormat(sysInfo.server.uptime_in_seconds) : '加载中...' }}</div>
|
|
|
- <div class="status-label">服务运行时间</div>
|
|
|
- <div class="uptime-info" v-if="sysInfo.server">
|
|
|
- <span>版本: {{ sysInfo.server.redis_version }}</span>
|
|
|
- </div>
|
|
|
- <div class="status-icon"><i class="el-icon-time"></i></div>
|
|
|
+ <el-card shadow="hover" class="status-card memory-card">
|
|
|
+ <div class="status-value">{{ sysInfo.memory ? memorySizeFormat(sysInfo.memory.used_memory) : '加载中...' }}</div>
|
|
|
+ <div class="status-label">内存使用</div>
|
|
|
+ <el-progress
|
|
|
+ v-if="sysInfo.memory"
|
|
|
+ :percentage="sysInfo.memory.maxmemory && sysInfo.memory.maxmemory > 0 ? parseFloat(((sysInfo.memory.used_memory / sysInfo.memory.maxmemory) * 100).toFixed(1)) : 0"
|
|
|
+ :color="memoryColorGetter"
|
|
|
+ :stroke-width="8"
|
|
|
+ class="memory-progress"
|
|
|
+ />
|
|
|
+ <div class="status-icon"><i class="el-icon-cpu"></i></div>
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
@@ -499,7 +499,7 @@ export default defineComponent({
|
|
|
const memoryColorGetter = computed(() => {
|
|
|
if (!state.sysInfo.memory) return '#409EFF';
|
|
|
if (!state.sysInfo.memory.maxmemory || state.sysInfo.memory.maxmemory === 0) return '#409EFF';
|
|
|
-
|
|
|
+
|
|
|
const percentage = (state.sysInfo.memory.used_memory / state.sysInfo.memory.maxmemory) * 100;
|
|
|
if (percentage < 50) return '#67C23A';
|
|
|
if (percentage < 80) return '#E6A23C';
|
|
@@ -508,7 +508,7 @@ export default defineComponent({
|
|
|
|
|
|
onMounted(() => {
|
|
|
initCharts();
|
|
|
-
|
|
|
+
|
|
|
// 每5秒更新一次图表数据
|
|
|
interval = setInterval(() => {
|
|
|
updateMemoryChart();
|
|
@@ -522,11 +522,11 @@ export default defineComponent({
|
|
|
clearInterval(interval);
|
|
|
interval = null;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (es) {
|
|
|
es.close();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
destroyCharts();
|
|
|
});
|
|
|
|
|
@@ -535,17 +535,17 @@ export default defineComponent({
|
|
|
memoryChart.dispose();
|
|
|
memoryChart = null;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (commandsChart) {
|
|
|
commandsChart.dispose();
|
|
|
commandsChart = null;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (commandsTrendChart) {
|
|
|
commandsTrendChart.dispose();
|
|
|
commandsTrendChart = null;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (commandsPieChart) {
|
|
|
commandsPieChart.dispose();
|
|
|
commandsPieChart = null;
|
|
@@ -556,10 +556,10 @@ export default defineComponent({
|
|
|
if (memoryChartRef.value) {
|
|
|
// 判断当前是否为深色模式
|
|
|
const isDarkMode = document.documentElement.classList.contains('dark');
|
|
|
-
|
|
|
+
|
|
|
// 根据深色模式初始化图表
|
|
|
memoryChart = echarts.init(memoryChartRef.value, isDarkMode ? 'dark' : '');
|
|
|
-
|
|
|
+
|
|
|
const option = {
|
|
|
backgroundColor: 'transparent',
|
|
|
grid: {
|
|
@@ -617,7 +617,7 @@ export default defineComponent({
|
|
|
|
|
|
// 判断当前是否为深色模式
|
|
|
const isDarkMode = document.documentElement.classList.contains('dark');
|
|
|
-
|
|
|
+
|
|
|
if (commandsChartRef.value) {
|
|
|
commandsChart = echarts.init(commandsChartRef.value, isDarkMode ? 'dark' : '');
|
|
|
const option = {
|
|
@@ -705,17 +705,17 @@ export default defineComponent({
|
|
|
|
|
|
function updateMemoryChart() {
|
|
|
if (!memoryChart || !state.sysInfo.memory) return;
|
|
|
-
|
|
|
+
|
|
|
const currentTime = getCurrentTime();
|
|
|
state.memoryChartData.times.push(currentTime);
|
|
|
state.memoryChartData.values.push(state.sysInfo.memory.used_memory);
|
|
|
-
|
|
|
+
|
|
|
// 保持最多显示20个数据点
|
|
|
if (state.memoryChartData.times.length > 20) {
|
|
|
state.memoryChartData.times.shift();
|
|
|
state.memoryChartData.values.shift();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
memoryChart.setOption({
|
|
|
xAxis: {
|
|
|
data: state.memoryChartData.times
|
|
@@ -730,32 +730,32 @@ export default defineComponent({
|
|
|
|
|
|
function updateCommandsChart() {
|
|
|
if (!commandsChart || !state.sysInfo.stats) return;
|
|
|
-
|
|
|
+
|
|
|
const currentTime = getCurrentTime();
|
|
|
const currentValue = state.sysInfo.stats.total_commands_processed;
|
|
|
-
|
|
|
+
|
|
|
// 计算增量
|
|
|
let increment = 0;
|
|
|
if (state.commandsChartData.lastValue > 0) {
|
|
|
increment = currentValue - state.commandsChartData.lastValue;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
state.commandsChartData.lastValue = currentValue;
|
|
|
state.commandsChartData.times.push(currentTime);
|
|
|
state.commandsChartData.values.push(increment);
|
|
|
-
|
|
|
+
|
|
|
// 添加到趋势数据
|
|
|
state.commandsChartData.trend.push(increment);
|
|
|
if (state.commandsChartData.trend.length > 5) {
|
|
|
state.commandsChartData.trend.shift();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 保持最多显示20个数据点
|
|
|
if (state.commandsChartData.times.length > 20) {
|
|
|
state.commandsChartData.times.shift();
|
|
|
state.commandsChartData.values.shift();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
commandsChart.setOption({
|
|
|
xAxis: {
|
|
|
data: state.commandsChartData.times
|
|
@@ -766,7 +766,7 @@ export default defineComponent({
|
|
|
}
|
|
|
]
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
// 更新小趋势图
|
|
|
if (commandsTrendChart) {
|
|
|
commandsTrendChart.setOption({
|
|
@@ -781,10 +781,10 @@ export default defineComponent({
|
|
|
|
|
|
function updateCommandsPieChart() {
|
|
|
if (!commandsPieChart || !state.sysInfo.stats) return;
|
|
|
-
|
|
|
+
|
|
|
// 判断当前是否为深色模式
|
|
|
const isDarkMode = document.documentElement.classList.contains('dark');
|
|
|
-
|
|
|
+
|
|
|
// 构建命令统计数据
|
|
|
if (state.sysInfo.stats.commandstats) {
|
|
|
const commandsData = [];
|
|
@@ -798,23 +798,23 @@ export default defineComponent({
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 按调用次数排序并取前10个
|
|
|
commandsData.sort((a, b) => b.value - a.value);
|
|
|
state.topCommands = commandsData.slice(0, 10);
|
|
|
-
|
|
|
+
|
|
|
// 设置默认颜色等配置
|
|
|
const pieColors = [
|
|
|
'#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399',
|
|
|
'#9B5DE5', '#2D69F0', '#44B3C2', '#F15C5C', '#FCBC51'
|
|
|
];
|
|
|
-
|
|
|
+
|
|
|
// 深色模式下使用更亮的颜色
|
|
|
const darkModeColors = [
|
|
|
'#5ea8ff', '#8ece67', '#f0b25e', '#f78989', '#b4b8bf',
|
|
|
'#bb8ef0', '#5c89f5', '#65c6d2', '#f78989', '#ffd780'
|
|
|
];
|
|
|
-
|
|
|
+
|
|
|
commandsPieChart.setOption({
|
|
|
backgroundColor: 'transparent',
|
|
|
color: isDarkMode ? darkModeColors : pieColors,
|
|
@@ -982,18 +982,18 @@ export default defineComponent({
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
margin-top: 10px;
|
|
|
-
|
|
|
+
|
|
|
.trend-value {
|
|
|
color: var(--el-color-success, #67C23A);
|
|
|
font-weight: bold;
|
|
|
margin-right: 10px;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
.trend-chart {
|
|
|
flex: 1;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
.clients-info, .uptime-info {
|
|
|
font-size: 12px;
|
|
|
color: var(--el-text-color-secondary, #909399);
|
|
@@ -1012,7 +1012,7 @@ export default defineComponent({
|
|
|
|
|
|
.chart-card, .data-card {
|
|
|
margin-bottom: 15px;
|
|
|
-
|
|
|
+
|
|
|
.card-header {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
@@ -1034,29 +1034,29 @@ export default defineComponent({
|
|
|
.db-card {
|
|
|
margin-bottom: 15px;
|
|
|
transition: all 0.3s;
|
|
|
-
|
|
|
+
|
|
|
&:hover {
|
|
|
transform: translateY(-3px);
|
|
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
.db-title {
|
|
|
font-size: 16px;
|
|
|
font-weight: bold;
|
|
|
margin-bottom: 15px;
|
|
|
color: var(--el-color-primary, #409EFF);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
.db-info {
|
|
|
.db-item {
|
|
|
margin-bottom: 8px;
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
-
|
|
|
+
|
|
|
.db-label {
|
|
|
color: var(--el-text-color-regular, #606266);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
.db-value {
|
|
|
font-weight: bold;
|
|
|
}
|
|
@@ -1098,7 +1098,7 @@ export default defineComponent({
|
|
|
table {
|
|
|
width: 100%;
|
|
|
border-collapse: collapse;
|
|
|
-
|
|
|
+
|
|
|
td {
|
|
|
padding: 8px;
|
|
|
&:first-child {
|
|
@@ -1109,7 +1109,7 @@ export default defineComponent({
|
|
|
font-weight: 500;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
tr:nth-child(even) {
|
|
|
background-color: var(--el-fill-color-light, #f9f9f9);
|
|
|
}
|