web/frpc: refactor dashboard with improved structure and API layer (#5117)

This commit is contained in:
fatedier
2026-01-09 00:40:51 +08:00
committed by GitHub
parent a4175a2595
commit 479e9f50c2
30 changed files with 2309 additions and 1694 deletions

View File

@@ -1,102 +0,0 @@
<template>
<div>
<el-row id="head">
<el-button type="primary" @click="fetchData">Refresh</el-button>
<el-button type="primary" @click="uploadConfig">Upload</el-button>
</el-row>
<el-input
type="textarea"
autosize
v-model="textarea"
placeholder="frpc configure file, can not be empty..."
></el-input>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
let textarea = ref('')
const fetchData = () => {
fetch('/api/config', { credentials: 'include' })
.then((res) => {
return res.text()
})
.then((text) => {
textarea.value = text
})
.catch(() => {
ElMessage({
showClose: true,
message: 'Get configure content from frpc failed!',
type: 'warning',
})
})
}
const uploadConfig = () => {
ElMessageBox.confirm(
'This operation will upload your frpc configure file content and hot reload it, do you want to continue?',
'Notice',
{
confirmButtonText: 'Yes',
cancelButtonText: 'No',
type: 'warning',
}
)
.then(() => {
if (textarea.value == '') {
ElMessage({
message: 'Configure content can not be empty!',
type: 'warning',
})
return
}
fetch('/api/config', {
credentials: 'include',
method: 'PUT',
body: textarea.value,
})
.then(() => {
fetch('/api/reload', { credentials: 'include' })
.then(() => {
ElMessage({
type: 'success',
message: 'Success',
})
})
.catch((err) => {
ElMessage({
showClose: true,
message: 'Reload frpc configure file error, ' + err,
type: 'warning',
})
})
})
.catch(() => {
ElMessage({
showClose: true,
message: 'Put config to frpc and hot reload failed!',
type: 'warning',
})
})
})
.catch(() => {
ElMessage({
message: 'Canceled',
type: 'info',
})
})
}
fetchData()
</script>
<style>
#head {
margin-bottom: 30px;
}
</style>

View File

@@ -1,85 +0,0 @@
<template>
<div>
<el-row>
<el-col :md="24">
<div>
<el-table
:data="status"
stripe
style="width: 100%"
:default-sort="{ prop: 'type', order: 'ascending' }"
>
<el-table-column
prop="name"
label="name"
sortable
></el-table-column>
<el-table-column
prop="type"
label="type"
width="150"
sortable
></el-table-column>
<el-table-column
prop="local_addr"
label="local address"
width="200"
sortable
></el-table-column>
<el-table-column
prop="plugin"
label="plugin"
width="200"
sortable
></el-table-column>
<el-table-column
prop="remote_addr"
label="remote address"
sortable
></el-table-column>
<el-table-column
prop="status"
label="status"
width="150"
sortable
></el-table-column>
<el-table-column prop="err" label="info"></el-table-column>
</el-table>
</div>
</el-col>
</el-row>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
let status = ref<any[]>([])
const fetchData = () => {
fetch('/api/status', { credentials: 'include' })
.then((res) => {
return res.json()
})
.then((json) => {
status.value = new Array()
for (let key in json) {
for (let ps of json[key]) {
console.log(ps)
status.value.push(ps)
}
}
})
.catch((err) => {
ElMessage({
showClose: true,
message: 'Get status info from frpc failed!' + err,
type: 'warning',
})
})
}
fetchData()
</script>
<style></style>