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)
|
||||
}
|
||||
|
||||
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 (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/nginx/components"
|
||||
)
|
||||
|
||||
type WebSiteReq struct {
|
||||
|
@ -59,10 +58,3 @@ type WebSiteDomainCreate struct {
|
|||
Port int `json:"port"`
|
||||
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))
|
||||
}
|
||||
|
||||
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/files"
|
||||
"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/cmd/server/nginx_conf"
|
||||
"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)
|
||||
}
|
||||
|
||||
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.DELETE("/domains/:id", baseApi.DeleteWebDomain)
|
||||
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;
|
||||
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) => {
|
||||
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地址,支持域名:端口',
|
||||
port: '端口',
|
||||
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;
|
||||
}
|
||||
loading.value = true;
|
||||
console.log(domain.value);
|
||||
CreateDomain(domain.value)
|
||||
.then(() => {
|
||||
ElMessage.success(i18n.global.t('commons.msg.createSuccess'));
|
||||
|
|
|
@ -38,6 +38,9 @@ const buttons = [
|
|||
click: function (row: WebSite.Domain) {
|
||||
deleteDoamin(row.id);
|
||||
},
|
||||
disabled: () => {
|
||||
return data.value.length == 1;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<template>
|
||||
<el-tabs tab-position="left" type="border-card">
|
||||
<el-tab-pane label="域名设置">
|
||||
<Doamin :id="id"></Doamin>
|
||||
<el-tabs tab-position="left" type="border-card" v-model="index">
|
||||
<el-tab-pane :label="$t('website.domainConfig')">
|
||||
<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 label="目录设置">Config</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>
|
||||
|
@ -14,9 +16,10 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup name="Basic">
|
||||
import { computed } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import Doamin from './domain/index.vue';
|
||||
import Default from './default-doc/index.vue';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
|
@ -28,4 +31,6 @@ const props = defineProps({
|
|||
const id = computed(() => {
|
||||
return props.id;
|
||||
});
|
||||
|
||||
let index = ref('0');
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue