feat: 首次提交,添加Web界面和Redis支持的数据管理系统
This commit is contained in:
59
web/src/App.vue
Normal file
59
web/src/App.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<script setup lang="ts">
|
||||
import {ref, watch} from 'vue'
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
const activeIndex = ref(route.name?.toString() || "TokenList")
|
||||
|
||||
watch(route, (newRoute) => {
|
||||
activeIndex.value = newRoute.name?.toString() || "TokenList"
|
||||
})
|
||||
|
||||
const handleSelect = (key: string) => {
|
||||
router.push({
|
||||
name: key
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<el-menu
|
||||
:default-active="activeIndex"
|
||||
class="el-menu-demo"
|
||||
mode="horizontal"
|
||||
@select="handleSelect"
|
||||
>
|
||||
<el-menu-item index="TokenList">Token列表</el-menu-item>
|
||||
<el-menu-item index="TokenDetail">Token信息</el-menu-item>
|
||||
</el-menu>
|
||||
</el-header>
|
||||
|
||||
<el-container>
|
||||
<el-main>
|
||||
<router-view></router-view>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
|
||||
<style>
|
||||
html, body, #app {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.el-container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.el-menu-demo {
|
||||
line-height: 60px;
|
||||
}
|
||||
</style>
|
7
web/src/axios.ts
Normal file
7
web/src/axios.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const instance = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_BASE_URL,
|
||||
});
|
||||
|
||||
export default instance;
|
15
web/src/main.ts
Normal file
15
web/src/main.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import {createApp} from 'vue'
|
||||
import {createPinia} from 'pinia'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
app.use(ElementPlus)
|
||||
|
||||
app.mount('#app')
|
16
web/src/router/index.ts
Normal file
16
web/src/router/index.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import {createRouter, createWebHistory} from 'vue-router'
|
||||
|
||||
import TokenListView from '@/views/TokenListView.vue'
|
||||
import TokenDetailView from '@/views/TokenDetailView.vue'
|
||||
|
||||
const routes = [
|
||||
{path: '/', name: "TokenList", component: TokenListView},
|
||||
{path: '/token', name: "TokenDetail", component: TokenDetailView},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes,
|
||||
})
|
||||
|
||||
export default router
|
8
web/src/stores/counter.ts
Normal file
8
web/src/stores/counter.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import {ref, computed} from 'vue'
|
||||
import {defineStore} from 'pinia'
|
||||
|
||||
export const useCounterStore = defineStore('counter', () => {
|
||||
const token = ref("")
|
||||
|
||||
return {token}
|
||||
})
|
62
web/src/views/TokenDetailView.vue
Normal file
62
web/src/views/TokenDetailView.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
import {useCounterStore} from "@/stores/counter.ts";
|
||||
import {ref} from 'vue'
|
||||
import axios from "@/axios.ts";
|
||||
|
||||
const result = ref()
|
||||
|
||||
const getInfo = () => {
|
||||
axios.get('/api/token/info', {
|
||||
params: {
|
||||
token: useCounterStore().token
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.status == 200) {
|
||||
result.value = res.data.result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const deleteDedup = () => {
|
||||
axios.delete('/api/token/info', {
|
||||
params: {
|
||||
token: useCounterStore().token,
|
||||
dedup_bf: true
|
||||
}
|
||||
})
|
||||
}
|
||||
const deleteRedis = () => {
|
||||
axios.delete('/api/token/info', {
|
||||
params: {
|
||||
token: useCounterStore().token,
|
||||
cache_list: true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getInfo()
|
||||
setInterval(getInfo, 5000)
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<p>当前Token:{{ useCounterStore().token }}</p>
|
||||
<el-button type="danger" @click="deleteDedup">删除去重记录值</el-button>
|
||||
<el-button type="danger" @click="deleteRedis">删除Redis数据</el-button>
|
||||
<el-divider/>
|
||||
<el-button type="primary" @click="getInfo">手动刷新</el-button>
|
||||
<el-descriptions
|
||||
:title="'Token信息 - ' + useCounterStore().token+'(每5秒刷新)'"
|
||||
direction="vertical"
|
||||
:column="4"
|
||||
border
|
||||
>
|
||||
<el-descriptions-item label="去重对象">{{ result?.dedup_object }}</el-descriptions-item>
|
||||
<el-descriptions-item label="去重记录值">{{ result?.dedup_items_number }}</el-descriptions-item>
|
||||
<el-descriptions-item label="Redis中数据条数">{{ result?.cache_list_number }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
183
web/src/views/TokenListView.vue
Normal file
183
web/src/views/TokenListView.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<script setup lang="ts">
|
||||
import {ref} from "vue";
|
||||
import axios from "@/axios.ts";
|
||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||
|
||||
const tableData = ref([])
|
||||
|
||||
axios.get("/api/token").then(res => {
|
||||
tableData.value = res.data.result
|
||||
})
|
||||
|
||||
const input = ref('')
|
||||
const value = ref('')
|
||||
const options = [
|
||||
{
|
||||
value: 'token',
|
||||
label: 'token',
|
||||
},
|
||||
{
|
||||
value: 'uid',
|
||||
label: 'uid',
|
||||
},
|
||||
{
|
||||
value: 'pid',
|
||||
label: 'pid',
|
||||
},
|
||||
{
|
||||
value: 'secid',
|
||||
label: 'secid',
|
||||
},
|
||||
{
|
||||
value: 'dyid',
|
||||
label: 'dyid',
|
||||
},
|
||||
{
|
||||
value: 'key',
|
||||
label: 'key',
|
||||
},
|
||||
{
|
||||
value: 'comment_id',
|
||||
label: 'comment_id',
|
||||
}
|
||||
]
|
||||
|
||||
const addToken = () => {
|
||||
axios.post('/api/token', {}, {
|
||||
params: {
|
||||
token: input.value,
|
||||
dedup_object: value.value
|
||||
}
|
||||
}).then(response => {
|
||||
if (response.data.result == "ok") {
|
||||
ElMessage({
|
||||
message: '添加成功',
|
||||
type: 'success',
|
||||
})
|
||||
axios.get('/api/token').then(res => {
|
||||
tableData.value = res.data.result
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
ElMessage.error(error.response?.data?.error)
|
||||
})
|
||||
}
|
||||
|
||||
import {useCounterStore} from "@/stores/counter.ts";
|
||||
import {useRouter} from "vue-router";
|
||||
|
||||
const router = useRouter()
|
||||
const viewDetails = (row: any) => {
|
||||
useCounterStore().token = row.token
|
||||
router.push({
|
||||
name: "TokenDetail"
|
||||
})
|
||||
}
|
||||
|
||||
var rowOut: any
|
||||
const dedupObjectVisible = ref(false)
|
||||
const dialogDedupObjectVisible = (row: any) => {
|
||||
rowOut = row
|
||||
dedupObjectVisible.value = true
|
||||
}
|
||||
const updateDedupObject = () => {
|
||||
dedupObjectVisible.value = false
|
||||
axios.put('/api/token', {}, {
|
||||
params: {
|
||||
token: rowOut.token,
|
||||
dedup_object: value.value
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.data.result == "ok") {
|
||||
ElMessage({
|
||||
message: '更改成功',
|
||||
type: 'success',
|
||||
})
|
||||
axios.get('/api/token').then(res => {
|
||||
tableData.value = res.data.result
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
ElMessage.error(error.response?.data?.error)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const deleteToken = (row: any) => {
|
||||
axios.delete('/api/token', {
|
||||
params: {
|
||||
token: row.token
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.data.result == "ok") {
|
||||
ElMessage({
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
})
|
||||
axios.get('/api/token').then(res => {
|
||||
tableData.value = res.data.result
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
ElMessage.error(error.response?.data?.error)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!--添加Token-->
|
||||
<el-input v-model="input" style="width: 200px" placeholder="请输入Token名称"/>
|
||||
<el-select v-model="value" placeholder="选择去重对象" style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-button type="primary" @click="addToken">添加Token</el-button>
|
||||
|
||||
<!--Token列表-->
|
||||
<el-table :data="tableData" style="width: 100%">
|
||||
<el-table-column prop="token" label="Token" width="180"/>
|
||||
<el-table-column prop="dedup_object" label="去重对象" width="180"/>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button @click="viewDetails(scope.row)">查看详细</el-button>
|
||||
<el-button @click="dialogDedupObjectVisible(scope.row)" type="primary">更改去重对象</el-button>
|
||||
<el-popconfirm
|
||||
width="180"
|
||||
title="确认删除此Token吗"
|
||||
confirm-button-text="确认"
|
||||
cancel-button-text="取消"
|
||||
@confirm="deleteToken(scope.row)"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button type="danger">删除此Token</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog v-model="dedupObjectVisible" title="更改去重对象" width="400">
|
||||
<el-select v-model="value" placeholder="选择去重对象" style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="updateDedupObject">
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
Reference in New Issue
Block a user