Browse Source

Enhanced domain add

0xJacky 3 years ago
parent
commit
60919aea4c

+ 1 - 1
frontend/package.json

@@ -1,6 +1,6 @@
 {
     "name": "nginx-ui-frontend",
-    "version": "1.2.2",
+    "version": "1.3.0",
     "private": true,
     "scripts": {
         "serve": "vue-cli-service serve",

+ 1 - 1
frontend/src/components/StdDataEntry/StdDataEntry.vue

@@ -115,7 +115,7 @@
 
             <p v-if="!dataSource[d.dataIndex] && d.empty_description" v-html="d.empty_description"/>
         </a-form-item>
-        <a-form-item>
+        <a-form-item v-if="$slots.supplement||$slots.action">
             <slot name="supplement"/>
             <slot name="action"/>
         </a-form-item>

+ 52 - 24
frontend/src/locale/en/LC_MESSAGES/app.po

@@ -23,28 +23,27 @@ msgstr ""
 msgid "Action"
 msgstr ""
 
-#: src/router/index.js:47 src/views/domain/DomainAdd.vue:18
+#: src/router/index.js:47 src/views/domain/DomainAdd.vue:27
 msgid "Add Site"
 msgstr ""
 
-#: src/views/domain/DomainAdd.vue:2
-msgid ""
-"Add site here first, then you can configure TLS on the domain edit page."
-msgstr ""
-
-#: src/views/domain/DomainEdit.vue:194
+#: src/views/domain/DomainAdd.vue:86 src/views/domain/DomainEdit.vue:172
 msgid "Auto-renewal disabled for %{name}"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:188
+#: src/views/domain/DomainAdd.vue:80 src/views/domain/DomainEdit.vue:166
 msgid "Auto-renewal enabled for %{name}"
 msgstr ""
 
+#: src/views/domain/DomainAdd.vue:37
+msgid "Base information"
+msgstr ""
+
 #: src/views/other/About.vue:11
 msgid "Build with"
 msgstr ""
 
-#: src/views/config/ConfigEdit.vue:5 src/views/domain/DomainEdit.vue:23
+#: src/views/config/ConfigEdit.vue:5 src/views/domain/DomainEdit.vue:24
 msgid "Cancel"
 msgstr ""
 
@@ -76,6 +75,10 @@ msgstr ""
 msgid "Configurations"
 msgstr ""
 
+#: src/views/domain/DomainAdd.vue:40
+msgid "Configure SSL"
+msgstr ""
+
 #: src/views/dashboard/DashBoard.vue:207
 msgid "CPU Status"
 msgstr ""
@@ -84,6 +87,10 @@ msgstr ""
 msgid "CPU:"
 msgstr ""
 
+#: src/views/domain/DomainAdd.vue:31 src/views/domain/DomainAdd.vue:5
+msgid "Create Another"
+msgstr ""
+
 #: src/views/user/User.vue:23
 msgid "Created at"
 msgstr ""
@@ -104,7 +111,7 @@ msgstr ""
 msgid "Development Mode"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:196
+#: src/views/domain/DomainAdd.vue:88 src/views/domain/DomainEdit.vue:174
 msgid "Disable auto-renewal failed for %{name}"
 msgstr ""
 
@@ -121,10 +128,14 @@ msgstr ""
 msgid "Disk IO"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:133
+#: src/views/domain/DomainEdit.vue:134
 msgid "Do you want to change the template to support the TLS?"
 msgstr ""
 
+#: src/views/domain/DomainAdd.vue:111
+msgid "Domain Config Created Successfully"
+msgstr ""
+
 #: src/views/domain/DomainEdit.vue:42
 msgid "Edit %{n}"
 msgstr ""
@@ -145,11 +156,11 @@ msgstr ""
 msgid "Email (*)"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:190
+#: src/views/domain/DomainAdd.vue:82 src/views/domain/DomainEdit.vue:168
 msgid "Enable auto-renewal failed for %{name}"
 msgstr ""
 
-#: src/views/domain/DomainAdd.vue:33
+#: src/views/domain/DomainAdd.vue:39
 msgid "Enable failed"
 msgstr ""
 
@@ -162,7 +173,7 @@ msgstr ""
 msgid "Enabled"
 msgstr ""
 
-#: src/views/domain/DomainAdd.vue:27 src/views/domain/DomainList.vue:46
+#: src/views/domain/DomainAdd.vue:36 src/views/domain/DomainList.vue:46
 msgid "Enabled successfully"
 msgstr ""
 
@@ -182,11 +193,16 @@ msgstr ""
 msgid "File Not Found"
 msgstr ""
 
+#: src/views/domain/DomainAdd.vue:43
+msgid "Finished"
+msgstr ""
+
+#: src/views/domain/DomainAdd.vue:13 src/views/domain/DomainAdd.vue:2
 #: src/views/domain/DomainEdit.vue:9 src/views/domain/DomainEdit.vue:3
 msgid "Getting Certificate from Let's Encrypt"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:156
+#: src/views/domain/methods.js:34
 msgid "Getting the certificate, please wait..."
 msgstr ""
 
@@ -265,6 +281,10 @@ msgstr ""
 msgid "Memory"
 msgstr ""
 
+#: src/views/domain/DomainAdd.vue:28 src/views/domain/DomainAdd.vue:2
+msgid "Modify Config"
+msgstr ""
+
 #: src/views/config/Config.vue:5 src/views/domain/DomainList.vue:5
 msgid "Name"
 msgstr ""
@@ -281,6 +301,10 @@ msgstr ""
 msgid "Network Total Send"
 msgstr ""
 
+#: src/views/domain/DomainAdd.vue:38
+msgid "Next"
+msgstr ""
+
 #: src/router/index.js:105
 msgid "Not Found"
 msgstr ""
@@ -289,7 +313,7 @@ msgstr ""
 msgid "Not Valid Before: %{date}"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:155
+#: src/views/domain/methods.js:33
 msgid ""
 "Note: The server_name in the current configuration must be the domain name "
 "you need to get the certificate."
@@ -343,18 +367,17 @@ msgstr ""
 msgid "Root Directory (root)"
 msgstr ""
 
-#: src/views/config/ConfigEdit.vue:6 src/views/domain/DomainAdd.vue:6
-#: src/views/domain/DomainEdit.vue:24
+#: src/views/config/ConfigEdit.vue:6 src/views/domain/DomainEdit.vue:27
 msgid "Save"
 msgstr ""
 
-#: src/views/config/ConfigEdit.vue:47 src/views/domain/DomainAdd.vue:38
-#: src/views/domain/DomainEdit.vue:151
+#: src/views/config/ConfigEdit.vue:47 src/views/domain/DomainAdd.vue:43
+#: src/views/domain/DomainAdd.vue:54 src/views/domain/DomainEdit.vue:152
 msgid "Save error %{msg}"
 msgstr ""
 
-#: src/views/config/ConfigEdit.vue:44 src/views/domain/DomainAdd.vue:24
-#: src/views/domain/DomainEdit.vue:145
+#: src/views/config/ConfigEdit.vue:44 src/views/domain/DomainAdd.vue:33
+#: src/views/domain/DomainAdd.vue:51 src/views/domain/DomainEdit.vue:146
 msgid "Saved successfully"
 msgstr ""
 
@@ -362,7 +385,7 @@ msgstr ""
 msgid "Send"
 msgstr ""
 
-#: src/views/config/ConfigEdit.vue:35 src/views/domain/DomainEdit.vue:71
+#: src/views/config/ConfigEdit.vue:35 src/views/domain/DomainEdit.vue:72
 #: src/views/other/Login.vue:35
 msgid "Server error"
 msgstr ""
@@ -379,6 +402,10 @@ msgstr ""
 msgid "Sites List"
 msgstr ""
 
+#: src/views/domain/DomainAdd.vue:20 src/views/domain/DomainAdd.vue:9
+msgid "Skip"
+msgstr ""
+
 #: src/views/domain/DomainList.vue:11
 msgid "Status"
 msgstr ""
@@ -418,11 +445,12 @@ msgid ""
 "changed after it has been created."
 msgstr ""
 
+#: src/views/domain/DomainAdd.vue:15 src/views/domain/DomainAdd.vue:4
 #: src/views/domain/DomainEdit.vue:11 src/views/domain/DomainEdit.vue:5
 msgid "This feature is not available in demo."
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:134
+#: src/views/domain/DomainEdit.vue:135
 msgid "This operation will lose the custom configuration."
 msgstr ""
 

BIN
frontend/src/locale/zh_CN/LC_MESSAGES/app.mo


+ 58 - 26
frontend/src/locale/zh_CN/LC_MESSAGES/app.po

@@ -25,28 +25,27 @@ msgstr "关于"
 msgid "Action"
 msgstr "操作"
 
-#: src/router/index.js:47 src/views/domain/DomainAdd.vue:18
+#: src/router/index.js:47 src/views/domain/DomainAdd.vue:27
 msgid "Add Site"
 msgstr "添加站点"
 
-#: src/views/domain/DomainAdd.vue:2
-msgid ""
-"Add site here first, then you can configure TLS on the domain edit page."
-msgstr "在这里添加站点,完成后可进入编辑页面配置 TLS。"
-
-#: src/views/domain/DomainEdit.vue:194
+#: src/views/domain/DomainAdd.vue:86 src/views/domain/DomainEdit.vue:172
 msgid "Auto-renewal disabled for %{name}"
 msgstr "成功关闭 %{name} 自动续签"
 
-#: src/views/domain/DomainEdit.vue:188
+#: src/views/domain/DomainAdd.vue:80 src/views/domain/DomainEdit.vue:166
 msgid "Auto-renewal enabled for %{name}"
 msgstr "成功启用 %{name} 自动续签"
 
+#: src/views/domain/DomainAdd.vue:37
+msgid "Base information"
+msgstr "基本信息"
+
 #: src/views/other/About.vue:11
 msgid "Build with"
 msgstr "构建基于"
 
-#: src/views/config/ConfigEdit.vue:5 src/views/domain/DomainEdit.vue:23
+#: src/views/config/ConfigEdit.vue:5 src/views/domain/DomainEdit.vue:24
 msgid "Cancel"
 msgstr "取消"
 
@@ -78,6 +77,10 @@ msgstr "配置名称"
 msgid "Configurations"
 msgstr "配置"
 
+#: src/views/domain/DomainAdd.vue:40
+msgid "Configure SSL"
+msgstr "配置 SSL"
+
 #: src/views/dashboard/DashBoard.vue:207
 msgid "CPU Status"
 msgstr "CPU 状态"
@@ -86,6 +89,10 @@ msgstr "CPU 状态"
 msgid "CPU:"
 msgstr ""
 
+#: src/views/domain/DomainAdd.vue:31 src/views/domain/DomainAdd.vue:5
+msgid "Create Another"
+msgstr "再创建一个"
+
 #: src/views/user/User.vue:23
 msgid "Created at"
 msgstr "创建时间"
@@ -106,7 +113,7 @@ msgstr "检测到版本更新,页面将会刷新。"
 msgid "Development Mode"
 msgstr "开发模式"
 
-#: src/views/domain/DomainEdit.vue:196
+#: src/views/domain/DomainAdd.vue:88 src/views/domain/DomainEdit.vue:174
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "关闭 %{name} 自动续签失败"
 
@@ -123,10 +130,14 @@ msgstr "禁用成功"
 msgid "Disk IO"
 msgstr "磁盘 IO"
 
-#: src/views/domain/DomainEdit.vue:133
+#: src/views/domain/DomainEdit.vue:134
 msgid "Do you want to change the template to support the TLS?"
 msgstr "你想要改变模板以支持 TLS 吗?"
 
+#: src/views/domain/DomainAdd.vue:111
+msgid "Domain Config Created Successfully"
+msgstr "域名配置文件创建成功"
+
 #: src/views/domain/DomainEdit.vue:42
 msgid "Edit %{n}"
 msgstr "编辑 %{n}"
@@ -147,11 +158,11 @@ msgstr "编辑站点"
 msgid "Email (*)"
 msgstr "邮箱 (*)"
 
-#: src/views/domain/DomainEdit.vue:190
+#: src/views/domain/DomainAdd.vue:82 src/views/domain/DomainEdit.vue:168
 msgid "Enable auto-renewal failed for %{name}"
 msgstr "启用 %{name} 自动续签失败"
 
-#: src/views/domain/DomainAdd.vue:33
+#: src/views/domain/DomainAdd.vue:39
 msgid "Enable failed"
 msgstr "启用失败"
 
@@ -164,7 +175,7 @@ msgstr "启用 TLS"
 msgid "Enabled"
 msgstr "启用"
 
-#: src/views/domain/DomainAdd.vue:27 src/views/domain/DomainList.vue:46
+#: src/views/domain/DomainAdd.vue:36 src/views/domain/DomainList.vue:46
 msgid "Enabled successfully"
 msgstr "启用成功"
 
@@ -184,11 +195,16 @@ msgstr "启用失败 %{msg}"
 msgid "File Not Found"
 msgstr "未找到文件"
 
+#: src/views/domain/DomainAdd.vue:43
+msgid "Finished"
+msgstr "完成"
+
+#: src/views/domain/DomainAdd.vue:13 src/views/domain/DomainAdd.vue:2
 #: src/views/domain/DomainEdit.vue:9 src/views/domain/DomainEdit.vue:3
 msgid "Getting Certificate from Let's Encrypt"
 msgstr "从 Let's Encrypt 获取证书"
 
-#: src/views/domain/DomainEdit.vue:156
+#: src/views/domain/methods.js:34
 msgid "Getting the certificate, please wait..."
 msgstr "正在获取证书,请稍等..."
 
@@ -269,6 +285,10 @@ msgstr "用户管理"
 msgid "Memory"
 msgstr "内存"
 
+#: src/views/domain/DomainAdd.vue:28 src/views/domain/DomainAdd.vue:2
+msgid "Modify Config"
+msgstr "修改配置文件"
+
 #: src/views/config/Config.vue:5 src/views/domain/DomainList.vue:5
 msgid "Name"
 msgstr "名称"
@@ -285,6 +305,10 @@ msgstr "下载流量"
 msgid "Network Total Send"
 msgstr "上传流量"
 
+#: src/views/domain/DomainAdd.vue:38
+msgid "Next"
+msgstr "下一步"
+
 #: src/router/index.js:105
 msgid "Not Found"
 msgstr "找不到页面"
@@ -293,7 +317,7 @@ msgstr "找不到页面"
 msgid "Not Valid Before: %{date}"
 msgstr "此前无效: %{date}"
 
-#: src/views/domain/DomainEdit.vue:155
+#: src/views/domain/methods.js:33
 msgid ""
 "Note: The server_name in the current configuration must be the domain name "
 "you need to get the certificate."
@@ -347,18 +371,17 @@ msgstr "下载"
 msgid "Root Directory (root)"
 msgstr "网站根目录 (root)"
 
-#: src/views/config/ConfigEdit.vue:6 src/views/domain/DomainAdd.vue:6
-#: src/views/domain/DomainEdit.vue:24
+#: src/views/config/ConfigEdit.vue:6 src/views/domain/DomainEdit.vue:27
 msgid "Save"
 msgstr "保存"
 
-#: src/views/config/ConfigEdit.vue:47 src/views/domain/DomainAdd.vue:38
-#: src/views/domain/DomainEdit.vue:151
+#: src/views/config/ConfigEdit.vue:47 src/views/domain/DomainAdd.vue:43
+#: src/views/domain/DomainAdd.vue:54 src/views/domain/DomainEdit.vue:152
 msgid "Save error %{msg}"
 msgstr "保存错误 %{msg}"
 
-#: src/views/config/ConfigEdit.vue:44 src/views/domain/DomainAdd.vue:24
-#: src/views/domain/DomainEdit.vue:145
+#: src/views/config/ConfigEdit.vue:44 src/views/domain/DomainAdd.vue:33
+#: src/views/domain/DomainAdd.vue:51 src/views/domain/DomainEdit.vue:146
 msgid "Saved successfully"
 msgstr "保存成功"
 
@@ -366,7 +389,7 @@ msgstr "保存成功"
 msgid "Send"
 msgstr "上传"
 
-#: src/views/config/ConfigEdit.vue:35 src/views/domain/DomainEdit.vue:71
+#: src/views/config/ConfigEdit.vue:35 src/views/domain/DomainEdit.vue:72
 #: src/views/other/Login.vue:35
 msgid "Server error"
 msgstr "服务器错误"
@@ -383,6 +406,10 @@ msgstr "网站域名 (server_name)"
 msgid "Sites List"
 msgstr "站点列表"
 
+#: src/views/domain/DomainAdd.vue:20 src/views/domain/DomainAdd.vue:9
+msgid "Skip"
+msgstr "跳过"
+
 #: src/views/domain/DomainList.vue:11
 msgid "Status"
 msgstr "状态"
@@ -423,14 +450,15 @@ msgid ""
 "fields in your configuration file. The configuration filename cannot be "
 "changed after it has been created."
 msgstr ""
-"只有在您的配置文件中有相应字段时,下列的配置才能生效。配置文件名称创建后不"
-"修改。"
+"只有在您的配置文件中有相应字段时,下列的配置才能生效。配置文件名称创建后不"
+"修改。"
 
+#: src/views/domain/DomainAdd.vue:15 src/views/domain/DomainAdd.vue:4
 #: src/views/domain/DomainEdit.vue:11 src/views/domain/DomainEdit.vue:5
 msgid "This feature is not available in demo."
 msgstr "该功能在 Demo 中不可用。"
 
-#: src/views/domain/DomainEdit.vue:134
+#: src/views/domain/DomainEdit.vue:135
 msgid "This operation will lose the custom configuration."
 msgstr "该操作将会丢失自定义配置。"
 
@@ -455,6 +483,10 @@ msgstr "用户名 (*)"
 msgid "Writes"
 msgstr "写"
 
+#~ msgid ""
+#~ "Add site here first, then you can configure TLS on the domain edit page."
+#~ msgstr "在这里添加站点,完成后可进入编辑页面配置 TLS。"
+
 #~ msgid "Server Status"
 #~ msgstr "服务器状态"
 

BIN
frontend/src/locale/zh_TW/LC_MESSAGES/app.mo


+ 59 - 25
frontend/src/locale/zh_TW/LC_MESSAGES/app.po

@@ -11,7 +11,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: easygettext\n"
-"X-Generator: Poedit 2.2\n"
+"X-Generator: Poedit 3.0.1\n"
 
 #: src/router/index.js:99
 msgid "404 Not Found"
@@ -26,28 +26,27 @@ msgstr "關於"
 msgid "Action"
 msgstr "操作"
 
-#: src/router/index.js:47 src/views/domain/DomainAdd.vue:18
+#: src/router/index.js:47 src/views/domain/DomainAdd.vue:27
 msgid "Add Site"
 msgstr "新增站點"
 
-#: src/views/domain/DomainAdd.vue:2
-msgid ""
-"Add site here first, then you can configure TLS on the domain edit page."
-msgstr "在這裡新增站點,完成後可進入編輯頁面配置 TLS。"
-
-#: src/views/domain/DomainEdit.vue:194
+#: src/views/domain/DomainAdd.vue:86 src/views/domain/DomainEdit.vue:172
 msgid "Auto-renewal disabled for %{name}"
 msgstr "成功關閉 %{name} 自動續簽"
 
-#: src/views/domain/DomainEdit.vue:188
+#: src/views/domain/DomainAdd.vue:80 src/views/domain/DomainEdit.vue:166
 msgid "Auto-renewal enabled for %{name}"
 msgstr "成功啟用 %{name} 自動續簽"
 
+#: src/views/domain/DomainAdd.vue:37
+msgid "Base information"
+msgstr "基本訊息"
+
 #: src/views/other/About.vue:11
 msgid "Build with"
 msgstr "構建基於"
 
-#: src/views/config/ConfigEdit.vue:5 src/views/domain/DomainEdit.vue:23
+#: src/views/config/ConfigEdit.vue:5 src/views/domain/DomainEdit.vue:24
 msgid "Cancel"
 msgstr "取消"
 
@@ -79,6 +78,10 @@ msgstr "配置名稱"
 msgid "Configurations"
 msgstr "配置"
 
+#: src/views/domain/DomainAdd.vue:40
+msgid "Configure SSL"
+msgstr "配置 SSL"
+
 #: src/views/dashboard/DashBoard.vue:207
 msgid "CPU Status"
 msgstr "中央處理器狀態"
@@ -87,6 +90,10 @@ msgstr "中央處理器狀態"
 msgid "CPU:"
 msgstr "中央處理器:"
 
+#: src/views/domain/DomainAdd.vue:31 src/views/domain/DomainAdd.vue:5
+msgid "Create Another"
+msgstr "再創建一個"
+
 #: src/views/user/User.vue:23
 msgid "Created at"
 msgstr "建立時間"
@@ -107,7 +114,7 @@ msgstr "檢測到版本更新,頁面將會重新整理。"
 msgid "Development Mode"
 msgstr "開發模式"
 
-#: src/views/domain/DomainEdit.vue:196
+#: src/views/domain/DomainAdd.vue:88 src/views/domain/DomainEdit.vue:174
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "關閉 %{name} 自動續簽失敗"
 
@@ -124,10 +131,14 @@ msgstr "禁用成功"
 msgid "Disk IO"
 msgstr "磁碟 IO"
 
-#: src/views/domain/DomainEdit.vue:133
+#: src/views/domain/DomainEdit.vue:134
 msgid "Do you want to change the template to support the TLS?"
 msgstr "你想要改變模板以支援 TLS 嗎?"
 
+#: src/views/domain/DomainAdd.vue:111
+msgid "Domain Config Created Successfully"
+msgstr "域名配置文件創建成功"
+
 #: src/views/domain/DomainEdit.vue:42
 msgid "Edit %{n}"
 msgstr "編輯 %{n}"
@@ -148,11 +159,11 @@ msgstr "編輯站點"
 msgid "Email (*)"
 msgstr "郵箱 (*)"
 
-#: src/views/domain/DomainEdit.vue:190
+#: src/views/domain/DomainAdd.vue:82 src/views/domain/DomainEdit.vue:168
 msgid "Enable auto-renewal failed for %{name}"
 msgstr "啟用 %{name} 自動續簽失敗"
 
-#: src/views/domain/DomainAdd.vue:33
+#: src/views/domain/DomainAdd.vue:39
 msgid "Enable failed"
 msgstr "啟用失敗"
 
@@ -165,7 +176,7 @@ msgstr "啟用 TLS"
 msgid "Enabled"
 msgstr "啟用"
 
-#: src/views/domain/DomainAdd.vue:27 src/views/domain/DomainList.vue:46
+#: src/views/domain/DomainAdd.vue:36 src/views/domain/DomainList.vue:46
 msgid "Enabled successfully"
 msgstr "啟用成功"
 
@@ -185,11 +196,16 @@ msgstr "啟用失敗 %{msg}"
 msgid "File Not Found"
 msgstr "未找到檔案"
 
+#: src/views/domain/DomainAdd.vue:43
+msgid "Finished"
+msgstr "完成"
+
+#: src/views/domain/DomainAdd.vue:13 src/views/domain/DomainAdd.vue:2
 #: src/views/domain/DomainEdit.vue:9 src/views/domain/DomainEdit.vue:3
 msgid "Getting Certificate from Let's Encrypt"
 msgstr "從 Let's Encrypt 獲取證書"
 
-#: src/views/domain/DomainEdit.vue:156
+#: src/views/domain/methods.js:34
 msgid "Getting the certificate, please wait..."
 msgstr "正在獲取證書,請稍等..."
 
@@ -247,6 +263,7 @@ msgid "Logout successful"
 msgstr "登出成功"
 
 #: src/views/domain/DomainEdit.vue:12 src/views/domain/DomainEdit.vue:6
+#, fuzzy
 msgid ""
 "Make sure you have configured a reverse proxy for .well-known directory to "
 "HTTPChallengePort (default: 9180) before getting the certificate."
@@ -270,6 +287,10 @@ msgstr "使用者管理"
 msgid "Memory"
 msgstr "記憶體"
 
+#: src/views/domain/DomainAdd.vue:28 src/views/domain/DomainAdd.vue:2
+msgid "Modify Config"
+msgstr "修改配置"
+
 #: src/views/config/Config.vue:5 src/views/domain/DomainList.vue:5
 msgid "Name"
 msgstr "名稱"
@@ -286,6 +307,10 @@ msgstr "下載流量"
 msgid "Network Total Send"
 msgstr "上傳流量"
 
+#: src/views/domain/DomainAdd.vue:38
+msgid "Next"
+msgstr "下一步"
+
 #: src/router/index.js:105
 msgid "Not Found"
 msgstr "找不到頁面"
@@ -294,7 +319,7 @@ msgstr "找不到頁面"
 msgid "Not Valid Before: %{date}"
 msgstr "此前無效: %{date}"
 
-#: src/views/domain/DomainEdit.vue:155
+#: src/views/domain/methods.js:33
 msgid ""
 "Note: The server_name in the current configuration must be the domain name "
 "you need to get the certificate."
@@ -348,18 +373,17 @@ msgstr "下載"
 msgid "Root Directory (root)"
 msgstr "網站根目錄 (root)"
 
-#: src/views/config/ConfigEdit.vue:6 src/views/domain/DomainAdd.vue:6
-#: src/views/domain/DomainEdit.vue:24
+#: src/views/config/ConfigEdit.vue:6 src/views/domain/DomainEdit.vue:27
 msgid "Save"
 msgstr "儲存"
 
-#: src/views/config/ConfigEdit.vue:47 src/views/domain/DomainAdd.vue:38
-#: src/views/domain/DomainEdit.vue:151
+#: src/views/config/ConfigEdit.vue:47 src/views/domain/DomainAdd.vue:43
+#: src/views/domain/DomainAdd.vue:54 src/views/domain/DomainEdit.vue:152
 msgid "Save error %{msg}"
 msgstr "儲存錯誤 %{msg}"
 
-#: src/views/config/ConfigEdit.vue:44 src/views/domain/DomainAdd.vue:24
-#: src/views/domain/DomainEdit.vue:145
+#: src/views/config/ConfigEdit.vue:44 src/views/domain/DomainAdd.vue:33
+#: src/views/domain/DomainAdd.vue:51 src/views/domain/DomainEdit.vue:146
 msgid "Saved successfully"
 msgstr "儲存成功"
 
@@ -367,7 +391,7 @@ msgstr "儲存成功"
 msgid "Send"
 msgstr "上傳"
 
-#: src/views/config/ConfigEdit.vue:35 src/views/domain/DomainEdit.vue:71
+#: src/views/config/ConfigEdit.vue:35 src/views/domain/DomainEdit.vue:72
 #: src/views/other/Login.vue:35
 msgid "Server error"
 msgstr "伺服器錯誤"
@@ -384,6 +408,10 @@ msgstr "網站域名 (server_name)"
 msgid "Sites List"
 msgstr "站點列表"
 
+#: src/views/domain/DomainAdd.vue:20 src/views/domain/DomainAdd.vue:9
+msgid "Skip"
+msgstr "跳過"
+
 #: src/views/domain/DomainList.vue:11
 msgid "Status"
 msgstr "狀態"
@@ -419,6 +447,7 @@ msgid "The filename cannot contain the following characters: %{c}"
 msgstr "檔名不能包含以下字元: %{c}"
 
 #: src/views/domain/DomainEdit.vue:4
+#, fuzzy
 msgid ""
 "The following values will only take effect if you have the corresponding "
 "fields in your configuration file. The configuration filename cannot be "
@@ -427,11 +456,12 @@ msgstr ""
 "只有在您的配置檔案中有相應欄位時,下列的配置才能生效。配置檔名稱建立後不可修"
 "改。"
 
+#: src/views/domain/DomainAdd.vue:15 src/views/domain/DomainAdd.vue:4
 #: src/views/domain/DomainEdit.vue:11 src/views/domain/DomainEdit.vue:5
 msgid "This feature is not available in demo."
 msgstr "此功能在演示中不可用。"
 
-#: src/views/domain/DomainEdit.vue:134
+#: src/views/domain/DomainEdit.vue:135
 msgid "This operation will lose the custom configuration."
 msgstr "該操作將會丟失自定義配置。"
 
@@ -456,6 +486,10 @@ msgstr "使用者名稱 (*)"
 msgid "Writes"
 msgstr "寫"
 
+#~ msgid ""
+#~ "Add site here first, then you can configure TLS on the domain edit page."
+#~ msgstr "在這裡新增站點,完成後可進入編輯頁面配置 TLS。"
+
 #~ msgid "Server Status"
 #~ msgstr "伺服器狀態"
 

File diff suppressed because it is too large
+ 0 - 0
frontend/src/translations.json


+ 1 - 1
frontend/src/views/config/ConfigEdit.vue

@@ -13,7 +13,7 @@
 <script>
 import FooterToolBar from '@/components/FooterToolbar/FooterToolBar'
 import VueItextarea from '@/components/VueItextarea/VueItextarea'
-import {$gettext, $interpolate} from "@/lib/translate/gettext"
+import $gettext, {$interpolate} from "@/lib/translate/gettext";
 
 export default {
     name: 'DomainEdit',

+ 140 - 31
frontend/src/views/domain/DomainAdd.vue

@@ -1,59 +1,163 @@
 <template>
     <a-card :title="$gettext('Add Site')">
-        <p v-translate>Add site here first, then you can configure TLS on the domain edit page.</p>
-        <std-data-entry :data-list="columns" :data-source="config"/>
-        <footer-tool-bar>
-            <a-button
-                type="primary"
-                @click="save"
+        <div class="container">
+            <a-steps :current="current_step" size="small">
+                <a-step :title="$gettext('Base information')" />
+                <a-step :title="$gettext('Configure SSL')" />
+                <a-step :title="$gettext('Finished')" />
+            </a-steps>
+
+            <std-data-entry :data-list="columns" :data-source="config" :error="error" v-show="current_step===0"/>
+
+            <template v-if="current_step===1">
+                <a-button
+                    @click="issue_cert"
+                    type="primary" ghost
+                    style="margin: 10px 0"
+                    :disabled="is_demo"
+                >
+                    <translate>Getting Certificate from Let's Encrypt</translate>
+                </a-button>
+                <p v-if="is_demo" v-translate>This feature is not available in demo.</p>
+
+                <std-data-entry :data-list="columnsSSL" :data-source="config" :error="error" />
+                <a-space style="margin-right: 10px">
+                    <a-button
+                        v-if="current_step===1"
+                        @click="current_step++"
+                    >
+                        <translate>Skip</translate>
+                    </a-button>
+                </a-space>
+            </template>
+
+            <a-result
+                v-if="current_step===2"
+                status="success"
+                :title="$gettext('Domain Config Created Successfully')"
             >
-                <translate>Save</translate>
-            </a-button>
-        </footer-tool-bar>
+                <template #extra>
+                    <a-button type="primary" @click="goto_modify">
+                        <translate>Modify Config</translate>
+                    </a-button>
+                    <a-button @click="create_another">
+                        <translate>Create Another</translate>
+                    </a-button>
+                </template>
+            </a-result>
+
+            <a-space v-if="current_step<2">
+                <a-button
+                    type="primary"
+                    @click="save"
+                    :disabled="!config.name"
+                >
+                    <translate>Next</translate>
+                </a-button>
+            </a-space>
+
+        </div>
+
+
     </a-card>
 </template>
 
 <script>
-import FooterToolBar from '@/components/FooterToolbar/FooterToolBar'
 import StdDataEntry from '@/components/StdDataEntry/StdDataEntry'
-import {columns} from '@/views/domain/columns'
-import {unparse} from '@/views/domain/methods'
-import $gettext, {$interpolate} from "@/lib/translate/gettext";
+import {columns, columnsSSL} from '@/views/domain/columns'
+import {unparse, issue_cert} from '@/views/domain/methods'
+import $gettext, {$interpolate} from "@/lib/translate/gettext"
 
 export default {
     name: 'DomainAdd',
-    components: {StdDataEntry, FooterToolBar},
+    components: {StdDataEntry},
     data() {
         return {
-            config: {},
-            columns: columns.slice(0, -1) // 隐藏SSL支持开关
+            config: {
+                http_listen_port: 80,
+                https_listen_port: 443
+            },
+            columns: columns.slice(0, -1), // 隐藏SSL支持开关
+            error: {},
+            current_step: 0,
+            columnsSSL
         }
     },
-    beforeCreate() {
-
+    watch: {
+        'config.auto_cert'() {
+            this.change_auto_cert()
+        }
     },
     methods: {
         save() {
-            this.$api.domain.get_template('http-conf').then(r => {
-                let text = unparse(r.template, this.config)
-                this.$api.domain.save(this.config.name, {content: text, enabled: true}).then(() => {
-                    this.$message.success($gettext('Saved successfully'))
+            if (this.current_step===0) {
+                this.$api.domain.get_template('http-conf').then(r => {
+                    let text = unparse(r.template, this.config)
 
-                    this.$api.domain.enable(this.config.name).then(() => {
-                        this.$message.success($gettext('Enabled successfully'))
+                    this.$api.domain.save(this.config.name, {content: text, enabled: true}).then(() => {
+                        this.$message.success($gettext('Saved successfully'))
 
-                        this.$router.push('/domain/' + this.config.name)
+                        this.$api.domain.enable(this.config.name).then(() => {
+                            this.$message.success($gettext('Enabled successfully'))
+                            this.current_step++
+                        }).catch(r => {
+                            this.$message.error(r.message ?? $gettext('Enable failed'), 10)
+                        })
 
                     }).catch(r => {
-                        console.log(r)
-                        this.$message.error(r.message ?? $gettext('Enable failed'), 10)
+                        this.$message.error($interpolate($gettext('Save error %{msg}'), {msg: r.message ?? ""}), 10)
                     })
+                })
+            } else if (this.current_step === 1) {
+                this.$api.domain.get_template('https-conf').then(r => {
+                    let text = unparse(r.template, this.config)
+
+                    this.$api.domain.save(this.config.name, {content: text, enabled: true}).then(() => {
+                        this.$message.success($gettext('Saved successfully'))
+                        this.current_step++
+                    }).catch(r => {
+                        this.$message.error($interpolate($gettext('Save error %{msg}'), {msg: r.message ?? ""}), 10)
+                    })
+                })
+            }
 
-                }).catch(r => {
-                    console.log(r)
-                    this.$message.error($interpolate($gettext('Save error %{msg}'), {msg: r.message ?? ""}), 10)
+        },
+        issue_cert() {
+            issue_cert(this.config.server_name, this.callback)
+        },
+        callback(ssl_certificate, ssl_certificate_key) {
+            this.$set(this.config, 'ssl_certificate', ssl_certificate)
+            this.$set(this.config, 'ssl_certificate_key', ssl_certificate_key)
+        },
+        goto_modify() {
+            this.$router.push('/domain/'+this.config.name)
+        },
+        create_another() {
+            this.current_step = 0
+            this.config = {
+                http_listen_port: 80,
+                https_listen_port: 443
+            }
+        },
+        change_auto_cert() {
+            if (this.config.auto_cert) {
+                this.$api.domain.add_auto_cert(this.config.name).then(() => {
+                    this.$message.success($interpolate($gettext('Auto-renewal enabled for %{name}'), {name: this.config.name}))
+                }).catch(e => {
+                    this.$message.error(e.message ?? $interpolate($gettext('Enable auto-renewal failed for %{name}'), {name: this.config.name}))
                 })
-            })
+            } else {
+                this.$api.domain.remove_auto_cert(this.config.name).then(() => {
+                    this.$message.success($interpolate($gettext('Auto-renewal disabled for %{name}'), {name: this.config.name}))
+                }).catch(e => {
+                    this.$message.error(e.message ?? $interpolate($gettext('Disable auto-renewal failed for %{name}'), {name: this.config.name}))
+                })
+            }
+        }
+    },
+    computed: {
+        is_demo() {
+            return this.$store.getters.env.demo === true
         }
     }
 }
@@ -63,4 +167,9 @@ export default {
 .ant-steps {
     padding: 10px 0 20px 0;
 }
+
+.container {
+    max-width: 800px;
+    margin: 0 auto
+}
 </style>

+ 21 - 39
frontend/src/views/domain/DomainEdit.vue

@@ -26,8 +26,12 @@
 
         <footer-tool-bar>
             <a-space>
-                <a-button @click="$router.go(-1)"><translate>Cancel</translate></a-button>
-                <a-button type="primary" @click="save"><translate>Save</translate></a-button>
+                <a-button @click="$router.go(-1)">
+                    <translate>Cancel</translate>
+                </a-button>
+                <a-button type="primary" @click="save">
+                    <translate>Save</translate>
+                </a-button>
             </a-space>
         </footer-tool-bar>
     </div>
@@ -39,9 +43,10 @@ import StdDataEntry from '@/components/StdDataEntry/StdDataEntry'
 import FooterToolBar from '@/components/FooterToolbar/FooterToolBar'
 import VueItextarea from '@/components/VueItextarea/VueItextarea'
 import {columns, columnsSSL} from '@/views/domain/columns'
-import {unparse} from '@/views/domain/methods'
+import {unparse, issue_cert} from '@/views/domain/methods'
 import CertInfo from '@/views/domain/CertInfo'
-import {$gettext, $interpolate} from "@/lib/translate/gettext"
+import {$gettext, $interpolate} from '@/lib/translate/gettext'
+
 
 export default {
     name: 'DomainEdit',
@@ -185,52 +190,29 @@ export default {
                 }
             }).catch(r => {
                 console.log(r)
-                this.$message.error($interpolate($gettext('Save error %{msg}'), {msg: r.message ?? ""}), 10)
+                this.$message.error($interpolate($gettext('Save error %{msg}'), {msg: r.message ?? ''}), 10)
             })
         },
         issue_cert() {
-            this.$message.info($gettext('Note: The server_name in the current configuration must be the domain name you need to get the certificate.'), 15)
-            this.$message.info($gettext('Getting the certificate, please wait...'), 15)
-            this.ws = new WebSocket(this.getWebSocketRoot() + '/cert/issue/' + this.config.server_name
-                + '?token=' + btoa(this.$store.state.user.token))
-
-            this.ws.onopen = () => {
-                this.ws.send('go')
-            }
-
-            this.ws.onmessage = m => {
-                const r = JSON.parse(m.data)
-                switch (r.status) {
-                    case 'success':
-                        this.$message.success(r.message, 10)
-                        break
-                    case 'info':
-                        this.$message.info(r.message, 10)
-                        break
-                    case 'error':
-                        this.$message.error(r.message, 10)
-                        break
-                }
-
-                if (r.status === 'success' && r.ssl_certificate !== undefined && r.ssl_certificate_key !== undefined) {
-                    this.config.ssl_certificate = r.ssl_certificate
-                    this.config.ssl_certificate_key = r.ssl_certificate_key
-                    if (this.$refs['cert-info']) this.$refs['cert-info'].get()
-                }
-            }
+            issue_cert(this.config.server_name, this.callback)
+        },
+        callback(ssl_certificate, ssl_certificate_key) {
+            this.$set(this.config, 'ssl_certificate', ssl_certificate)
+            this.$set(this.config, 'ssl_certificate_key', ssl_certificate_key)
+            if (this.$refs['cert-info']) this.$refs['cert-info'].get()
         },
         change_auto_cert() {
             if (this.config.auto_cert) {
                 this.$api.domain.add_auto_cert(this.name).then(() => {
-                    this.$message.success($interpolate($gettext('Auto-renewal enabled for %{name}'), {name: this.name}))
+                    this.$message.success($interpolate($gettext('Auto-renewal enabled for %{name}', {name: this.name})))
                 }).catch(e => {
-                    this.$message.error(e.message ?? $interpolate($gettext('Enable auto-renewal failed for %{name}'), {name: this.name}))
+                    this.$message.error(e.message ?? $interpolate($gettext('Enable auto-renewal failed for %{name}', {name: this.name})))
                 })
             } else {
                 this.$api.domain.remove_auto_cert(this.name).then(() => {
-                    this.$message.success($interpolate($gettext('Auto-renewal disabled for %{name}'), {name: this.name}))
+                    this.$message.success($interpolate($gettext('Auto-renewal disabled for %{name}', {name: this.name})))
                 }).catch(e => {
-                    this.$message.error(e.message ?? $interpolate($gettext('Disable auto-renewal failed for %{name}'), {name: this.name}))
+                    this.$message.error(e.message ?? $interpolate($gettext('Disable auto-renewal failed for %{name}', {name: this.name})))
                 })
             }
         }
@@ -246,7 +228,7 @@ export default {
             }
         },
         is_demo() {
-            return this.$store.getters.env.demo===true
+            return this.$store.getters.env.demo === true
         }
     }
 }

+ 34 - 1
frontend/src/views/domain/methods.js

@@ -1,3 +1,6 @@
+import $gettext from '@/lib/translate/gettext'
+import store from '@/lib/store'
+import Vue from 'vue'
 const unparse = (text, config) => {
     // http_listen_port: /listen (.*);/i,
     // https_listen_port: /listen (.*) ssl/i,
@@ -26,4 +29,34 @@ const unparse = (text, config) => {
     return text
 }
 
-export {unparse}
+const issue_cert = (server_name, callback) => {
+    Vue.prototype.$message.info($gettext('Note: The server_name in the current configuration must be the domain name you need to get the certificate.'), 15)
+    Vue.prototype.$message.info($gettext('Getting the certificate, please wait...'), 15)
+    const ws = new WebSocket(Vue.prototype.getWebSocketRoot() + '/cert/issue/' + server_name
+        + '?token=' + btoa(store.state.user.token))
+
+    ws.onopen = () => {
+        ws.send('go')
+    }
+
+    ws.onmessage = m => {
+        const r = JSON.parse(m.data)
+        switch (r.status) {
+            case 'success':
+                Vue.prototype.$message.success(r.message, 10)
+                break
+            case 'info':
+                Vue.prototype.$message.info(r.message, 10)
+                break
+            case 'error':
+                Vue.prototype.$message.error(r.message, 10)
+                break
+        }
+
+        if (r.status === 'success' && r.ssl_certificate !== undefined && r.ssl_certificate_key !== undefined) {
+            callback(r.ssl_certificate, r.ssl_certificate_key)
+        }
+    }
+}
+
+export {unparse, issue_cert}

+ 2 - 1
frontend/version.json

@@ -1 +1,2 @@
-{"version":"1.2.2","build_id":1,"total_build":49}
+{"version":"1.3.0","build_id":1,"total_build":51}
+

File diff suppressed because it is too large
+ 557 - 348
frontend/yarn.lock


+ 3 - 2
server/api/cert.go

@@ -4,6 +4,7 @@ import (
     "encoding/json"
     "github.com/0xJacky/Nginx-UI/server/settings"
     "github.com/0xJacky/Nginx-UI/server/tool"
+    "github.com/0xJacky/Nginx-UI/server/tool/nginx"
     "github.com/gin-gonic/gin"
     "github.com/gorilla/websocket"
     "log"
@@ -96,7 +97,7 @@ func IssueCert(c *gin.Context) {
                 return
             }
 
-            sslCertificatePath := tool.GetNginxConfPath("ssl/" + domain + "/fullchain.cer")
+            sslCertificatePath := nginx.GetNginxConfPath("ssl/" + domain + "/fullchain.cer")
             _, err = os.Stat(sslCertificatePath)
 
             if err != nil {
@@ -122,7 +123,7 @@ func IssueCert(c *gin.Context) {
                 return
             }
 
-            sslCertificateKeyPath := tool.GetNginxConfPath("ssl/" + domain + "/" + domain + ".key")
+            sslCertificateKeyPath := nginx.GetNginxConfPath("ssl/" + domain + "/" + domain + ".key")
             _, err = os.Stat(sslCertificateKeyPath)
 
             if err != nil {

+ 7 - 6
server/api/config.go

@@ -2,6 +2,7 @@ package api
 
 import (
 	"github.com/0xJacky/Nginx-UI/server/tool"
+	"github.com/0xJacky/Nginx-UI/server/tool/nginx"
 	"github.com/gin-gonic/gin"
 	"io/ioutil"
 	"log"
@@ -19,7 +20,7 @@ func GetConfigs(c *gin.Context) {
 		"modify": "time",
 	}
 
-	configFiles, err := ioutil.ReadDir(tool.GetNginxConfPath("/"))
+	configFiles, err := ioutil.ReadDir(nginx.GetNginxConfPath("/"))
 
 	if err != nil {
 		ErrHandler(c, err)
@@ -49,7 +50,7 @@ func GetConfigs(c *gin.Context) {
 
 func GetConfig(c *gin.Context) {
 	name := c.Param("name")
-	path := filepath.Join(tool.GetNginxConfPath("/"), name)
+	path := filepath.Join(nginx.GetNginxConfPath("/"), name)
 
 	content, err := ioutil.ReadFile(path)
 
@@ -80,7 +81,7 @@ func AddConfig(c *gin.Context) {
 	name := request.Name
 	content := request.Content
 
-	path := filepath.Join(tool.GetNginxConfPath("/"), name)
+	path := filepath.Join(nginx.GetNginxConfPath("/"), name)
 
 	log.Println(path)
 	if _, err = os.Stat(path); err == nil {
@@ -98,7 +99,7 @@ func AddConfig(c *gin.Context) {
 		}
 	}
 
-	output := tool.ReloadNginx()
+	output := nginx.ReloadNginx()
 
 	if output != "" {
 		c.JSON(http.StatusInternalServerError, gin.H{
@@ -126,7 +127,7 @@ func EditConfig(c *gin.Context) {
 		ErrHandler(c, err)
 		return
 	}
-	path := filepath.Join(tool.GetNginxConfPath("/"), name)
+	path := filepath.Join(nginx.GetNginxConfPath("/"), name)
 	content := request.Content
 
 	origContent, err := ioutil.ReadFile(path)
@@ -144,7 +145,7 @@ func EditConfig(c *gin.Context) {
 		}
 	}
 
-	output := tool.ReloadNginx()
+	output := nginx.ReloadNginx()
 
 	if output != "" {
 		c.JSON(http.StatusInternalServerError, gin.H{

+ 30 - 21
server/api/domain.go

@@ -3,6 +3,7 @@ package api
 import (
 	"github.com/0xJacky/Nginx-UI/server/model"
 	"github.com/0xJacky/Nginx-UI/server/tool"
+	"github.com/0xJacky/Nginx-UI/server/tool/nginx"
 	"github.com/gin-gonic/gin"
 	"io/ioutil"
 	"net/http"
@@ -20,25 +21,25 @@ func GetDomains(c *gin.Context) {
 		"modify":  "time",
 	}
 
-	configFiles, err := ioutil.ReadDir(tool.GetNginxConfPath("sites-available"))
+	configFiles, err := ioutil.ReadDir(nginx.GetNginxConfPath("sites-available"))
 
 	if err != nil {
 		ErrHandler(c, err)
 		return
 	}
 
-	enabledConfig, err := ioutil.ReadDir(filepath.Join(tool.GetNginxConfPath("sites-enabled")))
-
-	enabledConfigMap := make(map[string]bool)
-	for i := range enabledConfig {
-		enabledConfigMap[enabledConfig[i].Name()] = true
-	}
+	enabledConfig, err := ioutil.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled")))
 
 	if err != nil {
 		ErrHandler(c, err)
 		return
 	}
 
+	enabledConfigMap := make(map[string]bool)
+	for i := range enabledConfig {
+		enabledConfigMap[enabledConfig[i].Name()] = true
+	}
+
 	var configs []gin.H
 
 	for i := range configFiles {
@@ -62,10 +63,10 @@ func GetDomains(c *gin.Context) {
 
 func GetDomain(c *gin.Context) {
 	name := c.Param("name")
-	path := filepath.Join(tool.GetNginxConfPath("sites-available"), name)
+	path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name)
 
 	enabled := true
-	if _, err := os.Stat(filepath.Join(tool.GetNginxConfPath("sites-enabled"), name)); os.IsNotExist(err) {
+	if _, err := os.Stat(filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)); os.IsNotExist(err) {
 		enabled = false
 	}
 
@@ -98,7 +99,7 @@ func EditDomain(c *gin.Context) {
 	name := c.Param("name")
 	request := make(gin.H)
 	err = c.BindJSON(&request)
-	path := filepath.Join(tool.GetNginxConfPath("sites-available"), name)
+	path := filepath.Join(nginx.GetNginxConfPath("sites-available"), name)
 
 	err = ioutil.WriteFile(path, []byte(request["content"].(string)), 0644)
 	if err != nil {
@@ -106,10 +107,10 @@ func EditDomain(c *gin.Context) {
 		return
 	}
 
-	enabledConfigFilePath := filepath.Join(tool.GetNginxConfPath("sites-enabled"), name)
+	enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)
 	if _, err = os.Stat(enabledConfigFilePath); err == nil {
 		// 测试配置文件
-		err = tool.TestNginxConf(enabledConfigFilePath)
+		err = nginx.TestNginxConf()
 		if err != nil {
 			c.JSON(http.StatusInternalServerError, gin.H{
 				"message": err.Error(),
@@ -117,7 +118,7 @@ func EditDomain(c *gin.Context) {
 			return
 		}
 
-		output := tool.ReloadNginx()
+		output := nginx.ReloadNginx()
 
 		if output != "" {
 			c.JSON(http.StatusInternalServerError, gin.H{
@@ -131,8 +132,8 @@ func EditDomain(c *gin.Context) {
 }
 
 func EnableDomain(c *gin.Context) {
-	configFilePath := filepath.Join(tool.GetNginxConfPath("sites-available"), c.Param("name"))
-	enabledConfigFilePath := filepath.Join(tool.GetNginxConfPath("sites-enabled"), c.Param("name"))
+	configFilePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), c.Param("name"))
+	enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name"))
 
 	_, err := os.Stat(configFilePath)
 
@@ -149,7 +150,7 @@ func EnableDomain(c *gin.Context) {
 	}
 
 	// 测试配置文件,不通过则撤回启用
-	err = tool.TestNginxConf(enabledConfigFilePath)
+	err = nginx.TestNginxConf()
 	if err != nil {
 		_ = os.Remove(enabledConfigFilePath)
 		c.JSON(http.StatusInternalServerError, gin.H{
@@ -158,7 +159,7 @@ func EnableDomain(c *gin.Context) {
 		return
 	}
 
-	output := tool.ReloadNginx()
+	output := nginx.ReloadNginx()
 
 	if output != "" {
 		c.JSON(http.StatusInternalServerError, gin.H{
@@ -173,7 +174,7 @@ func EnableDomain(c *gin.Context) {
 }
 
 func DisableDomain(c *gin.Context) {
-	enabledConfigFilePath := filepath.Join(tool.GetNginxConfPath("sites-enabled"), c.Param("name"))
+	enabledConfigFilePath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), c.Param("name"))
 
 	_, err := os.Stat(enabledConfigFilePath)
 
@@ -189,7 +190,15 @@ func DisableDomain(c *gin.Context) {
 		return
 	}
 
-	output := tool.ReloadNginx()
+	// delete auto cert record
+	cert := model.Cert{Domain: c.Param("name")}
+	err = cert.Remove()
+	if err != nil {
+		ErrHandler(c, err)
+		return
+	}
+
+	output := nginx.ReloadNginx()
 
 	if output != "" {
 		c.JSON(http.StatusInternalServerError, gin.H{
@@ -206,8 +215,8 @@ func DisableDomain(c *gin.Context) {
 func DeleteDomain(c *gin.Context) {
 	var err error
 	name := c.Param("name")
-	availablePath := filepath.Join(tool.GetNginxConfPath("sites-available"), name)
-	enabledPath := filepath.Join(tool.GetNginxConfPath("sites-enabled"), name)
+	availablePath := filepath.Join(nginx.GetNginxConfPath("sites-available"), name)
+	enabledPath := filepath.Join(nginx.GetNginxConfPath("sites-enabled"), name)
 
 	if _, err = os.Stat(availablePath); os.IsNotExist(err) {
 		c.JSON(http.StatusNotFound, gin.H{

+ 27 - 1
server/model/cert.go

@@ -1,5 +1,11 @@
 package model
 
+import (
+	"github.com/0xJacky/Nginx-UI/server/tool/nginx"
+	"io/ioutil"
+	"path/filepath"
+)
+
 type Cert struct {
 	Model
 	Domain string `json:"domain"`
@@ -19,7 +25,27 @@ func FirstOrCreateCert(domain string) (c Cert, err error) {
 }
 
 func GetAutoCertList() (c []Cert) {
-	db.Find(&c)
+	var t []Cert
+	db.Find(&t)
+	// check if this domain is enabled
+
+	enabledConfig, err := ioutil.ReadDir(filepath.Join(nginx.GetNginxConfPath("sites-enabled")))
+
+	if err != nil {
+		return
+	}
+
+	enabledConfigMap := make(map[string]bool)
+	for i := range enabledConfig {
+		enabledConfigMap[enabledConfig[i].Name()] = true
+	}
+
+	for _, v := range t {
+		if enabledConfigMap[v.Domain] == true {
+			c = append(c, v)
+		}
+	}
+
 	return
 }
 

+ 2 - 2
server/test/acme_test.go

@@ -2,7 +2,7 @@ package test
 
 import (
 	"fmt"
-	"github.com/0xJacky/Nginx-UI/server/tool"
+	"github.com/0xJacky/Nginx-UI/server/tool/nginx"
 	"io/ioutil"
 	"log"
 	"os"
@@ -46,7 +46,7 @@ func TestAcme(t *testing.T) {
 				"install",
 				"--log",
 				"--home", "/usr/local/acme.sh",
-				"--cert-home", tool.GetNginxConfPath("ssl")).
+				"--cert-home", nginx.GetNginxConfPath("ssl")).
 				CombinedOutput()
 			if err != nil {
 				log.Println(err)

+ 3 - 3
server/test/cert_test.go

@@ -2,7 +2,7 @@ package test
 
 import (
 	"fmt"
-	"github.com/0xJacky/Nginx-UI/server/tool"
+	"github.com/0xJacky/Nginx-UI/server/tool/nginx"
 	"log"
 	"os"
 	"os/exec"
@@ -20,14 +20,14 @@ func TestCert(t *testing.T) {
 	}
 	fmt.Printf("%s\n", out)
 
-	_, err = os.Stat(tool.GetNginxConfPath("ssl/test.ojbk.me/fullchain.cer"))
+	_, err = os.Stat(nginx.GetNginxConfPath("ssl/test.ojbk.me/fullchain.cer"))
 
 	if err != nil {
 		log.Println(err)
 		return
 	}
 	log.Println("[found]", "fullchain.cer")
-	_, err = os.Stat(tool.GetNginxConfPath("ssl/test.ojbk.me/test.ojbk.me.key"))
+	_, err = os.Stat(nginx.GetNginxConfPath("ssl/test.ojbk.me/test.ojbk.me.key"))
 
 	if err != nil {
 		log.Println(err)

+ 147 - 146
server/tool/cert.go

@@ -1,178 +1,179 @@
 package tool
 
 import (
-    "crypto"
-    "crypto/ecdsa"
-    "crypto/elliptic"
-    "crypto/rand"
-    "crypto/tls"
-    "crypto/x509"
-    "github.com/0xJacky/Nginx-UI/server/model"
-    "github.com/0xJacky/Nginx-UI/server/settings"
-    "github.com/go-acme/lego/v4/certcrypto"
-    "github.com/go-acme/lego/v4/certificate"
-    "github.com/go-acme/lego/v4/challenge/http01"
-    "github.com/go-acme/lego/v4/lego"
-    "github.com/go-acme/lego/v4/registration"
-    "io"
-    "io/ioutil"
-    "log"
-    "net/http"
-    "os"
-    "path/filepath"
-    "time"
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/tls"
+	"crypto/x509"
+	"github.com/0xJacky/Nginx-UI/server/model"
+	"github.com/0xJacky/Nginx-UI/server/settings"
+	"github.com/0xJacky/Nginx-UI/server/tool/nginx"
+	"github.com/go-acme/lego/v4/certcrypto"
+	"github.com/go-acme/lego/v4/certificate"
+	"github.com/go-acme/lego/v4/challenge/http01"
+	"github.com/go-acme/lego/v4/lego"
+	"github.com/go-acme/lego/v4/registration"
+	"io"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"os"
+	"path/filepath"
+	"time"
 )
 
 // MyUser You'll need a user or account type that implements acme.User
 type MyUser struct {
-    Email        string
-    Registration *registration.Resource
-    key          crypto.PrivateKey
+	Email        string
+	Registration *registration.Resource
+	key          crypto.PrivateKey
 }
 
 func (u *MyUser) GetEmail() string {
-    return u.Email
+	return u.Email
 }
 func (u MyUser) GetRegistration() *registration.Resource {
-    return u.Registration
+	return u.Registration
 }
 func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
-    return u.key
+	return u.key
 }
 
 func AutoCert() {
-    for {
-        log.Println("[AutoCert] Start")
-        autoCertList := model.GetAutoCertList()
-        for i := range autoCertList {
-            domain := autoCertList[i].Domain
-            key, err := GetCertInfo(domain)
-            if err != nil {
-                // 获取证书信息失败,本次跳过
-                continue
-            }
-            // 未到一个月
-            if time.Now().Before(key.NotBefore.AddDate(0, 1, 0)) {
-                continue
-            }
-            // 过一个月了,重新申请证书
-            err = IssueCert(domain)
-            if err != nil {
-                log.Println(err)
-            }
-        }
-        time.Sleep(1 * time.Hour)
-    }
+	for {
+		log.Println("[AutoCert] Start")
+		autoCertList := model.GetAutoCertList()
+		for i := range autoCertList {
+			domain := autoCertList[i].Domain
+			key, err := GetCertInfo(domain)
+			if err != nil {
+				// 获取证书信息失败,本次跳过
+				continue
+			}
+			// 未到一个月
+			if time.Now().Before(key.NotBefore.AddDate(0, 1, 0)) {
+				continue
+			}
+			// 过一个月了,重新申请证书
+			err = IssueCert(domain)
+			if err != nil {
+				log.Println(err)
+			}
+		}
+		time.Sleep(1 * time.Hour)
+	}
 }
 
 func GetCertInfo(domain string) (key *x509.Certificate, err error) {
 
-    var response *http.Response
+	var response *http.Response
 
-    ts := &http.Transport{
-        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
-    }
+	ts := &http.Transport{
+		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+	}
 
-    client := &http.Client{Transport: ts}
+	client := &http.Client{Transport: ts}
 
-    response, err = client.Get("https://" + domain)
+	response, err = client.Get("https://" + domain)
 
-    if err != nil {
-        return
-    }
+	if err != nil {
+		return
+	}
 
-    defer func(Body io.ReadCloser) {
-        err = Body.Close()
-        if err != nil {
-            log.Println(err)
-            return
-        }
-    }(response.Body)
+	defer func(Body io.ReadCloser) {
+		err = Body.Close()
+		if err != nil {
+			log.Println(err)
+			return
+		}
+	}(response.Body)
 
-    key = response.TLS.PeerCertificates[0]
+	key = response.TLS.PeerCertificates[0]
 
-    return
+	return
 }
 
 func IssueCert(domain string) error {
-    // Create a user. New accounts need an email and private key to start.
-    privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-    if err != nil {
-        log.Println(err)
-        return err
-    }
-
-    myUser := MyUser{
-        Email: settings.ServerSettings.Email,
-        key:   privateKey,
-    }
-
-    config := lego.NewConfig(&myUser)
-
-    if settings.ServerSettings.Demo {
-        config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory"
-    }
-    config.Certificate.KeyType = certcrypto.RSA2048
-
-    // A client facilitates communication with the CA server.
-    client, err := lego.NewClient(config)
-    if err != nil {
-        log.Println(err)
-        return err
-    }
-
-    err = client.Challenge.SetHTTP01Provider(
-        http01.NewProviderServer("",
-            settings.ServerSettings.HTTPChallengePort,
-        ),
-    )
-    if err != nil {
-        log.Println(err)
-        return err
-    }
-
-    // New users will need to register
-    reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
-    if err != nil {
-        log.Println(err)
-        return err
-    }
-    myUser.Registration = reg
-
-    request := certificate.ObtainRequest{
-        Domains: []string{domain},
-        Bundle:  true,
-    }
-    certificates, err := client.Certificate.Obtain(request)
-    if err != nil {
-        log.Println(err)
-        return err
-    }
-    saveDir := GetNginxConfPath("ssl/" + domain)
-    if _, err := os.Stat(saveDir); os.IsNotExist(err) {
-        err = os.Mkdir(saveDir, 0755)
-        if err != nil {
-            log.Println("fail to create", saveDir)
-            return err
-        }
-    }
-
-    // Each certificate comes back with the cert bytes, the bytes of the client's
-    // private key, and a certificate URL. SAVE THESE TO DISK.
-    err = ioutil.WriteFile(filepath.Join(saveDir, "fullchain.cer"),
-        certificates.Certificate, 0644)
-    if err != nil {
-        log.Println(err)
-        return err
-    }
-    err = ioutil.WriteFile(filepath.Join(saveDir, domain+".key"),
-        certificates.PrivateKey, 0644)
-    if err != nil {
-        log.Println(err)
-        return err
-    }
-
-    ReloadNginx()
-
-    return nil
+	// Create a user. New accounts need an email and private key to start.
+	privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		log.Println(err)
+		return err
+	}
+
+	myUser := MyUser{
+		Email: settings.ServerSettings.Email,
+		key:   privateKey,
+	}
+
+	config := lego.NewConfig(&myUser)
+
+	if settings.ServerSettings.Demo {
+		config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory"
+	}
+	config.Certificate.KeyType = certcrypto.RSA2048
+
+	// A client facilitates communication with the CA server.
+	client, err := lego.NewClient(config)
+	if err != nil {
+		log.Println(err)
+		return err
+	}
+
+	err = client.Challenge.SetHTTP01Provider(
+		http01.NewProviderServer("",
+			settings.ServerSettings.HTTPChallengePort,
+		),
+	)
+	if err != nil {
+		log.Println(err)
+		return err
+	}
+
+	// New users will need to register
+	reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
+	if err != nil {
+		log.Println(err)
+		return err
+	}
+	myUser.Registration = reg
+
+	request := certificate.ObtainRequest{
+		Domains: []string{domain},
+		Bundle:  true,
+	}
+	certificates, err := client.Certificate.Obtain(request)
+	if err != nil {
+		log.Println(err)
+		return err
+	}
+	saveDir := nginx.GetNginxConfPath("ssl/" + domain)
+	if _, err := os.Stat(saveDir); os.IsNotExist(err) {
+		err = os.Mkdir(saveDir, 0755)
+		if err != nil {
+			log.Println("fail to create", saveDir)
+			return err
+		}
+	}
+
+	// Each certificate comes back with the cert bytes, the bytes of the client's
+	// private key, and a certificate URL. SAVE THESE TO DISK.
+	err = ioutil.WriteFile(filepath.Join(saveDir, "fullchain.cer"),
+		certificates.Certificate, 0644)
+	if err != nil {
+		log.Println(err)
+		return err
+	}
+	err = ioutil.WriteFile(filepath.Join(saveDir, domain+".key"),
+		certificates.PrivateKey, 0644)
+	if err != nil {
+		log.Println(err)
+		return err
+	}
+
+	nginx.ReloadNginx()
+
+	return nil
 }

+ 2 - 2
server/tool/nginx.go → server/tool/nginx/nginx.go

@@ -1,4 +1,4 @@
-package tool
+package nginx
 
 import (
 	"errors"
@@ -9,7 +9,7 @@ import (
 	"strings"
 )
 
-func TestNginxConf(filePath string) error {
+func TestNginxConf() error {
 	out, err := exec.Command("nginx", "-t").CombinedOutput()
 	if err != nil {
 		log.Println(err)

Some files were not shown because too many files changed in this diff