mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-17 03:04:46 +08:00
feat: 增加网站域名管理
This commit is contained in:
parent
42134e315b
commit
35e85930b9
@ -7,7 +7,6 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *BaseApi) SearchApp(c *gin.Context) {
|
func (b *BaseApi) SearchApp(c *gin.Context) {
|
||||||
@ -35,13 +34,13 @@ func (b *BaseApi) SyncApp(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *BaseApi) GetApp(c *gin.Context) {
|
func (b *BaseApi) GetApp(c *gin.Context) {
|
||||||
idStr := c.Param("id")
|
|
||||||
u64, err := strconv.ParseUint(idStr, 10, 32)
|
id, err := helper.GetParamID(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
appDTO, err := appService.GetApp(uint(u64))
|
appDTO, err := appService.GetApp(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
@ -49,14 +48,15 @@ func (b *BaseApi) GetApp(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, appDTO)
|
helper.SuccessWithData(c, appDTO)
|
||||||
}
|
}
|
||||||
func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
||||||
idStr := c.Param("appid")
|
|
||||||
u64, err := strconv.ParseUint(idStr, 10, 32)
|
appId, err := helper.GetIntParamByKey(c, "appId")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
version := c.Param("version")
|
version := c.Param("version")
|
||||||
appDetailDTO, err := appService.GetAppDetail(uint(u64), version)
|
appDetailDTO, err := appService.GetAppDetail(appId, version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
@ -175,17 +175,13 @@ func (b *BaseApi) GetServices(c *gin.Context) {
|
|||||||
|
|
||||||
func (b *BaseApi) GetUpdateVersions(c *gin.Context) {
|
func (b *BaseApi) GetUpdateVersions(c *gin.Context) {
|
||||||
|
|
||||||
appInstallId := c.Param("appInstallId")
|
appInstallId, err := helper.GetIntParamByKey(c, "appInstallId")
|
||||||
if appInstallId == "" {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, nil)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
id, err := strconv.Atoi(appInstallId)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
versions, err := appService.GetUpdateVersions(uint(id))
|
|
||||||
|
versions, err := appService.GetUpdateVersions(appInstallId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package helper
|
package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@ -85,3 +86,12 @@ func GetParamID(c *gin.Context) (uint, error) {
|
|||||||
intNum, _ := strconv.Atoi(idParam)
|
intNum, _ := strconv.Atoi(idParam)
|
||||||
return uint(intNum), nil
|
return uint(intNum), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetIntParamByKey(c *gin.Context, key string) (uint, error) {
|
||||||
|
idParam, ok := c.Params.Get(key)
|
||||||
|
if !ok {
|
||||||
|
return 0, fmt.Errorf("error %s in path", key)
|
||||||
|
}
|
||||||
|
intNum, _ := strconv.Atoi(idParam)
|
||||||
|
return uint(intNum), nil
|
||||||
|
}
|
||||||
|
@ -51,3 +51,34 @@ func (b *BaseApi) DeleteWebSite(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
helper.SuccessWithData(c, nil)
|
helper.SuccessWithData(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) GetWebDomains(c *gin.Context) {
|
||||||
|
|
||||||
|
websiteId, err := helper.GetIntParamByKey(c, "websiteId")
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := websiteService.GetWebsiteDomain(websiteId)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, list)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) DeleteWebDomain(c *gin.Context) {
|
||||||
|
|
||||||
|
id, err := helper.GetParamID(c)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := websiteService.DeleteWebsiteDomain(id); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, nil)
|
||||||
|
}
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *BaseApi) GetWebGroups(c *gin.Context) {
|
func (b *BaseApi) GetWebGroups(c *gin.Context) {
|
||||||
@ -45,17 +44,13 @@ func (b *BaseApi) UpdateWebGroup(c *gin.Context) {
|
|||||||
|
|
||||||
func (b *BaseApi) DeleteWebGroup(c *gin.Context) {
|
func (b *BaseApi) DeleteWebGroup(c *gin.Context) {
|
||||||
|
|
||||||
groupId := c.Param("groupId")
|
groupId, err := helper.GetIntParamByKey(c, "groupId")
|
||||||
if groupId == "" {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, nil)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
id, err := strconv.Atoi(groupId)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := websiteGroupService.DeleteGroup(uint(id)); err != nil {
|
|
||||||
|
if err := websiteGroupService.DeleteGroup(groupId); err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ type WebSiteCreate struct {
|
|||||||
Type string `json:"type" validate:"required"`
|
Type string `json:"type" validate:"required"`
|
||||||
Alias string `json:"alias" validate:"required"`
|
Alias string `json:"alias" validate:"required"`
|
||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
Domains []string `json:"domains"`
|
OtherDomains string `json:"otherDomains"`
|
||||||
AppType AppType `json:"appType" validate:"required"`
|
AppType AppType `json:"appType" validate:"required"`
|
||||||
AppInstall NewAppInstall `json:"appInstall"`
|
AppInstall NewAppInstall `json:"appInstall"`
|
||||||
AppID uint `json:"appID"`
|
AppID uint `json:"appID"`
|
||||||
@ -41,3 +41,18 @@ type WebSiteDel struct {
|
|||||||
type WebSiteDTO struct {
|
type WebSiteDTO struct {
|
||||||
model.WebSite
|
model.WebSite
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WebSiteGroupCreate struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebSiteGroupUpdate struct {
|
||||||
|
ID uint
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebSiteDomainCreate struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebSiteDomainDel struct {
|
||||||
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
package dto
|
|
||||||
|
|
||||||
type WebSiteGroupCreate struct {
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
type WebSiteGroupUpdate struct {
|
|
||||||
ID uint
|
|
||||||
Name string
|
|
||||||
}
|
|
@ -71,12 +71,13 @@ func (c *CommonRepo) WithIdsNotIn(ids []uint) DBOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getTx(ctx context.Context, opts ...DBOption) *gorm.DB {
|
func getTx(ctx context.Context, opts ...DBOption) *gorm.DB {
|
||||||
if ctx == nil || ctx.Value(constant.DB) == nil {
|
tx, ok := ctx.Value(constant.DB).(*gorm.DB)
|
||||||
return getDb()
|
if ok {
|
||||||
}
|
for _, opt := range opts {
|
||||||
tx := ctx.Value(constant.DB).(*gorm.DB)
|
tx = opt(tx)
|
||||||
for _, opt := range opts {
|
}
|
||||||
tx = opt(tx)
|
} else {
|
||||||
|
return getDb(opts...)
|
||||||
}
|
}
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,19 @@ package repo
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WebSiteRepo struct {
|
type WebSiteRepo struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebSiteRepo) WithAppInstallId(appInstallId uint) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("app_install_id = ?", appInstallId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w WebSiteRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebSite, error) {
|
func (w WebSiteRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebSite, error) {
|
||||||
var websites []model.WebSite
|
var websites []model.WebSite
|
||||||
db := getDb(opts...).Model(&model.WebSite{})
|
db := getDb(opts...).Model(&model.WebSite{})
|
||||||
|
@ -15,6 +15,17 @@ func (w WebSiteDomainRepo) WithWebSiteId(websiteId uint) DBOption {
|
|||||||
return db.Where("web_site_id = ?", websiteId)
|
return db.Where("web_site_id = ?", websiteId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebSiteDomainRepo) WithPort(port int) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("port = ?", port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (w WebSiteDomainRepo) WithDomain(domain string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("domain = ?", domain)
|
||||||
|
}
|
||||||
|
}
|
||||||
func (w WebSiteDomainRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebSiteDomain, error) {
|
func (w WebSiteDomainRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebSiteDomain, error) {
|
||||||
var domains []model.WebSiteDomain
|
var domains []model.WebSiteDomain
|
||||||
db := getDb(opts...).Model(&model.WebSiteDomain{})
|
db := getDb(opts...).Model(&model.WebSiteDomain{})
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,6 +31,7 @@ func (w WebsiteService) PageWebSite(req dto.WebSiteReq) (int64, []dto.WebSiteDTO
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteService) CreateWebsite(create dto.WebSiteCreate) error {
|
func (w WebsiteService) CreateWebsite(create dto.WebSiteCreate) error {
|
||||||
|
|
||||||
defaultDate, _ := time.Parse(constant.DateLayout, constant.DefaultDate)
|
defaultDate, _ := time.Parse(constant.DateLayout, constant.DefaultDate)
|
||||||
website := &model.WebSite{
|
website := &model.WebSite{
|
||||||
PrimaryDomain: create.PrimaryDomain,
|
PrimaryDomain: create.PrimaryDomain,
|
||||||
@ -54,7 +58,9 @@ func (w WebsiteService) CreateWebsite(create dto.WebSiteCreate) error {
|
|||||||
}
|
}
|
||||||
var domains []model.WebSiteDomain
|
var domains []model.WebSiteDomain
|
||||||
domains = append(domains, model.WebSiteDomain{Domain: website.PrimaryDomain, WebSiteID: website.ID, Port: 80})
|
domains = append(domains, model.WebSiteDomain{Domain: website.PrimaryDomain, WebSiteID: website.ID, Port: 80})
|
||||||
for _, domain := range create.Domains {
|
|
||||||
|
otherDomainArray := strings.Split(create.OtherDomains, "\n")
|
||||||
|
for _, domain := range otherDomainArray {
|
||||||
domainModel, err := getDomain(domain, website.ID)
|
domainModel, err := getDomain(domain, website.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
@ -93,6 +99,10 @@ func (w WebsiteService) DeleteWebSite(req dto.WebSiteDel) error {
|
|||||||
tx, ctx := getTxAndContext()
|
tx, ctx := getTxAndContext()
|
||||||
|
|
||||||
if req.DeleteApp {
|
if req.DeleteApp {
|
||||||
|
websites, _ := websiteRepo.GetBy(websiteRepo.WithAppInstallId(website.AppInstallID))
|
||||||
|
if len(websites) > 1 {
|
||||||
|
return errors.New("other website use this app")
|
||||||
|
}
|
||||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return err
|
return err
|
||||||
@ -115,3 +125,43 @@ func (w WebsiteService) DeleteWebSite(req dto.WebSiteDel) error {
|
|||||||
tx.Commit()
|
tx.Commit()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) CreateWebsiteDomain() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) GetWebsiteDomain(websiteId uint) ([]model.WebSiteDomain, error) {
|
||||||
|
return websiteDomainRepo.GetBy(websiteDomainRepo.WithWebSiteId(websiteId))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WebsiteService) DeleteWebsiteDomain(domainId uint) error {
|
||||||
|
|
||||||
|
webSiteDomain, err := websiteDomainRepo.GetFirst(commonRepo.WithByID(domainId))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if websiteDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebSiteId(webSiteDomain.WebSiteID)); len(websiteDomains) == 1 {
|
||||||
|
return fmt.Errorf("can not delete last domain")
|
||||||
|
}
|
||||||
|
website, err := websiteRepo.GetFirst(commonRepo.WithByID(webSiteDomain.WebSiteID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var ports []int
|
||||||
|
if oldDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebSiteId(webSiteDomain.WebSiteID), websiteDomainRepo.WithPort(webSiteDomain.Port)); len(oldDomains) == 1 {
|
||||||
|
ports = append(ports, webSiteDomain.Port)
|
||||||
|
}
|
||||||
|
|
||||||
|
var domains []string
|
||||||
|
if oldDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebSiteId(webSiteDomain.WebSiteID), websiteDomainRepo.WithDomain(webSiteDomain.Domain)); len(oldDomains) == 1 {
|
||||||
|
domains = append(domains, webSiteDomain.Domain)
|
||||||
|
}
|
||||||
|
if len(ports) > 0 || len(domains) > 0 {
|
||||||
|
if err := deleteListenAndServerName(website, ports, domains); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return websiteDomainRepo.DeleteBy(context.TODO(), commonRepo.WithByID(domainId))
|
||||||
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"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"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -67,7 +68,7 @@ func configDefaultNginx(website *model.WebSite, domains []model.WebSiteDomain) e
|
|||||||
var serverNames []string
|
var serverNames []string
|
||||||
for _, domain := range domains {
|
for _, domain := range domains {
|
||||||
serverNames = append(serverNames, domain.Domain)
|
serverNames = append(serverNames, domain.Domain)
|
||||||
server.UpdateListen(string(rune(domain.Port)), false)
|
server.UpdateListen(strconv.Itoa(domain.Port), false)
|
||||||
}
|
}
|
||||||
server.UpdateServerName(serverNames)
|
server.UpdateServerName(serverNames)
|
||||||
proxy := fmt.Sprintf("http://%s:%d", appInstall.ServiceName, appInstall.HttpPort)
|
proxy := fmt.Sprintf("http://%s:%d", appInstall.ServiceName, appInstall.HttpPort)
|
||||||
@ -121,6 +122,50 @@ func delNginxConfig(website model.WebSite) error {
|
|||||||
return opNginx(nginxInstall.ContainerName, "reload")
|
return opNginx(nginxInstall.ContainerName, "reload")
|
||||||
}
|
}
|
||||||
|
|
||||||
func delApp() error {
|
func nginxCheckAndReload(oldContent string, filePath string, containerName string) error {
|
||||||
|
|
||||||
|
if err := opNginx(containerName, "check"); err != nil {
|
||||||
|
_ = files.NewFileOp().WriteFile(filePath, strings.NewReader(oldContent), 0644)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := opNginx(containerName, "reload"); err != nil {
|
||||||
|
_ = files.NewFileOp().WriteFile(filePath, strings.NewReader(oldContent), 0644)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteListenAndServerName(website model.WebSite, ports []int, domains []string) error {
|
||||||
|
|
||||||
|
nginxApp, err := appRepo.GetFirst(appRepo.WithKey("nginx"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nginxInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(nginxApp.ID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
configPath := path.Join(constant.AppInstallDir, "nginx", nginxInstall.Name, "conf", "conf.d", website.PrimaryDomain+".conf")
|
||||||
|
content, err := os.ReadFile(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config := parser.NewStringParser(string(content)).Parse()
|
||||||
|
server := config.FindServers()[0]
|
||||||
|
for _, port := range ports {
|
||||||
|
server.DeleteListen(strconv.Itoa(port))
|
||||||
|
}
|
||||||
|
for _, domain := range domains {
|
||||||
|
server.DeleteServerName(domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.FilePath = configPath
|
||||||
|
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nginxCheckAndReload(string(content), configPath, nginxInstall.ContainerName)
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -18,7 +18,7 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) {
|
|||||||
appRouter.POST("/sync", baseApi.SyncApp)
|
appRouter.POST("/sync", baseApi.SyncApp)
|
||||||
appRouter.POST("/search", baseApi.SearchApp)
|
appRouter.POST("/search", baseApi.SearchApp)
|
||||||
appRouter.GET("/:id", baseApi.GetApp)
|
appRouter.GET("/:id", baseApi.GetApp)
|
||||||
appRouter.GET("/detail/:appid/:version", baseApi.GetAppDetail)
|
appRouter.GET("/detail/:appId/:version", baseApi.GetAppDetail)
|
||||||
appRouter.POST("/install", baseApi.InstallApp)
|
appRouter.POST("/install", baseApi.InstallApp)
|
||||||
appRouter.GET("/installed/:appInstallId/versions", baseApi.GetUpdateVersions)
|
appRouter.GET("/installed/:appInstallId/versions", baseApi.GetUpdateVersions)
|
||||||
appRouter.POST("/installed", baseApi.SearchInstalled)
|
appRouter.POST("/installed", baseApi.SearchInstalled)
|
||||||
|
@ -18,5 +18,7 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
|
|||||||
groupRouter.POST("", baseApi.CreateWebsite)
|
groupRouter.POST("", baseApi.CreateWebsite)
|
||||||
groupRouter.POST("/search", baseApi.PageWebsite)
|
groupRouter.POST("/search", baseApi.PageWebsite)
|
||||||
groupRouter.POST("/del", baseApi.DeleteWebSite)
|
groupRouter.POST("/del", baseApi.DeleteWebSite)
|
||||||
|
groupRouter.GET("/domains/:websiteId", baseApi.GetWebDomains)
|
||||||
|
groupRouter.DELETE("/domains/:id", baseApi.DeleteWebDomain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,17 +74,44 @@ func (s *Server) UpdateListen(bind string, defaultServer bool, params ...string)
|
|||||||
listen.DefaultServer = DefaultServer
|
listen.DefaultServer = DefaultServer
|
||||||
}
|
}
|
||||||
var newListens []*ServerListen
|
var newListens []*ServerListen
|
||||||
|
exist := false
|
||||||
for _, li := range s.Listens {
|
for _, li := range s.Listens {
|
||||||
if li.Bind == bind {
|
if li.Bind == bind {
|
||||||
|
exist = true
|
||||||
newListens = append(newListens, listen)
|
newListens = append(newListens, listen)
|
||||||
} else {
|
} else {
|
||||||
newListens = append(newListens, li)
|
newListens = append(newListens, li)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !exist {
|
||||||
|
newListens = append(newListens, listen)
|
||||||
|
}
|
||||||
|
|
||||||
s.Listens = newListens
|
s.Listens = newListens
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) DeleteListen(bind string) {
|
||||||
|
var newListens []*ServerListen
|
||||||
|
for _, li := range s.Listens {
|
||||||
|
if li.Bind != bind {
|
||||||
|
newListens = append(newListens, li)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Listens = newListens
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) DeleteServerName(name string) {
|
||||||
|
var names []string
|
||||||
|
dirs := s.FindDirectives("server_name")
|
||||||
|
params := dirs[0].GetParameters()
|
||||||
|
for _, param := range params {
|
||||||
|
if param != name {
|
||||||
|
names = append(names, param)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.UpdateServerName(names)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) UpdateServerName(names []string) {
|
func (s *Server) UpdateServerName(names []string) {
|
||||||
serverNameDirective := Directive{
|
serverNameDirective := Directive{
|
||||||
Name: "server_name",
|
Name: "server_name",
|
||||||
|
@ -35,7 +35,6 @@ export namespace WebSite {
|
|||||||
type: string;
|
type: string;
|
||||||
alias: string;
|
alias: string;
|
||||||
remark: string;
|
remark: string;
|
||||||
domains: string[];
|
|
||||||
appType: string;
|
appType: string;
|
||||||
appInstallID: number;
|
appInstallID: number;
|
||||||
webSiteGroupID: number;
|
webSiteGroupID: number;
|
||||||
@ -51,4 +50,10 @@ export namespace WebSite {
|
|||||||
name: string;
|
name: string;
|
||||||
id?: number;
|
id?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Domain {
|
||||||
|
name: string;
|
||||||
|
port: number;
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,3 +29,11 @@ export const UpdateGroup = (req: WebSite.GroupOp) => {
|
|||||||
export const DeleteGroup = (id: number) => {
|
export const DeleteGroup = (id: number) => {
|
||||||
return http.delete<any>(`/websites/groups/${id}`);
|
return http.delete<any>(`/websites/groups/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ListDomains = (id: number) => {
|
||||||
|
return http.get<WebSite.Domain[]>(`/websites/domains/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DeleteDomain = (id: number) => {
|
||||||
|
return http.delete<any>(`/websites/domains/${id}`);
|
||||||
|
};
|
||||||
|
@ -682,5 +682,8 @@ export default {
|
|||||||
deleteApp: '删除应用',
|
deleteApp: '删除应用',
|
||||||
deleteBackup: '删除备份',
|
deleteBackup: '删除备份',
|
||||||
domain: '域名',
|
domain: '域名',
|
||||||
|
domainHelper: '一行一个域名,支持*和IP地址,支持域名:端口',
|
||||||
|
port: '端口',
|
||||||
|
addDomain: '新增域名',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -19,16 +19,17 @@ const webSiteRouter = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/websites/projects/config',
|
path: '/websites/:id/config',
|
||||||
name: 'WebsiteConfig',
|
name: 'WebsiteConfig',
|
||||||
component: () => import('@/views/website/project/config/index.vue'),
|
component: () => import('@/views/website/project/config/index.vue'),
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
props: true,
|
||||||
meta: {
|
meta: {
|
||||||
activeMenu: '/websites',
|
activeMenu: '/websites',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/websites/config',
|
path: '/websites/nginx',
|
||||||
name: 'Config',
|
name: 'Config',
|
||||||
component: () => import('@/views/website/config/index.vue'),
|
component: () => import('@/views/website/config/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
<template>
|
||||||
|
<ComplexTable :data="data" @search="search" v-loading="loading">
|
||||||
|
<template #toolbar>
|
||||||
|
<el-button type="primary" plain>{{ $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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import ComplexTable from '@/components/complex-table/index.vue';
|
||||||
|
import { WebSite } from '@/api/interface/website';
|
||||||
|
import { DeleteDomain, ListDomains } from '@/api/modules/website';
|
||||||
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const id = computed(() => {
|
||||||
|
return props.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
let loading = ref(false);
|
||||||
|
const data = ref<WebSite.Domain[]>([]);
|
||||||
|
|
||||||
|
const buttons = [
|
||||||
|
{
|
||||||
|
label: i18n.global.t('app.delete'),
|
||||||
|
click: function (row: WebSite.Domain) {
|
||||||
|
deleteDoamin(row.id);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const deleteDoamin = async (domainId: number) => {
|
||||||
|
await useDeleteData(DeleteDomain, domainId, 'commons.msg.delete', loading.value);
|
||||||
|
search(id.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const search = (id: number) => {
|
||||||
|
loading.value = true;
|
||||||
|
ListDomains(id)
|
||||||
|
.then((res) => {
|
||||||
|
data.value = res.data;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => search(id.value));
|
||||||
|
</script>
|
31
frontend/src/views/website/project/config/basic/index.vue
Normal file
31
frontend/src/views/website/project/config/basic/index.vue
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<el-tabs tab-position="left" type="border-card">
|
||||||
|
<el-tab-pane label="域名设置">
|
||||||
|
<Doamin :id="id"></Doamin>
|
||||||
|
</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>
|
||||||
|
<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-tabs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="Basic">
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
import Doamin from './domain/index.vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const id = computed(() => {
|
||||||
|
return props.id;
|
||||||
|
});
|
||||||
|
</script>
|
@ -2,24 +2,7 @@
|
|||||||
<LayoutContent :header="'网站设置'" :back-name="'Website'">
|
<LayoutContent :header="'网站设置'" :back-name="'Website'">
|
||||||
<el-tabs type="card">
|
<el-tabs type="card">
|
||||||
<el-tab-pane label="基本">
|
<el-tab-pane label="基本">
|
||||||
<el-tabs tab-position="left" type="border-card">
|
<Basic :id="id"></Basic>
|
||||||
<el-tab-pane label="域名设置">
|
|
||||||
<ComplexTable>
|
|
||||||
<template #toolbar>
|
|
||||||
<el-button type="primary" plain>{{ '新增域名' }}</el-button>
|
|
||||||
</template>
|
|
||||||
<el-table-column :label="'域名'" prop="backup"></el-table-column>
|
|
||||||
<el-table-column :label="'端口'" prop="remark"></el-table-column>
|
|
||||||
</ComplexTable>
|
|
||||||
</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>
|
|
||||||
<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-tabs>
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="优化">优化</el-tab-pane>
|
<el-tab-pane label="优化">优化</el-tab-pane>
|
||||||
<el-tab-pane label="反代">反代</el-tab-pane>
|
<el-tab-pane label="反代">反代</el-tab-pane>
|
||||||
@ -33,5 +16,17 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import LayoutContent from '@/layout/layout-content.vue';
|
import LayoutContent from '@/layout/layout-content.vue';
|
||||||
import ComplexTable from '@/components/complex-table/index.vue';
|
import { computed } from 'vue';
|
||||||
|
import Basic from './basic/index.vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const id = computed(() => {
|
||||||
|
return props.id;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -86,7 +86,12 @@
|
|||||||
<el-input v-model="website.primaryDomain"></el-input>
|
<el-input v-model="website.primaryDomain"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('website.otherDomains')" prop="otherDomains">
|
<el-form-item :label="$t('website.otherDomains')" prop="otherDomains">
|
||||||
<el-input v-model="website.otherDomains"></el-input>
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 2, maxRows: 6 }"
|
||||||
|
v-model="website.otherDomains"
|
||||||
|
:placeholder="$t('website.domainHelper')"
|
||||||
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('website.alias')" prop="alias">
|
<el-form-item :label="$t('website.alias')" prop="alias">
|
||||||
<el-input v-model="website.alias"></el-input>
|
<el-input v-model="website.alias"></el-input>
|
||||||
@ -123,7 +128,6 @@ const website = ref({
|
|||||||
type: 'deployment',
|
type: 'deployment',
|
||||||
alias: '',
|
alias: '',
|
||||||
remark: '',
|
remark: '',
|
||||||
domains: [],
|
|
||||||
appType: 'installed',
|
appType: 'installed',
|
||||||
appInstallID: 0,
|
appInstallID: 0,
|
||||||
webSiteGroupID: 1,
|
webSiteGroupID: 1,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<el-table-column :label="$t('commons.table.name')" fix show-overflow-tooltip prop="primaryDomain">
|
<el-table-column :label="$t('commons.table.name')" fix show-overflow-tooltip prop="primaryDomain">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-link @click="openConfig">{{ row.primaryDomain }}</el-link>
|
<el-link @click="openConfig(row.id)">{{ row.primaryDomain }}</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('commons.table.status')" prop="status"></el-table-column>
|
<el-table-column :label="$t('commons.table.status')" prop="status"></el-table-column>
|
||||||
@ -66,8 +66,8 @@ const search = async () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const openConfig = () => {
|
const openConfig = (id: number) => {
|
||||||
router.push({ name: 'WebsiteConfig' });
|
router.push({ name: 'WebsiteConfig', params: { id: id } });
|
||||||
};
|
};
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user