+
Linux
Windows
- 复制命令
- 下载脚本
+
+
+
+
+
+
+
+
+ curl -fsSLk -H "Authorization: Bearer {{ adminToken }}" {{ scriptDownloadUrl }} -o /opt/deploy-{{ scriptDomain?.domain?.replace('*.', '') }}.sh
+
+
+
+
+
+
+
+ chmod +x /opt/deploy-{{ scriptDomain?.domain?.replace('*.', '') }}.sh
+
+
+
+
+
+
+
+ /opt/deploy-{{ scriptDomain?.domain?.replace('*.', '') }}.sh && echo "0 * * * * /opt/deploy-{{ scriptDomain?.domain?.replace('*.', '') }}.sh >> /var/log/cert-deploy.log 2>&1" | crontab -
+ > /var/log/cert-deploy.log 2>&1' | crontab -`)" />
+
+
+
+
+
+
+
+
+
+
+
+
+ Invoke-WebRequest -Uri "{{ scriptDownloadUrl }}" -Headers @{Authorization="Bearer {{ adminToken }}"} -OutFile "C:\cert\deploy-{{ scriptDomain?.domain?.replace('*.', '') }}.ps1" -SkipCertificateCheck
+
+
+
+
+
+
+
+ powershell -ExecutionPolicy Bypass -File "C:\cert\deploy-{{ scriptDomain?.domain?.replace('*.', '') }}.ps1"
+
+
+
+
+
+
+
+ powershell -ExecutionPolicy Bypass -File "C:\cert\deploy-{{ scriptDomain?.domain?.replace('*.', '') }}.ps1"; schtasks /create /tn "CertDeploy-{{ scriptDomain?.domain?.replace('*.', '') }}" /tr "powershell -ExecutionPolicy Bypass -File C:\cert\deploy-{{ scriptDomain?.domain?.replace('*.', '') }}.ps1" /sc hourly /f
+
+
+
+
+
+
+
+
+
@@ -129,7 +194,7 @@
import { ref, onMounted } from 'vue'
import { Plus, ArrowDown, DocumentCopy, Download } from '@element-plus/icons-vue'
import { ElMessageBox, ElMessage } from 'element-plus'
-import { getDomains, createDomain, updateDomain, deleteDomain, getServers } from '../api'
+import { getDomains, createDomain, updateDomain, deleteDomain, getServers, issueCert } from '../api'
import api from '../api'
const domains = ref([])
@@ -148,6 +213,8 @@ const scriptDialogVisible = ref(false)
const scriptDomain = ref(null)
const scriptOs = ref('linux')
const scriptContent = ref('')
+const scriptDownloadUrl = ref('')
+const adminToken = ref(localStorage.getItem('admin_token') || '')
const load = async () => {
const { data } = await getDomains()
@@ -212,6 +279,10 @@ const openScript = async (row) => {
scriptDomain.value = row
scriptOs.value = 'linux'
scriptContent.value = ''
+ // 构建脚本下载 URL(供 curl 使用)
+ const base = window.location.origin
+ const params = new URLSearchParams({ domain: row.domain, server_name: row.server_name, os: 'linux' })
+ scriptDownloadUrl.value = `${base}/admin/api/script/download?${params}`
scriptDialogVisible.value = true
await loadScript()
}
@@ -226,11 +297,21 @@ const loadScript = async () => {
},
})
scriptContent.value = resp.data.script
+ // 更新下载 URL 的 os 参数
+ const base = window.location.origin
+ const params = new URLSearchParams({ domain: scriptDomain.value.domain, server_name: scriptDomain.value.server_name, os: scriptOs.value })
+ scriptDownloadUrl.value = `${base}/admin/api/script/download?${params}`
} catch (e) {
scriptContent.value = '# 加载失败: ' + (e.response?.data?.detail || e.message)
}
}
+const copyText = (text) => {
+ navigator.clipboard.writeText(text).then(() => {
+ ElMessage.success('已复制到剪贴板')
+ })
+}
+
const copyScript = () => {
navigator.clipboard.writeText(scriptContent.value).then(() => {
ElMessage.success('已复制到剪贴板')
@@ -263,6 +344,24 @@ const handleCertAction = async (cmd, row) => {
}
// ---- 删除 ----
+// ---- 申请证书 ----
+const handleIssue = async (row) => {
+ try {
+ await ElMessageBox.confirm(
+ `确认为 "${row.domain}" 申请证书?`,
+ '申请证书',
+ { type: 'info', confirmButtonText: '立即申请', cancelButtonText: '取消' }
+ )
+ const { data } = await issueCert(row.id)
+ ElMessage.success(data.message || '证书申请成功')
+ await load()
+ } catch (e) {
+ if (e !== 'cancel') {
+ ElMessage.error(e.response?.data?.detail || '证书申请失败')
+ }
+ }
+}
+
const handleDelete = async (row) => {
try {
await ElMessageBox.confirm(`确认删除域名 "${row.domain}"?`, '确认删除', { type: 'warning' })