feat: 首次提交,添加Web界面和Redis支持的数据管理系统

This commit is contained in:
2025-09-01 00:45:37 +08:00
parent 7abb872b2c
commit b9fbe07b70
30 changed files with 4970 additions and 0 deletions

59
web/src/App.vue Normal file
View 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
View 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
View 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
View 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

View File

@@ -0,0 +1,8 @@
import {ref, computed} from 'vue'
import {defineStore} from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const token = ref("")
return {token}
})

View 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>

View 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>