mirror of https://github.com/1Panel-dev/1Panel
feat: 增加默认文档TAB页
parent
cfa5f08cdd
commit
daa2e12420
|
@ -96,3 +96,30 @@ func (b *BaseApi) CreateWebDomain(c *gin.Context) {
|
||||||
}
|
}
|
||||||
helper.SuccessWithData(c, domain)
|
helper.SuccessWithData(c, domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) GetNginxConfig(c *gin.Context) {
|
||||||
|
var req dto.NginxConfigReq
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
config, err := websiteService.GetNginxConfigByScope(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) UpdateNginxConfig(c *gin.Context) {
|
||||||
|
var req dto.NginxConfigReq
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteService.UpdateNginxConfigByScope(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, nil)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package dto
|
||||||
|
|
||||||
|
import "github.com/1Panel-dev/1Panel/backend/utils/nginx/components"
|
||||||
|
|
||||||
|
type NginxConfig struct {
|
||||||
|
FilePath string `json:"filePath"`
|
||||||
|
ContainerName string `json:"containerName"`
|
||||||
|
Config *components.Config `json:"config"`
|
||||||
|
OldContent string `json:"oldContent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NginxConfigReq struct {
|
||||||
|
Scope NginxScope `json:"scope"`
|
||||||
|
WebSiteID uint `json:"webSiteId" validate:"required"`
|
||||||
|
Params map[string]string `json:"params"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NginxScope string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Index NginxScope = "index"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ScopeKeyMap = map[NginxScope][]string{
|
||||||
|
Index: {"index"},
|
||||||
|
}
|
|
@ -2,7 +2,6 @@ package dto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/nginx/components"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type WebSiteReq struct {
|
type WebSiteReq struct {
|
||||||
|
@ -59,10 +58,3 @@ type WebSiteDomainCreate struct {
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NginxConfig struct {
|
|
||||||
FilePath string `json:"filePath"`
|
|
||||||
ContainerName string `json:"containerName"`
|
|
||||||
Config *components.Config `json:"config"`
|
|
||||||
OldContent string `json:"oldContent"`
|
|
||||||
}
|
|
||||||
|
|
|
@ -185,3 +185,41 @@ func (w WebsiteService) DeleteWebsiteDomain(domainId uint) error {
|
||||||
|
|
||||||
return websiteDomainRepo.DeleteBy(context.TODO(), commonRepo.WithByID(domainId))
|
return websiteDomainRepo.DeleteBy(context.TODO(), commonRepo.WithByID(domainId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) GetNginxConfigByScope(req dto.NginxConfigReq) (map[string]interface{}, error) {
|
||||||
|
|
||||||
|
keys, ok := dto.ScopeKeyMap[req.Scope]
|
||||||
|
if !ok || len(keys) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.WebSiteID))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return getNginxConfigByKeys(website, keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) UpdateNginxConfigByScope(req dto.NginxConfigReq) error {
|
||||||
|
|
||||||
|
keys, ok := dto.ScopeKeyMap[req.Scope]
|
||||||
|
if !ok || len(keys) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
keyValues := make(map[string][]string, len(keys))
|
||||||
|
for k, v := range req.Params {
|
||||||
|
for _, name := range keys {
|
||||||
|
if name == k {
|
||||||
|
keyValues[k] = getNginxParams(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.WebSiteID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateNginxConfig(website, keyValues)
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/nginx"
|
"github.com/1Panel-dev/1Panel/backend/utils/nginx"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/nginx/components"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/nginx/parser"
|
"github.com/1Panel-dev/1Panel/backend/utils/nginx/parser"
|
||||||
"github.com/1Panel-dev/1Panel/cmd/server/nginx_conf"
|
"github.com/1Panel-dev/1Panel/cmd/server/nginx_conf"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -204,3 +205,51 @@ func deleteListenAndServerName(website model.WebSite, ports []int, domains []str
|
||||||
}
|
}
|
||||||
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxConfig.ContainerName)
|
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxConfig.ContainerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getNginxConfigByKeys(website model.WebSite, keys []string) (map[string]interface{}, error) {
|
||||||
|
nginxConfig, err := getNginxConfig(website.PrimaryDomain)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config := nginxConfig.Config
|
||||||
|
server := config.FindServers()[0]
|
||||||
|
res := make(map[string]interface{})
|
||||||
|
for _, key := range keys {
|
||||||
|
dirs := server.FindDirectives(key)
|
||||||
|
for _, dir := range dirs {
|
||||||
|
res[dir.GetName()] = dir.GetParameters()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateNginxConfig(website model.WebSite, keyValues map[string][]string) error {
|
||||||
|
nginxConfig, err := getNginxConfig(website.PrimaryDomain)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config := nginxConfig.Config
|
||||||
|
server := config.FindServers()[0]
|
||||||
|
for k, v := range keyValues {
|
||||||
|
newDir := components.Directive{
|
||||||
|
Name: k,
|
||||||
|
Parameters: v,
|
||||||
|
}
|
||||||
|
server.UpdateDirectives(k, newDir)
|
||||||
|
}
|
||||||
|
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxConfig.ContainerName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNginxParams(key string, param interface{}) []string {
|
||||||
|
var res []string
|
||||||
|
switch param.(type) {
|
||||||
|
case string:
|
||||||
|
if key == "index" {
|
||||||
|
res = strings.Split(param.(string), "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
|
@ -21,5 +21,7 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
|
||||||
groupRouter.GET("/domains/:websiteId", baseApi.GetWebDomains)
|
groupRouter.GET("/domains/:websiteId", baseApi.GetWebDomains)
|
||||||
groupRouter.DELETE("/domains/:id", baseApi.DeleteWebDomain)
|
groupRouter.DELETE("/domains/:id", baseApi.DeleteWebDomain)
|
||||||
groupRouter.POST("/domains", baseApi.CreateWebDomain)
|
groupRouter.POST("/domains", baseApi.CreateWebDomain)
|
||||||
|
groupRouter.POST("/config", baseApi.GetNginxConfig)
|
||||||
|
groupRouter.POST("/config/update", baseApi.UpdateNginxConfig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,4 +63,10 @@ export namespace WebSite {
|
||||||
port: number;
|
port: number;
|
||||||
domain: string;
|
domain: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface NginxConfigReq {
|
||||||
|
websiteId: number;
|
||||||
|
scope: string;
|
||||||
|
params?: any;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,3 +41,11 @@ export const DeleteDomain = (id: number) => {
|
||||||
export const CreateDomain = (req: WebSite.DomainCreate) => {
|
export const CreateDomain = (req: WebSite.DomainCreate) => {
|
||||||
return http.post<any>(`/websites/domains`, req);
|
return http.post<any>(`/websites/domains`, req);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const GetNginxConfig = (req: WebSite.NginxConfigReq) => {
|
||||||
|
return http.post<any>(`/websites/config`, req);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const UpdateNginxConfig = (req: WebSite.NginxConfigReq) => {
|
||||||
|
return http.post<any>(`/websites/config/update`, req);
|
||||||
|
};
|
||||||
|
|
|
@ -685,5 +685,7 @@ export default {
|
||||||
domainHelper: '一行一个域名,支持*和IP地址,支持域名:端口',
|
domainHelper: '一行一个域名,支持*和IP地址,支持域名:端口',
|
||||||
port: '端口',
|
port: '端口',
|
||||||
addDomain: '新增域名',
|
addDomain: '新增域名',
|
||||||
|
domainConfig: '域名设置',
|
||||||
|
defaultDoc: '默认文档',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-form ref="defaultForm" label-position="top" :model="defaultModel" :rules="rules" :loading="loading">
|
||||||
|
<el-form-item :label="$t('website.domain')" prop="index">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-input
|
||||||
|
width="40%"
|
||||||
|
v-model="defaultModel.index"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 8, maxRows: 20 }"
|
||||||
|
></el-input>
|
||||||
|
</el-col>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submit(defaultForm)" :loading="loading">
|
||||||
|
{{ $t('commons.button.save') }}
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { WebSite } from '@/api/interface/website';
|
||||||
|
import { GetNginxConfig, UpdateNginxConfig } from '@/api/modules/website';
|
||||||
|
import { Rules } from '@/global/form-rules';
|
||||||
|
import { ElMessage, FormInstance } from 'element-plus';
|
||||||
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const websiteId = computed(() => {
|
||||||
|
return Number(props.id);
|
||||||
|
});
|
||||||
|
const defaultForm = ref<FormInstance>();
|
||||||
|
let rules = ref({
|
||||||
|
index: [Rules.requiredInput],
|
||||||
|
});
|
||||||
|
let defaultModel = ref({
|
||||||
|
index: '',
|
||||||
|
});
|
||||||
|
let req = ref({
|
||||||
|
scope: 'index',
|
||||||
|
websiteId: websiteId.value,
|
||||||
|
params: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
let loading = ref(false);
|
||||||
|
|
||||||
|
const submit = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
await formEl.validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
req.value.params = defaultModel.value;
|
||||||
|
loading.value = true;
|
||||||
|
UpdateNginxConfig(req.value)
|
||||||
|
.then(() => {
|
||||||
|
ElMessage.success(i18n.global.t('commons.msg.updateSuccess'));
|
||||||
|
search(req.value);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const search = (req: WebSite.NginxConfigReq) => {
|
||||||
|
loading.value = true;
|
||||||
|
GetNginxConfig(req)
|
||||||
|
.then((res) => {
|
||||||
|
const params = res.data['index'];
|
||||||
|
let values = '';
|
||||||
|
for (const param of params) {
|
||||||
|
values = values + param + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultModel.value.index = values;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
search(req.value);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -59,7 +59,6 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
console.log(domain.value);
|
|
||||||
CreateDomain(domain.value)
|
CreateDomain(domain.value)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success(i18n.global.t('commons.msg.createSuccess'));
|
ElMessage.success(i18n.global.t('commons.msg.createSuccess'));
|
||||||
|
|
|
@ -38,6 +38,9 @@ const buttons = [
|
||||||
click: function (row: WebSite.Domain) {
|
click: function (row: WebSite.Domain) {
|
||||||
deleteDoamin(row.id);
|
deleteDoamin(row.id);
|
||||||
},
|
},
|
||||||
|
disabled: () => {
|
||||||
|
return data.value.length == 1;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<el-tabs tab-position="left" type="border-card">
|
<el-tabs tab-position="left" type="border-card" v-model="index">
|
||||||
<el-tab-pane label="域名设置">
|
<el-tab-pane :label="$t('website.domainConfig')">
|
||||||
<Doamin :id="id"></Doamin>
|
<Doamin :id="id" v-if="index == '0'"></Doamin>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('website.defaultDoc')">
|
||||||
|
<Default :id="id" v-if="index == '1'"></Default>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="目录设置">Config</el-tab-pane>
|
|
||||||
<el-tab-pane label="HTTPS">Role</el-tab-pane>
|
<el-tab-pane label="HTTPS">Role</el-tab-pane>
|
||||||
<el-tab-pane label="域名跳转">Task</el-tab-pane>
|
<el-tab-pane label="域名跳转">Task</el-tab-pane>
|
||||||
<el-tab-pane label="错误页面">Task</el-tab-pane>
|
<el-tab-pane label="错误页面">Task</el-tab-pane>
|
||||||
|
@ -14,9 +16,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="Basic">
|
<script lang="ts" setup name="Basic">
|
||||||
import { computed } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
import Doamin from './domain/index.vue';
|
import Doamin from './domain/index.vue';
|
||||||
|
import Default from './default-doc/index.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -28,4 +31,6 @@ const props = defineProps({
|
||||||
const id = computed(() => {
|
const id = computed(() => {
|
||||||
return props.id;
|
return props.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let index = ref('0');
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue