mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-18 22:22:59 +08:00
feat: 新增创建域名
This commit is contained in:
parent
35e85930b9
commit
cfa5f08cdd
@ -82,3 +82,17 @@ func (b *BaseApi) DeleteWebDomain(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) CreateWebDomain(c *gin.Context) {
|
||||
var req dto.WebSiteDomainCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
domain, err := websiteService.CreateWebsiteDomain(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, domain)
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package dto
|
||||
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/nginx/components"
|
||||
)
|
||||
|
||||
type WebSiteReq struct {
|
||||
PageInfo
|
||||
@ -43,16 +46,23 @@ type WebSiteDTO struct {
|
||||
}
|
||||
|
||||
type WebSiteGroupCreate struct {
|
||||
Name string
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type WebSiteGroupUpdate struct {
|
||||
ID uint
|
||||
Name string
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type WebSiteDomainCreate struct {
|
||||
WebSiteID uint `json:"webSiteId"`
|
||||
Port int `json:"port"`
|
||||
Domain string `json:"domain"`
|
||||
}
|
||||
|
||||
type WebSiteDomainDel struct {
|
||||
type NginxConfig struct {
|
||||
FilePath string `json:"filePath"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Config *components.Config `json:"config"`
|
||||
OldContent string `json:"oldContent"`
|
||||
}
|
||||
|
@ -126,8 +126,28 @@ func (w WebsiteService) DeleteWebSite(req dto.WebSiteDel) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w WebsiteService) CreateWebsiteDomain() {
|
||||
func (w WebsiteService) CreateWebsiteDomain(create dto.WebSiteDomainCreate) (model.WebSiteDomain, error) {
|
||||
var domainModel model.WebSiteDomain
|
||||
var ports []int
|
||||
var domains []string
|
||||
|
||||
website, err := websiteRepo.GetFirst(commonRepo.WithByID(create.WebSiteID))
|
||||
if err != nil {
|
||||
return domainModel, err
|
||||
}
|
||||
if oldDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebSiteId(create.WebSiteID), websiteDomainRepo.WithPort(create.Port)); len(oldDomains) == 0 {
|
||||
ports = append(ports, create.Port)
|
||||
}
|
||||
domains = append(domains, create.Domain)
|
||||
if err := addListenAndServerName(website, ports, domains); err != nil {
|
||||
return domainModel, err
|
||||
}
|
||||
domainModel = model.WebSiteDomain{
|
||||
Domain: create.Domain,
|
||||
Port: create.Port,
|
||||
WebSiteID: create.WebSiteID,
|
||||
}
|
||||
return domainModel, websiteDomainRepo.Create(context.TODO(), &domainModel)
|
||||
}
|
||||
|
||||
func (w WebsiteService) GetWebsiteDomain(websiteId uint) ([]model.WebSiteDomain, error) {
|
||||
|
@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
@ -137,23 +138,59 @@ func nginxCheckAndReload(oldContent string, filePath string, containerName strin
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteListenAndServerName(website model.WebSite, ports []int, domains []string) error {
|
||||
|
||||
func getNginxConfig(primaryDomain string) (dto.NginxConfig, error) {
|
||||
var nginxConfig dto.NginxConfig
|
||||
nginxApp, err := appRepo.GetFirst(appRepo.WithKey("nginx"))
|
||||
if err != nil {
|
||||
return err
|
||||
return nginxConfig, err
|
||||
}
|
||||
nginxInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(nginxApp.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
return nginxConfig, err
|
||||
}
|
||||
|
||||
configPath := path.Join(constant.AppInstallDir, "nginx", nginxInstall.Name, "conf", "conf.d", website.PrimaryDomain+".conf")
|
||||
configPath := path.Join(constant.AppInstallDir, "nginx", nginxInstall.Name, "conf", "conf.d", primaryDomain+".conf")
|
||||
content, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return err
|
||||
return nginxConfig, err
|
||||
}
|
||||
config := parser.NewStringParser(string(content)).Parse()
|
||||
config.FilePath = configPath
|
||||
nginxConfig.Config = config
|
||||
nginxConfig.OldContent = string(content)
|
||||
nginxConfig.ContainerName = nginxInstall.ContainerName
|
||||
nginxConfig.FilePath = configPath
|
||||
|
||||
return nginxConfig, nil
|
||||
}
|
||||
|
||||
func addListenAndServerName(website model.WebSite, ports []int, domains []string) error {
|
||||
|
||||
nginxConfig, err := getNginxConfig(website.PrimaryDomain)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
config := nginxConfig.Config
|
||||
server := config.FindServers()[0]
|
||||
for _, port := range ports {
|
||||
server.AddListen(strconv.Itoa(port), false)
|
||||
}
|
||||
for _, domain := range domains {
|
||||
server.AddServerName(domain)
|
||||
}
|
||||
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxConfig.ContainerName)
|
||||
}
|
||||
|
||||
func deleteListenAndServerName(website model.WebSite, ports []int, domains []string) error {
|
||||
|
||||
nginxConfig, err := getNginxConfig(website.PrimaryDomain)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
config := nginxConfig.Config
|
||||
server := config.FindServers()[0]
|
||||
for _, port := range ports {
|
||||
server.DeleteListen(strconv.Itoa(port))
|
||||
@ -162,10 +199,8 @@ func deleteListenAndServerName(website model.WebSite, ports []int, domains []str
|
||||
server.DeleteServerName(domain)
|
||||
}
|
||||
|
||||
config.FilePath = configPath
|
||||
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
return nginxCheckAndReload(string(content), configPath, nginxInstall.ContainerName)
|
||||
|
||||
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxConfig.ContainerName)
|
||||
}
|
||||
|
@ -20,5 +20,6 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
|
||||
groupRouter.POST("/del", baseApi.DeleteWebSite)
|
||||
groupRouter.GET("/domains/:websiteId", baseApi.GetWebDomains)
|
||||
groupRouter.DELETE("/domains/:id", baseApi.DeleteWebDomain)
|
||||
groupRouter.POST("/domains", baseApi.CreateWebDomain)
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +112,13 @@ func (s *Server) DeleteServerName(name string) {
|
||||
s.UpdateServerName(names)
|
||||
}
|
||||
|
||||
func (s *Server) AddServerName(name string) {
|
||||
dirs := s.FindDirectives("server_name")
|
||||
params := dirs[0].GetParameters()
|
||||
params = append(params, name)
|
||||
s.UpdateServerName(params)
|
||||
}
|
||||
|
||||
func (s *Server) UpdateServerName(names []string) {
|
||||
serverNameDirective := Directive{
|
||||
Name: "server_name",
|
||||
|
@ -52,8 +52,15 @@ export namespace WebSite {
|
||||
}
|
||||
|
||||
export interface Domain {
|
||||
name: string;
|
||||
websiteId: number;
|
||||
port: number;
|
||||
id: number;
|
||||
domain: string;
|
||||
}
|
||||
|
||||
export interface DomainCreate {
|
||||
websiteId: number;
|
||||
port: number;
|
||||
domain: string;
|
||||
}
|
||||
}
|
||||
|
@ -37,3 +37,7 @@ export const ListDomains = (id: number) => {
|
||||
export const DeleteDomain = (id: number) => {
|
||||
return http.delete<any>(`/websites/domains/${id}`);
|
||||
};
|
||||
|
||||
export const CreateDomain = (req: WebSite.DomainCreate) => {
|
||||
return http.post<any>(`/websites/domains`, req);
|
||||
};
|
||||
|
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<el-dialog v-model="open" :title="$t('website.create')" width="40%" :before-close="handleClose">
|
||||
<el-form ref="domainForm" label-position="right" :model="domain" label-width="130px" :rules="rules">
|
||||
<el-form-item :label="$t('website.domain')" prop="domain">
|
||||
<el-input v-model="domain.domain"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('website.port')" prop="port">
|
||||
<el-input v-model.number="domain.port"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit(domainForm)" :loading="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { CreateDomain } from '@/api/modules/website';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { ElMessage, FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const domainForm = ref<FormInstance>();
|
||||
|
||||
let rules = ref({
|
||||
domain: [Rules.requiredInput],
|
||||
port: [Rules.requiredInput],
|
||||
});
|
||||
|
||||
let open = ref(false);
|
||||
let loading = ref(false);
|
||||
let domain = ref({
|
||||
websiteId: 0,
|
||||
domain: '',
|
||||
port: 80,
|
||||
});
|
||||
|
||||
const em = defineEmits(['close']);
|
||||
const handleClose = () => {
|
||||
open.value = false;
|
||||
em('close', false);
|
||||
};
|
||||
|
||||
const acceptParams = async (websiteId: number) => {
|
||||
domain.value.websiteId = Number(websiteId);
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
console.log(domain.value);
|
||||
CreateDomain(domain.value)
|
||||
.then(() => {
|
||||
ElMessage.success(i18n.global.t('commons.msg.createSuccess'));
|
||||
handleClose();
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
@ -1,16 +1,18 @@
|
||||
<template>
|
||||
<ComplexTable :data="data" @search="search" v-loading="loading">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" plain>{{ $t('website.addDomain') }}</el-button>
|
||||
<el-button type="primary" plain @click="openCreate">{{ $t('website.addDomain') }}</el-button>
|
||||
</template>
|
||||
<el-table-column :label="$t('website.domain')" prop="domain"></el-table-column>
|
||||
<el-table-column :label="$t('website.port')" prop="port"></el-table-column>
|
||||
<fu-table-operations :ellipsis="1" :buttons="buttons" :label="$t('commons.table.operate')" fixed="right" fix />
|
||||
</ComplexTable>
|
||||
<Domain ref="domainRef" @close="search(id)"></Domain>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import Domain from './create/index.vue';
|
||||
import { WebSite } from '@/api/interface/website';
|
||||
import { DeleteDomain, ListDomains } from '@/api/modules/website';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
@ -23,13 +25,12 @@ const props = defineProps({
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const id = computed(() => {
|
||||
return props.id;
|
||||
});
|
||||
|
||||
let loading = ref(false);
|
||||
const data = ref<WebSite.Domain[]>([]);
|
||||
const domainRef = ref();
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
@ -40,6 +41,10 @@ const buttons = [
|
||||
},
|
||||
];
|
||||
|
||||
const openCreate = () => {
|
||||
domainRef.value.acceptParams(id.value);
|
||||
};
|
||||
|
||||
const deleteDoamin = async (domainId: number) => {
|
||||
await useDeleteData(DeleteDomain, domainId, 'commons.msg.delete', loading.value);
|
||||
search(id.value);
|
||||
|
Loading…
Reference in New Issue
Block a user