diff --git a/frontend/src/locales/en-US.json b/frontend/src/locales/en-US.json
index a90abad..fc510b3 100644
--- a/frontend/src/locales/en-US.json
+++ b/frontend/src/locales/en-US.json
@@ -972,7 +972,13 @@
"http01Hint": "Let’s Encrypt HTTP-01. Port 80 must be reachable. Auto-renewal status appears in the list.",
"certKeyRequired": "Certificate and private key are required",
"certUploaded": "Certificate uploaded",
- "uploadApiPending": "Upload API is not ready yet (POST /system/tls/certificate). Use HTTP-01 for now."
+ "uploadApiPending": "Upload API is not ready yet (POST /system/tls/certificate). Use HTTP-01 for now.",
+ "dropHint": "Drop a file here, or click to choose",
+ "pastePem": "Or paste PEM text",
+ "importCert": "Import certificate",
+ "startIssue": "Start issuance",
+ "http01CheckDns": "DNS already points to this public entry",
+ "http01CheckPort": "Issuance port is reachable (usually 80, or matches entry port)"
},
"feishuSync": {
"title": "Feishu directory",
diff --git a/frontend/src/locales/zh-CN.json b/frontend/src/locales/zh-CN.json
index 320607b..1b39ae5 100644
--- a/frontend/src/locales/zh-CN.json
+++ b/frontend/src/locales/zh-CN.json
@@ -972,7 +972,13 @@
"http01Hint": "使用 Let’s Encrypt HTTP-01 验证;需公网可访问 80 端口。过期前将尝试自动续期,失败时列表会显示状态。",
"certKeyRequired": "请填写证书与私钥",
"certUploaded": "证书已上传",
- "uploadApiPending": "上传证书接口尚未就绪,请先由后端落地 POST /system/tls/certificate,或改用 HTTP-01 申请。"
+ "uploadApiPending": "上传证书接口尚未就绪,请先由后端落地 POST /system/tls/certificate,或改用 HTTP-01 申请。",
+ "dropHint": "拖拽文件到此处,或点击选择",
+ "pastePem": "或粘贴 PEM 文本",
+ "importCert": "导入证书",
+ "startIssue": "开始申请",
+ "http01CheckDns": "DNS 已指向本机公网入口",
+ "http01CheckPort": "申请用端口可达(通常为 80,或与入口配置一致)"
},
"feishuSync": {
"title": "飞书组织与成员",
diff --git a/frontend/src/views/settings/components/GatewaySettings.vue b/frontend/src/views/settings/components/GatewaySettings.vue
index e02e1ca..c71bad5 100644
--- a/frontend/src/views/settings/components/GatewaySettings.vue
+++ b/frontend/src/views/settings/components/GatewaySettings.vue
@@ -138,16 +138,42 @@
{{ nginxActivateLog }}
@@ -207,6 +239,8 @@ const certForm = reactive({
method: 'upload',
certPem: '',
keyPem: '',
+ certFileName: '',
+ keyFileName: '',
host: '',
email: '',
})
@@ -243,6 +277,8 @@ function resetCertForm() {
certForm.method = 'upload'
certForm.certPem = ''
certForm.keyPem = ''
+ certForm.certFileName = ''
+ certForm.keyFileName = ''
certForm.host = entry.host
certForm.email = ''
nginxActivateLog.value = ''
@@ -255,7 +291,11 @@ function openAddCert() {
function readPemFile(file, field) {
const reader = new FileReader()
- reader.onload = () => { certForm[field] = String(reader.result || '') }
+ reader.onload = () => {
+ certForm[field] = String(reader.result || '')
+ if (field === 'certPem') certForm.certFileName = file.name
+ if (field === 'keyPem') certForm.keyFileName = file.name
+ }
reader.readAsText(file)
return false
}
@@ -461,5 +501,10 @@ onMounted(() => { if (!auth.mustChange) refreshAll() })
transition: border-color .15s, box-shadow .15s;
}
.method-card.active { border-color: var(--el-color-primary); box-shadow: 0 0 0 1px var(--el-color-primary) inset; }
-.upload-btn { color: var(--el-color-primary); border-style: dashed; }
+.pem-drop { width: 100%; }
+.pem-drop :deep(.el-upload), .pem-drop :deep(.el-upload-dragger) { width: 100%; }
+.pem-drop-inner { padding: 8px 0; }
+.pem-drop-title { color: var(--el-color-primary); font-weight: 600; }
+.pem-drop-hint { margin-top: 4px; font-size: 12px; color: var(--text-secondary); }
+.http01-checklist { margin: 0; padding-left: 1.2em; color: var(--text-secondary); font-size: 13px; line-height: 1.7; }