|
@@ -3,14 +3,18 @@
|
|
<a-collapse :bordered="false" default-active-key="1">
|
|
<a-collapse :bordered="false" default-active-key="1">
|
|
<a-collapse-panel key="1" :header="name ? '编辑站点:' + name : '添加站点'">
|
|
<a-collapse-panel key="1" :header="name ? '编辑站点:' + name : '添加站点'">
|
|
<p>您的配置文件中应当有对应的字段时,下列表单中的设置才能生效,配置文件名称创建后不可修改。</p>
|
|
<p>您的配置文件中应当有对应的字段时,下列表单中的设置才能生效,配置文件名称创建后不可修改。</p>
|
|
- <std-data-entry :data-list="columns" v-model="config" />
|
|
|
|
- <cert-info :domain="name" ref="cert-info" v-if="name"/>
|
|
|
|
- <br/>
|
|
|
|
- <a-space>
|
|
|
|
|
|
+ <std-data-entry :data-list="columns" v-model="config"/>
|
|
|
|
+ <template v-if="config.support_ssl">
|
|
|
|
+ <cert-info :domain="name" ref="cert-info" v-if="name"/>
|
|
|
|
+ <br/>
|
|
<a-button @click="issue_cert" type="primary" ghost>
|
|
<a-button @click="issue_cert" type="primary" ghost>
|
|
自动申请 Let's Encrypt 证书
|
|
自动申请 Let's Encrypt 证书
|
|
</a-button>
|
|
</a-button>
|
|
- </a-space>
|
|
|
|
|
|
+ <p><br/>点击自动申请证书将会从 Let's Encrypt 获得签发证书
|
|
|
|
+ 在获取签发证书前,请确保配置文件中已为
|
|
|
|
+ <code>/.well-known</code> 目录反向代理到后端的
|
|
|
|
+ <code>HTTPChallengePort (default:9180)</code></p>
|
|
|
|
+ </template>
|
|
</a-collapse-panel>
|
|
</a-collapse-panel>
|
|
</a-collapse>
|
|
</a-collapse>
|
|
|
|
|
|
@@ -20,7 +24,7 @@
|
|
|
|
|
|
<footer-tool-bar>
|
|
<footer-tool-bar>
|
|
<a-space>
|
|
<a-space>
|
|
- <a-button @click="$router.go(-1)">返回</a-button>
|
|
|
|
|
|
+ <a-button @click="$router.push('/domain/list')">返回</a-button>
|
|
<a-button type="primary" @click="save">保存</a-button>
|
|
<a-button type="primary" @click="save">保存</a-button>
|
|
</a-space>
|
|
</a-space>
|
|
</footer-tool-bar>
|
|
</footer-tool-bar>
|
|
@@ -32,16 +36,16 @@
|
|
import StdDataEntry from "@/components/StdDataEntry/StdDataEntry"
|
|
import StdDataEntry from "@/components/StdDataEntry/StdDataEntry"
|
|
import FooterToolBar from "@/components/FooterToolbar/FooterToolBar"
|
|
import FooterToolBar from "@/components/FooterToolbar/FooterToolBar"
|
|
import VueItextarea from "@/components/VueItextarea/VueItextarea"
|
|
import VueItextarea from "@/components/VueItextarea/VueItextarea"
|
|
-import columns from "@/views/domain_edit/columns"
|
|
|
|
-import CertInfo from "@/views/domain_edit/CertInfo";
|
|
|
|
|
|
+import {columns, columnsSSL} from "@/views/domain/columns"
|
|
|
|
+import {unparse} from "@/views/domain/methods"
|
|
|
|
+import CertInfo from "@/views/domain/CertInfo"
|
|
|
|
|
|
export default {
|
|
export default {
|
|
name: "DomainEdit",
|
|
name: "DomainEdit",
|
|
components: {CertInfo, FooterToolBar, StdDataEntry, VueItextarea},
|
|
components: {CertInfo, FooterToolBar, StdDataEntry, VueItextarea},
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
- name: this.$route.params.name,
|
|
|
|
- columns,
|
|
|
|
|
|
+ name: this.$route.params.name.toString(),
|
|
config: {
|
|
config: {
|
|
http_listen_port: 80,
|
|
http_listen_port: 80,
|
|
https_listen_port: null,
|
|
https_listen_port: null,
|
|
@@ -50,7 +54,8 @@ export default {
|
|
root: "",
|
|
root: "",
|
|
ssl_certificate: "",
|
|
ssl_certificate: "",
|
|
ssl_certificate_key: "",
|
|
ssl_certificate_key: "",
|
|
- support_ssl: false
|
|
|
|
|
|
+ support_ssl: false,
|
|
|
|
+ auto_cert: false
|
|
},
|
|
},
|
|
configText: "",
|
|
configText: "",
|
|
ws: null,
|
|
ws: null,
|
|
@@ -68,7 +73,14 @@ export default {
|
|
deep: true
|
|
deep: true
|
|
},
|
|
},
|
|
'config.support_ssl'() {
|
|
'config.support_ssl'() {
|
|
- if (this.ok) this.change_support_ssl()
|
|
|
|
|
|
+ if (this.ok) {
|
|
|
|
+ this.change_support_ssl()
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ 'config.auto_cert'() {
|
|
|
|
+ if (this.ok) {
|
|
|
|
+ this.change_auto_cert()
|
|
|
|
+ }
|
|
}
|
|
}
|
|
},
|
|
},
|
|
created() {
|
|
created() {
|
|
@@ -84,7 +96,8 @@ export default {
|
|
if (this.name) {
|
|
if (this.name) {
|
|
this.$api.domain.get(this.name).then(r => {
|
|
this.$api.domain.get(this.name).then(r => {
|
|
this.configText = r.config
|
|
this.configText = r.config
|
|
- this.parse(r).then(()=>{
|
|
|
|
|
|
+ this.config.auto_cert = r.auto_cert
|
|
|
|
+ this.parse(r).then(() => {
|
|
this.ok = true
|
|
this.ok = true
|
|
})
|
|
})
|
|
}).catch(r => {
|
|
}).catch(r => {
|
|
@@ -100,7 +113,8 @@ export default {
|
|
root: "",
|
|
root: "",
|
|
ssl_certificate: "",
|
|
ssl_certificate: "",
|
|
ssl_certificate_key: "",
|
|
ssl_certificate_key: "",
|
|
- support_ssl: false
|
|
|
|
|
|
+ support_ssl: false,
|
|
|
|
+ auto_cert: false,
|
|
}
|
|
}
|
|
this.get_template()
|
|
this.get_template()
|
|
}
|
|
}
|
|
@@ -133,32 +147,7 @@ export default {
|
|
}
|
|
}
|
|
},
|
|
},
|
|
async unparse() {
|
|
async unparse() {
|
|
- let text = this.configText
|
|
|
|
- // http_listen_port: /listen (.*);/i,
|
|
|
|
- // https_listen_port: /listen (.*) ssl/i,
|
|
|
|
- const reg = {
|
|
|
|
- server_name: /server_name[\s](.*);/ig,
|
|
|
|
- index: /index[\s](.*);/i,
|
|
|
|
- root: /root[\s](.*);/i,
|
|
|
|
- ssl_certificate: /ssl_certificate[\s](.*);/i,
|
|
|
|
- ssl_certificate_key: /ssl_certificate_key[\s](.*);/i
|
|
|
|
- }
|
|
|
|
- text = text.replace(/listen[\s](.*);/i, "listen\t"
|
|
|
|
- + this.config['http_listen_port'] + ';')
|
|
|
|
- text = text.replace(/listen[\s](.*) ssl/i, "listen\t"
|
|
|
|
- + this.config['https_listen_port'] + ' ssl')
|
|
|
|
-
|
|
|
|
- text = text.replace(/listen(.*):(.*);/i, "listen\t[::]:"
|
|
|
|
- + this.config['http_listen_port'] + ';')
|
|
|
|
- text = text.replace(/listen(.*):(.*) ssl/i, "listen\t[::]:"
|
|
|
|
- + this.config['https_listen_port'] + ' ssl')
|
|
|
|
-
|
|
|
|
- for (let k in reg) {
|
|
|
|
- text = text.replace(new RegExp(reg[k]), k + "\t" +
|
|
|
|
- (this.config[k] !== undefined ? this.config[k] : " ") + ";")
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- this.configText = text
|
|
|
|
|
|
+ this.configText = unparse(this.configText, this.config)
|
|
},
|
|
},
|
|
async get_template() {
|
|
async get_template() {
|
|
if (this.config.support_ssl) {
|
|
if (this.config.support_ssl) {
|
|
@@ -185,11 +174,11 @@ export default {
|
|
})
|
|
})
|
|
},
|
|
},
|
|
save() {
|
|
save() {
|
|
- this.$api.domain.save(this.name ? this.name : this.config.name, {content: this.configText}).then(r => {
|
|
|
|
|
|
+ this.$api.domain.save(this.name, {content: this.configText}).then(r => {
|
|
this.parse(r)
|
|
this.parse(r)
|
|
this.$message.success("保存成功")
|
|
this.$message.success("保存成功")
|
|
if (this.name) {
|
|
if (this.name) {
|
|
- this.$refs["cert-info"].get()
|
|
|
|
|
|
+ if (this.$refs["cert-info"]) this.$refs["cert-info"].get()
|
|
}
|
|
}
|
|
}).catch(r => {
|
|
}).catch(r => {
|
|
console.log(r)
|
|
console.log(r)
|
|
@@ -223,10 +212,35 @@ export default {
|
|
if (r.status === "success" && r.ssl_certificate !== undefined && r.ssl_certificate_key !== undefined) {
|
|
if (r.status === "success" && r.ssl_certificate !== undefined && r.ssl_certificate_key !== undefined) {
|
|
this.config.ssl_certificate = r.ssl_certificate
|
|
this.config.ssl_certificate = r.ssl_certificate
|
|
this.config.ssl_certificate_key = r.ssl_certificate_key
|
|
this.config.ssl_certificate_key = r.ssl_certificate_key
|
|
- this.$refs["cert-info"].get()
|
|
|
|
|
|
+ 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(this.name + ' 加入自动续签列表成功')
|
|
|
|
+ }).catch(e => {
|
|
|
|
+ this.$message.error(e.message ?? this.name + ' 加入自动续签列表失败')
|
|
|
|
+ })
|
|
|
|
+ } else {
|
|
|
|
+ this.$api.domain.remove_auto_cert(this.name).then(() => {
|
|
|
|
+ this.$message.success('从自动续签列表中删除 ' + this.name + ' 成功')
|
|
|
|
+ }).catch(e => {
|
|
|
|
+ this.$message.error(e.message ?? '从自动续签列表中删除 ' + this.name + ' 失败')
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ columns: {
|
|
|
|
+ get() {
|
|
|
|
+ if (this.config.support_ssl) {
|
|
|
|
+ return [...columns, ...columnsSSL]
|
|
|
|
+ } else {
|
|
|
|
+ return [...columns]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -234,16 +248,21 @@ export default {
|
|
|
|
|
|
<style lang="less">
|
|
<style lang="less">
|
|
.ant-collapse {
|
|
.ant-collapse {
|
|
- margin: 10px;
|
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
+
|
|
|
|
+ .ant-collapse-item {
|
|
|
|
+ border-bottom: unset;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
.ant-collapse-content-box {
|
|
.ant-collapse-content-box {
|
|
- padding: 24px!important;
|
|
|
|
|
|
+ padding: 24px !important;
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
<style lang="less" scoped>
|
|
.ant-card {
|
|
.ant-card {
|
|
- margin: 10px;
|
|
|
|
|
|
+ // margin: 10px;
|
|
@media (max-width: 512px) {
|
|
@media (max-width: 512px) {
|
|
margin: 10px 0;
|
|
margin: 10px 0;
|
|
}
|
|
}
|