gohttp/adminui/js/app.js

353 lines
11 KiB
JavaScript

// GoHttp 管理控制台 - 前端应用
new Vue({
el: '#app',
data() {
return {
loading: false,
activeTab: 'servers',
servers: [],
tcpProxies: [],
runningTcpProxies: [],
goroutines: 0,
serverDialog: {
visible: false,
title: '添加服务器',
isEdit: false,
saving: false,
form: this.getDefaultServerForm()
},
tcpDialog: {
visible: false,
title: '添加TCP代理',
isEdit: false,
saving: false,
form: this.getDefaultTcpForm()
}
}
},
mounted() {
this.refreshAll()
this.startStatusPolling()
},
methods: {
// 获取默认服务器表单
getDefaultServerForm() {
return {
name: '',
server: [],
port: 8080,
enable_ssl: false,
certfile: '',
keyfile: '',
paths: []
}
},
// 获取默认TCP代理表单
getDefaultTcpForm() {
return {
name: '',
listen: '',
target: '',
enabled: true
}
},
// 重置服务器表单
resetServerForm() {
this.serverDialog.form = this.getDefaultServerForm()
this.serverDialog.isEdit = false
},
// 重置TCP表单
resetTcpForm() {
this.tcpDialog.form = this.getDefaultTcpForm()
this.tcpDialog.isEdit = false
},
// API请求封装
async request(method, url, data) {
try {
const options = {
method: method,
headers: { 'Content-Type': 'application/json' }
}
if (data && (method === 'POST' || method === 'PUT' || method === 'DELETE')) {
options.body = JSON.stringify({ data })
}
const response = await fetch(url, options)
const result = await response.json()
if (result.code !== 200) {
this.$message.error(result.error || '操作失败')
return null
}
return result
} catch (error) {
console.error('Request error:', error)
this.$message.error('网络错误: ' + error.message)
return null
}
},
// 刷新所有数据
async refreshAll() {
this.loading = true
await Promise.all([
this.fetchServers(),
this.fetchTcpProxies(),
this.fetchStatus()
])
this.loading = false
},
// 获取服务器列表
async fetchServers() {
const result = await this.request('GET', '/api/config')
if (result) {
this.servers = result.data || []
}
},
// 获取TCP代理列表
async fetchTcpProxies() {
const result = await this.request('GET', '/api/tcp')
if (result) {
this.tcpProxies = result.data || []
}
},
// 获取系统状态
async fetchStatus() {
const result = await this.request('GET', '/api/status')
if (result && result.data) {
this.goroutines = result.data.goroutines || 0
}
},
// 定时获取状态
startStatusPolling() {
setInterval(() => {
if (this.activeTab === 'status') {
this.fetchStatus()
}
}, 5000)
},
// Tab切换
handleTabClick(tab) {
if (tab.name === 'status') {
this.fetchStatus()
}
},
// 判断TCP代理是否运行中
isTcpRunning(name) {
return this.runningTcpProxies.includes(name)
},
// 显示服务器对话框
showServerDialog(server) {
if (server) {
this.serverDialog.title = '编辑服务器'
this.serverDialog.isEdit = true
// 转换后端数据格式到前端
this.serverDialog.form = {
name: server.name,
server: server.server || [],
port: server.port,
enable_ssl: server.enable_ssl || false,
certfile: server.certfile || '',
keyfile: server.keyfile || '',
paths: (server.paths || []).map(p => ({
path: p.path,
type: p.root ? 'static' : (p.upstreams && p.upstreams.length > 0 ? 'proxy' : 'static'),
root: p.root || '',
default: p.default || '',
upstreams: p.upstreams || []
}))
}
} else {
this.serverDialog.title = '添加服务器'
this.serverDialog.isEdit = false
this.serverDialog.form = this.getDefaultServerForm()
}
this.serverDialog.visible = true
},
// 添加路由
addPath() {
this.serverDialog.form.paths.push({
path: '',
type: 'static',
root: '',
default: 'index.html',
upstreams: []
})
},
// 移除路由
removePath(index) {
this.serverDialog.form.paths.splice(index, 1)
},
// 路由类型变更
onPathTypeChange(path) {
if (path.type === 'static') {
path.upstreams = []
} else {
path.root = ''
path.default = ''
}
},
// 保存服务器
async saveServer() {
const form = this.serverDialog.form
if (!form.name || !form.port) {
this.$message.warning('请填写必填项')
return
}
// 转换前端数据格式到后端
const serverConfig = {
name: form.name,
server: form.server,
port: form.port,
enable_ssl: form.enable_ssl,
certfile: form.certfile,
keyfile: form.keyfile,
paths: form.paths.map(p => ({
path: p.path,
root: p.type === 'static' ? p.root : '',
default: p.type === 'static' ? p.default : '',
upstreams: p.type === 'proxy' ? p.upstreams : [],
directives: p.directives || []
}))
}
this.serverDialog.saving = true
const result = await this.request('POST', '/api/config', serverConfig)
this.serverDialog.saving = false
if (result) {
this.$message.success('保存成功')
this.serverDialog.visible = false
await this.fetchServers()
}
},
// 重启服务器
async restartServer(name) {
try {
const result = await this.request('POST', `/api/server/restart/${name}`)
if (result) {
this.$message.success(`服务器 ${name} 已重启`)
}
} catch (e) {
this.$message.error('重启失败')
}
},
// 删除服务器
async deleteServer(name) {
try {
await this.$confirm(`确定要删除服务器 "${name}" 吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
const result = await this.request('DELETE', `/api/server/${name}`)
if (result) {
this.$message.success('删除成功')
await this.fetchServers()
}
} catch (e) {
if (e !== 'cancel') {
this.$message.error('删除失败')
}
}
},
// 显示TCP代理对话框
showTcpDialog(tcp) {
if (tcp) {
this.tcpDialog.title = '编辑TCP代理'
this.tcpDialog.isEdit = true
this.tcpDialog.form = {
name: tcp.name,
listen: tcp.listen,
target: tcp.target,
enabled: tcp.enabled !== false
}
} else {
this.tcpDialog.title = '添加TCP代理'
this.tcpDialog.isEdit = false
this.tcpDialog.form = this.getDefaultTcpForm()
}
this.tcpDialog.visible = true
},
// 保存TCP代理
async saveTcpProxy() {
const form = this.tcpDialog.form
if (!form.name || !form.listen || !form.target) {
this.$message.warning('请填写必填项')
return
}
this.tcpDialog.saving = true
const result = await this.request('POST', '/api/tcp', form)
this.tcpDialog.saving = false
if (result) {
this.$message.success('保存成功')
this.tcpDialog.visible = false
await this.fetchTcpProxies()
}
},
// 切换TCP代理状态
async toggleTcpProxy(tcp) {
const action = this.isTcpRunning(tcp.name) ? 'stop' : 'start'
try {
const result = await this.request('POST', `/api/tcp/${action}/${tcp.name}`)
if (result) {
this.$message.success(`TCP代理已${action === 'stop' ? '停止' : '启动'}`)
// 更新运行状态
if (action === 'start') {
if (!this.runningTcpProxies.includes(tcp.name)) {
this.runningTcpProxies.push(tcp.name)
}
} else {
this.runningTcpProxies = this.runningTcpProxies.filter(n => n !== tcp.name)
}
}
} catch (e) {
this.$message.error('操作失败')
}
},
// 删除TCP代理
async deleteTcpProxy(name) {
try {
await this.$confirm(`确定要删除TCP代理 "${name}" 吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
const result = await this.request('DELETE', `/api/tcp/${name}`)
if (result) {
this.$message.success('删除成功')
this.runningTcpProxies = this.runningTcpProxies.filter(n => n !== name)
await this.fetchTcpProxies()
}
} catch (e) {
if (e !== 'cancel') {
this.$message.error('删除失败')
}
}
}
}
})