修改网站托管模块

This commit is contained in:
zyj
2025-11-22 18:19:00 +08:00
parent 6212fa372c
commit c854ebd819
3 changed files with 114 additions and 62 deletions

View File

@@ -136,38 +136,38 @@
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'site'">
<div class="site-cell">
<a-avatar :style="{ backgroundColor: getAvatarColor(record.name) }" size="small">
{{ record.name.charAt(0).toUpperCase() }}
<a-avatar :style="{ backgroundColor: getAvatarColor(record.Name || record.name) }" size="small">
{{ (record.Name || record.name).charAt(0).toUpperCase() }}
</a-avatar>
<div class="site-details">
<div class="site-name">{{ record.name }}</div>
<div class="site-path">{{ record.path }}</div>
<div class="site-name">{{ record.Name || record.name }}</div>
<div class="site-path">{{ record.Path || record.path }}</div>
</div>
</div>
</template>
<template v-else-if="column.key === 'domain'">
<div class="domain-cell">
<a-tag color="blue" v-for="domain in record.domains" :key="domain">
<a-tag color="blue" v-for="domain in (record.Domains || record.domains)" :key="domain">
{{ domain }}
</a-tag>
</div>
</template>
<template v-else-if="column.key === 'port'">
<a-tag color="cyan">{{ record.port }}</a-tag>
<a-tag color="cyan">{{ record.Port || record.port }}</a-tag>
</template>
<template v-else-if="column.key === 'status'">
<a-badge
:status="record.enabled ? 'success' : 'default'"
:text="record.enabled ? '已启用' : '已禁用'"
:status="(record.Enabled !== undefined ? record.Enabled : record.enabled) ? 'success' : 'default'"
:text="(record.Enabled !== undefined ? record.Enabled : record.enabled) ? '已启用' : '已禁用'"
/>
</template>
<template v-else-if="column.key === 'action'">
<a-space size="small">
<a-button type="link" size="small" @click="openSite(record)" :disabled="!nginxRunning || !record.enabled">
<a-button type="link" size="small" @click="openSite(record)" :disabled="!nginxRunning || !(record.Enabled !== undefined ? record.Enabled : record.enabled)">
<template #icon><eye-outlined /></template>
访问
</a-button>
@@ -180,9 +180,9 @@
编辑
</a-button>
<a-switch
v-model:checked="record.enabled"
:checked="record.Enabled !== undefined ? record.Enabled : record.enabled"
size="small"
@change="toggleSiteStatus(record)"
@change="(val: boolean) => toggleSiteStatus(record, val)"
/>
<a-popconfirm
title="确定要删除此站点吗?"
@@ -210,12 +210,12 @@
@cancel="handleModalCancel"
>
<a-form :model="formData" layout="vertical" ref="formRef">
<a-form-item label="选择网站" name="name" :rules="[{ required: true, message: '请选择网站' }]">
<a-select v-model:value="formData.name" placeholder="请选择已下载的网站" @change="onSiteSelect">
<a-select-option v-for="site in availableSites" :key="site.name" :value="site.name">
{{ site.name }}
</a-select-option>
</a-select>
<a-form-item label="站点名称" name="name" :rules="[{ required: true, message: '请输入站点名称' }]">
<a-input v-model:value="formData.name" placeholder="请输入站点名称,如: example.com" />
<div class="form-tip">
<info-circle-outlined />
<span>可以输入域名或自定义名称</span>
</div>
</a-form-item>
<a-form-item label="域名配置" name="domains" :rules="[{ required: true, message: '请至少添加一个域名' }]">
@@ -252,10 +252,20 @@
</a-row>
<a-form-item label="网站路径" name="path" :rules="[{ required: true, message: '请输入网站路径' }]">
<a-input v-model:value="formData.path" placeholder="相对路径,如: www/example.com" />
<a-input-group compact style="display: flex;">
<a-input
v-model:value="formData.path"
placeholder="网站文件夹的绝对路径或相对路径"
style="flex: 1;"
/>
<a-button type="primary" @click="handleSelectFolder">
<template #icon><folder-open-outlined /></template>
选择文件夹
</a-button>
</a-input-group>
<div class="form-tip">
<info-circle-outlined />
<span>相对于项目根目录的路径</span>
<span>支持绝对路径 D:/www/mysite www/mysite</span>
</div>
</a-form-item>
@@ -304,7 +314,6 @@ const totalVisits = ref(0);
// 托管站点列表
const hostingSites = ref<any[]>([]);
const availableSites = ref<any[]>([]);
// 对话框
const modalVisible = ref(false);
@@ -362,7 +371,6 @@ onMounted(() => {
// 加载数据
const loadData = async () => {
await Promise.all([
getAvailableSites(),
getHostingSites(),
checkNginxStatus()
]);
@@ -379,16 +387,6 @@ const checkNginxStatus = async () => {
}
};
// 获取可用网站列表(已下载的)
const getAvailableSites = async () => {
try {
const res = await App.GetDownloadList();
availableSites.value = res || [];
} catch (error) {
console.error('获取网站列表失败:', error);
}
};
// 获取托管列表
const getHostingSites = async () => {
loading.value = true;
@@ -450,17 +448,31 @@ const showAddModal = () => {
// 编辑站点
const editSite = (record: any) => {
editingRecord.value = record;
formData.value = { ...record };
// 将后端字段转换为前端字段
formData.value = {
name: record.Name || record.name,
domains: record.Domains || record.domains || [],
port: record.Port || record.port,
path: record.Path || record.path,
index: record.Index || record.index || 'index.html',
enabled: record.Enabled !== undefined ? record.Enabled : record.enabled
};
modalVisible.value = true;
};
// 网站选择改变
const onSiteSelect = (value: string) => {
const site = availableSites.value.find(s => s.name === value);
if (site) {
// 设置网站路径(从工作目录)
formData.value.path = `www/${value}`;
formData.value.domains = [value, '127.0.0.1'];
// 选择文件夹
const handleSelectFolder = async () => {
try {
const folderPath = await App.SelectFolder();
if (folderPath) {
formData.value.path = folderPath;
message.success('已选择文件夹');
}
} catch (error: any) {
console.error('选择文件夹失败:', error);
if (error.message && error.message !== 'User cancelled') {
message.error('选择文件夹失败');
}
}
};
@@ -472,25 +484,25 @@ const handleModalOk = async () => {
if (editingRecord.value) {
// 更新站点配置
await App.UpdateNginxSite({
ID: "",
Name: formData.value.name,
Domains: formData.value.domains,
Port: formData.value.port,
Path: formData.value.path,
Index: formData.value.index,
Enabled: formData.value.enabled
id: "",
name: formData.value.name,
domains: formData.value.domains,
port: formData.value.port,
path: formData.value.path,
index: formData.value.index,
enabled: formData.value.enabled
});
message.success('更新成功');
} else {
// 添加站点配置
await App.AddNginxSite({
ID: "",
Name: formData.value.name,
Domains: formData.value.domains,
Port: formData.value.port,
Path: formData.value.path,
Index: formData.value.index,
Enabled: formData.value.enabled
id: "",
name: formData.value.name,
domains: formData.value.domains,
port: formData.value.port,
path: formData.value.path,
index: formData.value.index,
enabled: formData.value.enabled
});
message.success('站点配置创建成功');
}
@@ -517,14 +529,27 @@ const handleModalCancel = () => {
};
// 切换站点状态
const toggleSiteStatus = async (record: any) => {
const toggleSiteStatus = async (record: any, enabled: boolean) => {
try {
if (record.enabled) {
await App.EnableNginxSite(record.name);
const siteName = record.Name || record.name;
if (enabled) {
await App.EnableNginxSite(siteName);
message.success('站点已启用');
// 更新本地状态
if (record.Enabled !== undefined) {
record.Enabled = true;
} else {
record.enabled = true;
}
} else {
await App.DisableNginxSite(record.name);
await App.DisableNginxSite(siteName);
message.success('站点已禁用');
// 更新本地状态
if (record.Enabled !== undefined) {
record.Enabled = false;
} else {
record.enabled = false;
}
}
// 如果 nginx 正在运行,重载配置
@@ -534,15 +559,16 @@ const toggleSiteStatus = async (record: any) => {
} catch (error: any) {
console.error('切换状态失败:', error);
message.error(error.message || '操作失败');
// 回滚状态
record.enabled = !record.enabled;
// 重新加载数据恢复状态
await getHostingSites();
}
};
// 删除站点
const deleteSite = async (record: any) => {
try {
await App.DeleteNginxSite(record.name);
const siteName = record.Name || record.name;
await App.DeleteNginxSite(siteName);
message.success('站点配置已删除');
// 重新加载站点列表
@@ -560,14 +586,17 @@ const deleteSite = async (record: any) => {
// 访问站点
const openSite = (record: any) => {
const url = `http://${record.domains[0]}:${record.port}`;
const domains = record.Domains || record.domains || [];
const port = record.Port || record.port;
const url = `http://${domains[0]}:${port}`;
window.open(url, '_blank');
};
// 打开文件夹
const openFolder = async (record: any) => {
try {
await App.OpenSiteFileDir(record.name);
const siteName = record.Name || record.name;
await App.OpenSiteFileDir(siteName);
message.success('已打开文件夹');
} catch (error) {
console.error('打开文件夹失败:', error);