2021-07-28 18:03:19 +08:00
|
|
|
<template>
|
|
|
|
|
<div>
|
2021-12-21 03:06:29 +00:00
|
|
|
<el-card>
|
2021-07-28 18:03:19 +08:00
|
|
|
<div style="float: left">
|
|
|
|
|
<el-row type="flex" justify="space-between">
|
|
|
|
|
<el-col :span="24">
|
|
|
|
|
<project-env-select @changeProjectEnv="changeProjectEnv" @clear="clearRedis">
|
|
|
|
|
<template #default>
|
|
|
|
|
<el-form-item label="redis" label-width="40px">
|
|
|
|
|
<el-select v-model="scanParam.id" placeholder="请选择redis" @change="changeRedis" @clear="clearRedis" clearable>
|
|
|
|
|
<el-option v-for="item in redisList" :key="item.id" :label="item.host" :value="item.id">
|
|
|
|
|
<span style="float: left">{{ item.host }}</span>
|
|
|
|
|
<span style="float: right; color: #8492a6; margin-left: 6px; font-size: 13px">{{
|
|
|
|
|
`库: [${item.db}]`
|
|
|
|
|
}}</span>
|
|
|
|
|
</el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
</project-env-select>
|
|
|
|
|
</el-col>
|
2022-01-12 16:00:31 +08:00
|
|
|
<el-col class="mt10">
|
|
|
|
|
<el-form class="search-form" label-position="right" :inline="true" label-width="60px">
|
|
|
|
|
<el-form-item label="key" label-width="40px">
|
|
|
|
|
<el-input
|
|
|
|
|
placeholder="支持*模糊key"
|
|
|
|
|
style="width: 180px"
|
|
|
|
|
v-model="scanParam.match"
|
|
|
|
|
@clear="clear()"
|
|
|
|
|
clearable
|
|
|
|
|
></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="count" label-width="60px">
|
|
|
|
|
<el-input placeholder="count" style="width: 62px" v-model="scanParam.count"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button @click="searchKey()" type="success" icon="search" plain></el-button>
|
|
|
|
|
<el-button @click="scan()" icon="bottom" plain>scan</el-button>
|
|
|
|
|
<el-button type="primary" icon="plus" @click="onAddData(false)" plain></el-button>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<div style="float: right">
|
|
|
|
|
<span>keys: {{ dbsize }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</el-form>
|
|
|
|
|
</el-col>
|
2021-07-28 18:03:19 +08:00
|
|
|
</el-row>
|
|
|
|
|
</div>
|
2022-01-12 16:00:31 +08:00
|
|
|
|
2021-12-21 03:06:29 +00:00
|
|
|
<el-table v-loading="loading" :data="keys" stripe :highlight-current-row="true" style="cursor: pointer">
|
|
|
|
|
<el-table-column show-overflow-tooltip prop="key" label="key"></el-table-column>
|
|
|
|
|
<el-table-column prop="type" label="type" width="80"> </el-table-column>
|
2022-01-21 11:28:55 +08:00
|
|
|
<el-table-column prop="ttl" label="ttl(过期时间)" width="130">
|
2021-12-21 03:06:29 +00:00
|
|
|
<template #default="scope">
|
|
|
|
|
{{ ttlConveter(scope.row.ttl) }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="操作">
|
|
|
|
|
<template #default="scope">
|
2022-01-12 16:00:31 +08:00
|
|
|
<el-button @click="getValue(scope.row)" type="success" icon="search" plain size="small">查看</el-button>
|
|
|
|
|
<el-button @click="del(scope.row.key)" type="danger" icon="delete" plain size="small">删除</el-button>
|
2021-12-21 03:06:29 +00:00
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
</el-card>
|
|
|
|
|
|
2021-07-28 18:03:19 +08:00
|
|
|
<div style="text-align: center; margin-top: 10px"></div>
|
|
|
|
|
|
2022-01-12 16:00:31 +08:00
|
|
|
<!-- <value-dialog v-model:visible="valueDialog.visible" :keyValue="valueDialog.value" /> -->
|
|
|
|
|
|
|
|
|
|
<data-edit
|
|
|
|
|
v-model:visible="dataEdit.visible"
|
|
|
|
|
:title="dataEdit.title"
|
|
|
|
|
:keyInfo="dataEdit.keyInfo"
|
|
|
|
|
:redisId="scanParam.id"
|
|
|
|
|
:operationType="dataEdit.operationType"
|
|
|
|
|
:stringValue="dataEdit.stringValue"
|
|
|
|
|
:setValue="dataEdit.setValue"
|
|
|
|
|
:hashValue="dataEdit.hashValue"
|
|
|
|
|
@valChange="searchKey"
|
|
|
|
|
@cancel="onCancelDataEdit"
|
|
|
|
|
/>
|
2021-07-28 18:03:19 +08:00
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
|
import ValueDialog from './ValueDialog.vue';
|
|
|
|
|
import { redisApi } from './api';
|
|
|
|
|
import { toRefs, reactive, defineComponent } from 'vue';
|
|
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
|
|
import ProjectEnvSelect from '../component/ProjectEnvSelect.vue';
|
2022-01-12 16:00:31 +08:00
|
|
|
import DataEdit from './DataEdit.vue';
|
2021-07-28 18:03:19 +08:00
|
|
|
import { isTrue, notNull } from '@/common/assert';
|
|
|
|
|
|
|
|
|
|
export default defineComponent({
|
|
|
|
|
name: 'DataOperation',
|
|
|
|
|
components: {
|
|
|
|
|
ValueDialog,
|
2022-01-12 16:00:31 +08:00
|
|
|
DataEdit,
|
2021-07-28 18:03:19 +08:00
|
|
|
ProjectEnvSelect,
|
|
|
|
|
},
|
|
|
|
|
setup() {
|
|
|
|
|
const state = reactive({
|
|
|
|
|
loading: false,
|
|
|
|
|
cluster: 0,
|
|
|
|
|
redisList: [],
|
|
|
|
|
query: {
|
|
|
|
|
envId: 0,
|
|
|
|
|
},
|
|
|
|
|
// redis: {
|
|
|
|
|
// id: 0,
|
|
|
|
|
// info: '',
|
|
|
|
|
// conf: '',
|
|
|
|
|
// },
|
|
|
|
|
scanParam: {
|
|
|
|
|
id: null,
|
|
|
|
|
cluster: 0,
|
|
|
|
|
match: null,
|
|
|
|
|
count: 10,
|
|
|
|
|
cursor: 0,
|
|
|
|
|
prevCursor: null,
|
|
|
|
|
},
|
|
|
|
|
valueDialog: {
|
|
|
|
|
visible: false,
|
|
|
|
|
value: {},
|
|
|
|
|
},
|
2022-01-12 16:00:31 +08:00
|
|
|
dataEdit: {
|
|
|
|
|
visible: false,
|
|
|
|
|
title: '新增数据',
|
|
|
|
|
operationType: 1,
|
|
|
|
|
keyInfo: {
|
|
|
|
|
type: 'string',
|
|
|
|
|
timed: -1,
|
|
|
|
|
key: '',
|
|
|
|
|
},
|
|
|
|
|
stringValue: '',
|
|
|
|
|
hashValue: [{ key: '', value: '' }],
|
|
|
|
|
setValue: [{ value: '' }],
|
|
|
|
|
},
|
2021-07-28 18:03:19 +08:00
|
|
|
keys: [],
|
|
|
|
|
dbsize: 0,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const searchRedis = async () => {
|
|
|
|
|
notNull(state.query.envId, '请先选择项目环境');
|
|
|
|
|
const res = await redisApi.redisList.request(state.query);
|
|
|
|
|
state.redisList = res.list;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const changeProjectEnv = (projectId: any, envId: any) => {
|
|
|
|
|
clearRedis();
|
|
|
|
|
if (envId != null) {
|
|
|
|
|
state.query.envId = envId;
|
|
|
|
|
searchRedis();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2021-09-08 17:55:57 +08:00
|
|
|
const changeRedis = () => {
|
2021-07-28 18:03:19 +08:00
|
|
|
resetScanParam();
|
|
|
|
|
state.keys = [];
|
|
|
|
|
state.dbsize = 0;
|
|
|
|
|
searchKey();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const scan = () => {
|
|
|
|
|
isTrue(state.scanParam.id != null, '请先选择redis');
|
2022-01-21 11:28:55 +08:00
|
|
|
isTrue(state.scanParam.count < 20001, 'count不能超过20000');
|
2021-07-28 18:03:19 +08:00
|
|
|
|
|
|
|
|
state.loading = true;
|
|
|
|
|
state.scanParam.cluster = state.cluster == 0 ? 0 : 1;
|
|
|
|
|
|
|
|
|
|
redisApi.scan.request(state.scanParam).then((res) => {
|
|
|
|
|
state.keys = res.keys;
|
|
|
|
|
state.dbsize = res.dbSize;
|
|
|
|
|
state.scanParam.cursor = res.cursor;
|
|
|
|
|
state.loading = false;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const searchKey = () => {
|
|
|
|
|
state.scanParam.cursor = 0;
|
|
|
|
|
scan();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const clearRedis = () => {
|
|
|
|
|
state.redisList = [];
|
|
|
|
|
state.scanParam.id = null;
|
|
|
|
|
resetScanParam();
|
|
|
|
|
state.keys = [];
|
|
|
|
|
state.dbsize = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const clear = () => {
|
|
|
|
|
resetScanParam();
|
|
|
|
|
if (state.scanParam.id) {
|
|
|
|
|
scan();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const resetScanParam = () => {
|
|
|
|
|
state.scanParam.match = null;
|
|
|
|
|
state.scanParam.cursor = 0;
|
|
|
|
|
state.scanParam.count = 10;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getValue = async (row: any) => {
|
2022-01-12 16:00:31 +08:00
|
|
|
const type = row.type;
|
|
|
|
|
const key = row.key;
|
|
|
|
|
|
|
|
|
|
let res: any;
|
|
|
|
|
const id = state.cluster == 0 ? state.scanParam.id : state.cluster;
|
|
|
|
|
const reqParam = {
|
|
|
|
|
cluster: state.cluster,
|
|
|
|
|
key: row.key,
|
|
|
|
|
id,
|
|
|
|
|
};
|
|
|
|
|
switch (type) {
|
2021-07-28 18:03:19 +08:00
|
|
|
case 'string':
|
2022-01-12 16:00:31 +08:00
|
|
|
res = await redisApi.getStringValue.request(reqParam);
|
2021-07-28 18:03:19 +08:00
|
|
|
break;
|
|
|
|
|
case 'hash':
|
2022-01-12 16:00:31 +08:00
|
|
|
res = await redisApi.getHashValue.request(reqParam);
|
2021-07-28 18:03:19 +08:00
|
|
|
break;
|
|
|
|
|
case 'set':
|
2022-01-12 16:00:31 +08:00
|
|
|
res = await redisApi.getSetValue.request(reqParam);
|
2021-07-28 18:03:19 +08:00
|
|
|
break;
|
|
|
|
|
default:
|
2022-01-12 16:00:31 +08:00
|
|
|
res = null;
|
2021-07-28 18:03:19 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2022-01-12 16:00:31 +08:00
|
|
|
notNull(res, '暂不支持该类型数据查看');
|
2021-07-28 18:03:19 +08:00
|
|
|
|
2022-01-12 16:00:31 +08:00
|
|
|
if (type == 'string') {
|
|
|
|
|
state.dataEdit.stringValue = res;
|
|
|
|
|
}
|
|
|
|
|
if (type == 'set') {
|
|
|
|
|
state.dataEdit.setValue = res.map((x: any) => {
|
|
|
|
|
return {
|
|
|
|
|
value: x,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (type == 'hash') {
|
|
|
|
|
const hash = [];
|
|
|
|
|
//遍历key和value
|
|
|
|
|
const keys = Object.keys(res);
|
|
|
|
|
for (let i = 0; i < keys.length; i++) {
|
|
|
|
|
const key = keys[i];
|
|
|
|
|
const value = res[key];
|
|
|
|
|
hash.push({
|
|
|
|
|
key,
|
|
|
|
|
value,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
state.dataEdit.hashValue = hash;
|
|
|
|
|
}
|
2021-07-28 18:03:19 +08:00
|
|
|
|
2022-01-12 16:00:31 +08:00
|
|
|
state.dataEdit.keyInfo.type = type;
|
|
|
|
|
state.dataEdit.keyInfo.timed = row.ttl;
|
|
|
|
|
state.dataEdit.keyInfo.key = key;
|
|
|
|
|
state.dataEdit.operationType = 2;
|
|
|
|
|
state.dataEdit.title = '修改数据';
|
|
|
|
|
state.dataEdit.visible = true;
|
|
|
|
|
};
|
2021-07-28 18:03:19 +08:00
|
|
|
|
|
|
|
|
const del = (key: string) => {
|
|
|
|
|
ElMessageBox.confirm(`此操作将删除对应的key , 是否继续?`, '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
type: 'warning',
|
|
|
|
|
})
|
|
|
|
|
.then(() => {
|
|
|
|
|
let id = state.cluster == 0 ? state.scanParam.id : state.cluster;
|
|
|
|
|
redisApi.delKey
|
|
|
|
|
.request({
|
|
|
|
|
cluster: state.cluster,
|
|
|
|
|
key,
|
|
|
|
|
id,
|
|
|
|
|
})
|
2021-09-08 17:55:57 +08:00
|
|
|
.then(() => {
|
2021-07-28 18:03:19 +08:00
|
|
|
ElMessage.success('删除成功!');
|
|
|
|
|
scan();
|
|
|
|
|
});
|
|
|
|
|
})
|
2021-09-08 17:55:57 +08:00
|
|
|
.catch(() => {});
|
2021-07-28 18:03:19 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const ttlConveter = (ttl: any) => {
|
2022-01-12 16:00:31 +08:00
|
|
|
if (ttl == -1) {
|
2021-07-28 18:03:19 +08:00
|
|
|
return '永久';
|
|
|
|
|
}
|
|
|
|
|
if (!ttl) {
|
|
|
|
|
ttl = 0;
|
|
|
|
|
}
|
|
|
|
|
let second = parseInt(ttl); // 秒
|
|
|
|
|
let min = 0; // 分
|
|
|
|
|
let hour = 0; // 小时
|
|
|
|
|
let day = 0;
|
|
|
|
|
if (second > 60) {
|
|
|
|
|
min = parseInt(second / 60 + '');
|
|
|
|
|
second = second % 60;
|
|
|
|
|
if (min > 60) {
|
|
|
|
|
hour = parseInt(min / 60 + '');
|
|
|
|
|
min = min % 60;
|
|
|
|
|
if (hour > 24) {
|
|
|
|
|
day = parseInt(hour / 24 + '');
|
|
|
|
|
hour = hour % 24;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let result = '' + second + 's';
|
|
|
|
|
if (min > 0) {
|
|
|
|
|
result = '' + min + 'm:' + result;
|
|
|
|
|
}
|
|
|
|
|
if (hour > 0) {
|
|
|
|
|
result = '' + hour + 'h:' + result;
|
|
|
|
|
}
|
|
|
|
|
if (day > 0) {
|
|
|
|
|
result = '' + day + 'd:' + result;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
};
|
|
|
|
|
|
2022-01-12 16:00:31 +08:00
|
|
|
const onAddData = () => {
|
|
|
|
|
notNull(state.scanParam.id, '请先选择redis');
|
|
|
|
|
state.dataEdit.operationType = 1;
|
|
|
|
|
state.dataEdit.title = '新增数据';
|
|
|
|
|
state.dataEdit.visible = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onCancelDataEdit = () => {
|
|
|
|
|
state.dataEdit.keyInfo = {} as any;
|
|
|
|
|
state.dataEdit.stringValue = '';
|
|
|
|
|
state.dataEdit.setValue = [];
|
|
|
|
|
state.dataEdit.hashValue = [];
|
|
|
|
|
};
|
|
|
|
|
|
2021-07-28 18:03:19 +08:00
|
|
|
return {
|
|
|
|
|
...toRefs(state),
|
|
|
|
|
changeProjectEnv,
|
|
|
|
|
changeRedis,
|
|
|
|
|
clearRedis,
|
|
|
|
|
searchKey,
|
|
|
|
|
scan,
|
|
|
|
|
clear,
|
|
|
|
|
getValue,
|
|
|
|
|
del,
|
|
|
|
|
ttlConveter,
|
2022-01-12 16:00:31 +08:00
|
|
|
onAddData,
|
|
|
|
|
onCancelDataEdit,
|
2021-07-28 18:03:19 +08:00
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
</style>
|