feat: 增加创建运行环境类型网站
This commit is contained in:
committed by
zhengkunwang223
parent
d4c1caa26a
commit
c629fa9575
@@ -96,6 +96,28 @@ func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, appDetailDTO)
|
helper.SuccessWithData(c, appDetailDTO)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags App
|
||||||
|
// @Summary Search app detail by id
|
||||||
|
// @Description 通过 id 获取应用详情
|
||||||
|
// @Accept json
|
||||||
|
// @Param appId path integer true "id"
|
||||||
|
// @Success 200 {object} response.AppDetailDTO
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /apps/detail/:id[get]
|
||||||
|
func (b *BaseApi) GetAppDetailByID(c *gin.Context) {
|
||||||
|
appDetailID, err := helper.GetIntParamByKey(c, "id")
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
appDetailDTO, err := appService.GetAppDetailByID(appDetailID)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, appDetailDTO)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags App
|
// @Tags App
|
||||||
// @Summary Install app
|
// @Summary Install app
|
||||||
// @Description 安装应用
|
// @Description 安装应用
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ type WebsiteCreate struct {
|
|||||||
AppInstall NewAppInstall `json:"appInstall"`
|
AppInstall NewAppInstall `json:"appInstall"`
|
||||||
AppID uint `json:"appID"`
|
AppID uint `json:"appID"`
|
||||||
AppInstallID uint `json:"appInstallID"`
|
AppInstallID uint `json:"appInstallID"`
|
||||||
|
|
||||||
|
RuntimeID uint `json:"runtimeID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NewAppInstall struct {
|
type NewAppInstall struct {
|
||||||
|
|||||||
@@ -6,5 +6,4 @@ type RuntimeRes struct {
|
|||||||
model.Runtime
|
model.Runtime
|
||||||
AppParams []AppParam `json:"appParams"`
|
AppParams []AppParam `json:"appParams"`
|
||||||
AppID uint `json:"appId"`
|
AppID uint `json:"appId"`
|
||||||
Version string `json:"version"`
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type Website struct {
|
|||||||
ErrorLog bool `json:"errorLog"`
|
ErrorLog bool `json:"errorLog"`
|
||||||
AccessLog bool `json:"accessLog"`
|
AccessLog bool `json:"accessLog"`
|
||||||
DefaultServer bool `json:"defaultServer"`
|
DefaultServer bool `json:"defaultServer"`
|
||||||
|
RuntimeID uint `gorm:"type:integer" json:"runtimeID"`
|
||||||
Domains []WebsiteDomain `json:"domains" gorm:"-:migration"`
|
Domains []WebsiteDomain `json:"domains" gorm:"-:migration"`
|
||||||
WebsiteSSL WebsiteSSL `json:"webSiteSSL" gorm:"-:migration"`
|
WebsiteSSL WebsiteSSL `json:"webSiteSSL" gorm:"-:migration"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ type RuntimeRepo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type IRuntimeRepo interface {
|
type IRuntimeRepo interface {
|
||||||
WithNameOrImage(name string, image string) DBOption
|
WithName(name string) DBOption
|
||||||
WithOtherNameOrImage(name string, image string, id uint) DBOption
|
WithImage(image string) DBOption
|
||||||
|
WithNotId(id uint) DBOption
|
||||||
Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error)
|
Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error)
|
||||||
Create(ctx context.Context, runtime *model.Runtime) error
|
Create(ctx context.Context, runtime *model.Runtime) error
|
||||||
Save(runtime *model.Runtime) error
|
Save(runtime *model.Runtime) error
|
||||||
@@ -23,15 +24,21 @@ func NewIRunTimeRepo() IRuntimeRepo {
|
|||||||
return &RuntimeRepo{}
|
return &RuntimeRepo{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RuntimeRepo) WithNameOrImage(name string, image string) DBOption {
|
func (r *RuntimeRepo) WithName(name string) DBOption {
|
||||||
return func(g *gorm.DB) *gorm.DB {
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
return g.Where("name = ? or image = ?", name, image)
|
return g.Where("name = ?", name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RuntimeRepo) WithOtherNameOrImage(name string, image string, id uint) DBOption {
|
func (r *RuntimeRepo) WithImage(image string) DBOption {
|
||||||
return func(g *gorm.DB) *gorm.DB {
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
return g.Where("name = ? or image = ? and id != ?", name, image, id)
|
return g.Where("image = ?", image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuntimeRepo) WithNotId(id uint) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("id != ?", id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ type IAppService interface {
|
|||||||
Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error)
|
Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error)
|
||||||
SyncAppList() error
|
SyncAppList() error
|
||||||
GetAppUpdate() (*response.AppUpdateRes, error)
|
GetAppUpdate() (*response.AppUpdateRes, error)
|
||||||
|
GetAppDetailByID(id uint) (*response.AppDetailDTO, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIAppService() IAppService {
|
func NewIAppService() IAppService {
|
||||||
@@ -206,6 +207,20 @@ func (a AppService) GetAppDetail(appId uint, version, appType string) (response.
|
|||||||
}
|
}
|
||||||
return appDetailDTO, nil
|
return appDetailDTO, nil
|
||||||
}
|
}
|
||||||
|
func (a AppService) GetAppDetailByID(id uint) (*response.AppDetailDTO, error) {
|
||||||
|
res := &response.AppDetailDTO{}
|
||||||
|
appDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(id))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res.AppDetail = appDetail
|
||||||
|
paramMap := make(map[string]interface{})
|
||||||
|
if err := json.Unmarshal([]byte(appDetail.Params), ¶mMap); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res.Params = paramMap
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error) {
|
func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error) {
|
||||||
if err := docker.CreateDefaultDockerNetwork(); err != nil {
|
if err := docker.CreateDefaultDockerNetwork(); err != nil {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/subosito/gotenv"
|
"github.com/subosito/gotenv"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -207,7 +208,21 @@ func updateInstall(installId uint, detailId uint) error {
|
|||||||
if err := NewIBackupService().AppBackup(dto.CommonBackup{Name: install.App.Key, DetailName: install.Name}); err != nil {
|
if err := NewIBackupService().AppBackup(dto.CommonBackup{Name: install.App.Key, DetailName: install.Name}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err = compose.Down(install.GetComposePath()); err != nil {
|
|
||||||
|
detailDir := path.Join(constant.ResourceDir, "apps", install.App.Key, "versions", detail.Version)
|
||||||
|
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("cp -rf %s/* %s", detailDir, install.GetPath()))
|
||||||
|
stdout, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
if stdout != nil {
|
||||||
|
return errors.New(string(stdout))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if out, err := compose.Down(install.GetComposePath()); err != nil {
|
||||||
|
if out != "" {
|
||||||
|
return errors.New(out)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
install.DockerCompose = detail.DockerCompose
|
install.DockerCompose = detail.DockerCompose
|
||||||
@@ -218,7 +233,10 @@ func updateInstall(installId uint, detailId uint) error {
|
|||||||
if err := fileOp.WriteFile(install.GetComposePath(), strings.NewReader(install.DockerCompose), 0775); err != nil {
|
if err := fileOp.WriteFile(install.GetComposePath(), strings.NewReader(install.DockerCompose), 0775); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err = compose.Up(install.GetComposePath()); err != nil {
|
if out, err := compose.Up(install.GetComposePath()); err != nil {
|
||||||
|
if out != "" {
|
||||||
|
return errors.New(out)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return appInstallRepo.Save(&install)
|
return appInstallRepo.Save(&install)
|
||||||
|
|||||||
@@ -35,19 +35,24 @@ func NewRuntimeService() IRuntimeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RuntimeService) Create(create request.RuntimeCreate) (err error) {
|
func (r *RuntimeService) Create(create request.RuntimeCreate) (err error) {
|
||||||
exist, _ := runtimeRepo.GetFirst(runtimeRepo.WithNameOrImage(create.Name, create.Image))
|
exist, _ := runtimeRepo.GetFirst(runtimeRepo.WithName(create.Name))
|
||||||
if exist != nil {
|
if exist != nil {
|
||||||
return buserr.New(constant.ErrNameOrImageIsExist)
|
return buserr.New(constant.ErrNameIsExist)
|
||||||
}
|
}
|
||||||
if create.Resource == constant.ResourceLocal {
|
if create.Resource == constant.ResourceLocal {
|
||||||
runtime := &model.Runtime{
|
runtime := &model.Runtime{
|
||||||
Name: create.Name,
|
Name: create.Name,
|
||||||
Resource: create.Resource,
|
Resource: create.Resource,
|
||||||
Type: create.Type,
|
Type: create.Type,
|
||||||
|
Version: create.Version,
|
||||||
Status: constant.RuntimeNormal,
|
Status: constant.RuntimeNormal,
|
||||||
}
|
}
|
||||||
return runtimeRepo.Create(context.Background(), runtime)
|
return runtimeRepo.Create(context.Background(), runtime)
|
||||||
}
|
}
|
||||||
|
exist, _ = runtimeRepo.GetFirst(runtimeRepo.WithImage(create.Image))
|
||||||
|
if exist != nil {
|
||||||
|
return buserr.New(constant.ErrImageExist)
|
||||||
|
}
|
||||||
appDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(create.AppDetailID))
|
appDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(create.AppDetailID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -134,6 +139,7 @@ func (r *RuntimeService) Delete(id uint) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//TODO 校验网站关联
|
//TODO 校验网站关联
|
||||||
|
//TODO 删除镜像
|
||||||
if runtime.Resource == constant.ResourceAppstore {
|
if runtime.Resource == constant.ResourceAppstore {
|
||||||
runtimeDir := path.Join(constant.RuntimeDir, runtime.Type, runtime.Name)
|
runtimeDir := path.Join(constant.RuntimeDir, runtime.Type, runtime.Name)
|
||||||
if err := files.NewFileOp().DeleteDir(runtimeDir); err != nil {
|
if err := files.NewFileOp().DeleteDir(runtimeDir); err != nil {
|
||||||
@@ -158,7 +164,6 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeRes, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
res.AppID = appDetail.AppId
|
res.AppID = appDetail.AppId
|
||||||
res.Version = appDetail.Version
|
|
||||||
var (
|
var (
|
||||||
appForm dto.AppForm
|
appForm dto.AppForm
|
||||||
appParams []response.AppParam
|
appParams []response.AppParam
|
||||||
@@ -207,10 +212,6 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeRes, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||||
exist, _ := runtimeRepo.GetFirst(runtimeRepo.WithOtherNameOrImage(req.Name, req.Image, req.ID))
|
|
||||||
if exist != nil {
|
|
||||||
return buserr.New(constant.ErrNameOrImageIsExist)
|
|
||||||
}
|
|
||||||
runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(req.ID))
|
runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -219,6 +220,10 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
|||||||
runtime.Version = req.Version
|
runtime.Version = req.Version
|
||||||
return runtimeRepo.Save(runtime)
|
return runtimeRepo.Save(runtime)
|
||||||
}
|
}
|
||||||
|
exist, _ := runtimeRepo.GetFirst(runtimeRepo.WithImage(req.Name), runtimeRepo.WithNotId(req.ID))
|
||||||
|
if exist != nil {
|
||||||
|
return buserr.New(constant.ErrImageExist)
|
||||||
|
}
|
||||||
runtimeDir := path.Join(constant.RuntimeDir, runtime.Type, runtime.Name)
|
runtimeDir := path.Join(constant.RuntimeDir, runtime.Type, runtime.Name)
|
||||||
composeContent, envContent, _, err := handleParams(req.Image, runtime.Type, runtimeDir, req.Params)
|
composeContent, envContent, _, err := handleParams(req.Image, runtime.Type, runtimeDir, req.Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -131,7 +131,10 @@ func (w WebsiteService) CreateWebsite(ctx context.Context, create request.Websit
|
|||||||
ErrorLog: true,
|
ErrorLog: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
var appInstall *model.AppInstall
|
var (
|
||||||
|
appInstall *model.AppInstall
|
||||||
|
runtime *model.Runtime
|
||||||
|
)
|
||||||
switch create.Type {
|
switch create.Type {
|
||||||
case constant.Deployment:
|
case constant.Deployment:
|
||||||
if create.AppType == constant.NewApp {
|
if create.AppType == constant.NewApp {
|
||||||
@@ -153,6 +156,30 @@ func (w WebsiteService) CreateWebsite(ctx context.Context, create request.Websit
|
|||||||
appInstall = &install
|
appInstall = &install
|
||||||
website.AppInstallID = appInstall.ID
|
website.AppInstallID = appInstall.ID
|
||||||
}
|
}
|
||||||
|
case constant.Runtime:
|
||||||
|
var err error
|
||||||
|
runtime, err = runtimeRepo.GetFirst(commonRepo.WithByID(create.RuntimeID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if runtime.Resource == constant.ResourceAppstore {
|
||||||
|
var req request.AppInstallCreate
|
||||||
|
req.Name = create.PrimaryDomain
|
||||||
|
req.AppDetailId = create.AppInstall.AppDetailId
|
||||||
|
req.Params = create.AppInstall.Params
|
||||||
|
req.Params["IMAGE_NAME"] = runtime.Image
|
||||||
|
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Params["PANEL_WEBSITE_DIR"] = path.Join(nginxInstall.GetPath(), "/www")
|
||||||
|
install, err := NewIAppService().Install(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
website.AppInstallID = install.ID
|
||||||
|
appInstall = install
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := websiteRepo.Create(ctx, website); err != nil {
|
if err := websiteRepo.Create(ctx, website); err != nil {
|
||||||
@@ -180,7 +207,7 @@ func (w WebsiteService) CreateWebsite(ctx context.Context, create request.Websit
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return configDefaultNginx(website, domains, appInstall)
|
return configDefaultNginx(website, domains, appInstall, runtime)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteService) OpWebsite(req request.WebsiteOp) error {
|
func (w WebsiteService) OpWebsite(req request.WebsiteOp) error {
|
||||||
|
|||||||
@@ -43,15 +43,28 @@ func getDomain(domainStr string, websiteID uint) (model.WebsiteDomain, error) {
|
|||||||
return model.WebsiteDomain{}, nil
|
return model.WebsiteDomain{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createStaticHtml(website *model.Website) error {
|
func createIndexFile(website *model.Website, runtime *model.Runtime) error {
|
||||||
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
indexFolder := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name, "www", "sites", website.Alias, "index")
|
indexFolder := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name, "www", "sites", website.Alias, "index")
|
||||||
indexPath := path.Join(indexFolder, "index.html")
|
indexPath := ""
|
||||||
indexContent := string(nginx_conf.Index)
|
indexContent := ""
|
||||||
|
switch website.Type {
|
||||||
|
case constant.Static:
|
||||||
|
indexPath = path.Join(indexFolder, "index.html")
|
||||||
|
indexContent = string(nginx_conf.Index)
|
||||||
|
case constant.Runtime:
|
||||||
|
if runtime.Type == constant.RuntimePHP {
|
||||||
|
indexPath = path.Join(indexFolder, "index.php")
|
||||||
|
indexContent = string(nginx_conf.IndexPHP)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
if !fileOp.Stat(indexFolder) {
|
if !fileOp.Stat(indexFolder) {
|
||||||
if err := fileOp.CreateDir(indexFolder, 0755); err != nil {
|
if err := fileOp.CreateDir(indexFolder, 0755); err != nil {
|
||||||
@@ -69,7 +82,7 @@ func createStaticHtml(website *model.Website) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createWebsiteFolder(nginxInstall model.AppInstall, website *model.Website) error {
|
func createWebsiteFolder(nginxInstall model.AppInstall, website *model.Website, runtime *model.Runtime) error {
|
||||||
nginxFolder := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name)
|
nginxFolder := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name)
|
||||||
siteFolder := path.Join(nginxFolder, "www", "sites", website.Alias)
|
siteFolder := path.Join(nginxFolder, "www", "sites", website.Alias)
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
@@ -92,8 +105,8 @@ func createWebsiteFolder(nginxInstall model.AppInstall, website *model.Website)
|
|||||||
if err := fileOp.CreateDir(path.Join(siteFolder, "ssl"), 0755); err != nil {
|
if err := fileOp.CreateDir(path.Join(siteFolder, "ssl"), 0755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if website.Type == constant.Static {
|
if website.Type == constant.Static || website.Type == constant.Runtime {
|
||||||
if err := createStaticHtml(website); err != nil {
|
if err := createIndexFile(website, runtime); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,12 +114,12 @@ func createWebsiteFolder(nginxInstall model.AppInstall, website *model.Website)
|
|||||||
return fileOp.CopyDir(path.Join(nginxFolder, "www", "common", "waf", "rules"), path.Join(siteFolder, "waf"))
|
return fileOp.CopyDir(path.Join(nginxFolder, "www", "common", "waf", "rules"), path.Join(siteFolder, "waf"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, appInstall *model.AppInstall) error {
|
func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, appInstall *model.AppInstall, runtime *model.Runtime) error {
|
||||||
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := createWebsiteFolder(nginxInstall, website); err != nil {
|
if err := createWebsiteFolder(nginxInstall, website, runtime); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,9 +153,21 @@ func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, a
|
|||||||
server.UpdateRootProxy([]string{proxy})
|
server.UpdateRootProxy([]string{proxy})
|
||||||
case constant.Static:
|
case constant.Static:
|
||||||
server.UpdateRoot(path.Join("/www/sites", website.Alias, "index"))
|
server.UpdateRoot(path.Join("/www/sites", website.Alias, "index"))
|
||||||
server.UpdateRootLocation()
|
//server.UpdateRootLocation()
|
||||||
case constant.Proxy:
|
case constant.Proxy:
|
||||||
server.UpdateRootProxy([]string{website.Proxy})
|
server.UpdateRootProxy([]string{website.Proxy})
|
||||||
|
case constant.Runtime:
|
||||||
|
if runtime.Resource == constant.ResourceLocal {
|
||||||
|
server.UpdateRoot(path.Join("/www/sites", website.Alias, "index"))
|
||||||
|
}
|
||||||
|
if runtime.Resource == constant.ResourceAppstore {
|
||||||
|
switch runtime.Type {
|
||||||
|
case constant.RuntimePHP:
|
||||||
|
server.UpdateRoot(path.Join("/www/sites", website.Alias, "index"))
|
||||||
|
proxy := fmt.Sprintf("127.0.0.1:%d", appInstall.HttpPort)
|
||||||
|
server.UpdatePHPProxy([]string{proxy})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.FilePath = configPath
|
config.FilePath = configPath
|
||||||
|
|||||||
@@ -106,8 +106,8 @@ var (
|
|||||||
|
|
||||||
// runtime
|
// runtime
|
||||||
var (
|
var (
|
||||||
ErrDirNotFound = "ErrDirNotFound"
|
ErrDirNotFound = "ErrDirNotFound"
|
||||||
ErrFileNotExist = "ErrFileNotExist"
|
ErrFileNotExist = "ErrFileNotExist"
|
||||||
ErrImageBuildErr = "ErrImageBuildErr"
|
ErrImageBuildErr = "ErrImageBuildErr"
|
||||||
ErrNameOrImageIsExist = "ErrNameOrImageIsExist"
|
ErrImageExist = "ErrImageExist"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ const (
|
|||||||
Deployment = "deployment"
|
Deployment = "deployment"
|
||||||
Static = "static"
|
Static = "static"
|
||||||
Proxy = "proxy"
|
Proxy = "proxy"
|
||||||
|
Runtime = "runtime"
|
||||||
|
|
||||||
SSLExisted = "existed"
|
SSLExisted = "existed"
|
||||||
SSLAuto = "auto"
|
SSLAuto = "auto"
|
||||||
|
|||||||
@@ -64,4 +64,4 @@ ErrObjectInUsed: "This object is in use and cannot be deleted"
|
|||||||
ErrDirNotFound: "The build folder does not exist! Please check file integrity!"
|
ErrDirNotFound: "The build folder does not exist! Please check file integrity!"
|
||||||
ErrFileNotExist: "{{ .detail }} file does not exist! Please check source file integrity!"
|
ErrFileNotExist: "{{ .detail }} file does not exist! Please check source file integrity!"
|
||||||
ErrImageBuildErr: "Image build failed"
|
ErrImageBuildErr: "Image build failed"
|
||||||
ErrNameOrImageIsExist: "Duplicate name or image"
|
ErrImageExist: "Image is already exist!"
|
||||||
@@ -64,4 +64,4 @@ ErrObjectInUsed: "该对象正被使用,无法删除"
|
|||||||
ErrDirNotFound: "build 文件夹不存在!请检查文件完整性!"
|
ErrDirNotFound: "build 文件夹不存在!请检查文件完整性!"
|
||||||
ErrFileNotExist: "{{ .detail }} 文件不存在!请检查源文件完整性!"
|
ErrFileNotExist: "{{ .detail }} 文件不存在!请检查源文件完整性!"
|
||||||
ErrImageBuildErr: "镜像 build 失败"
|
ErrImageBuildErr: "镜像 build 失败"
|
||||||
ErrNameOrImageIsExist: "名称或者镜像重复"
|
ErrImageExist: "镜像已存在!"
|
||||||
@@ -251,6 +251,6 @@ var AddDefaultGroup = &gormigrate.Migration{
|
|||||||
var AddTableRuntime = &gormigrate.Migration{
|
var AddTableRuntime = &gormigrate.Migration{
|
||||||
ID: "20230330-add-table-runtime",
|
ID: "20230330-add-table-runtime",
|
||||||
Migrate: func(tx *gorm.DB) error {
|
Migrate: func(tx *gorm.DB) error {
|
||||||
return tx.AutoMigrate(&model.Runtime{})
|
return tx.AutoMigrate(&model.Runtime{}, &model.Website{})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) {
|
|||||||
appRouter.POST("/search", baseApi.SearchApp)
|
appRouter.POST("/search", baseApi.SearchApp)
|
||||||
appRouter.GET("/:key", baseApi.GetApp)
|
appRouter.GET("/:key", baseApi.GetApp)
|
||||||
appRouter.GET("/detail/:appId/:version/:type", baseApi.GetAppDetail)
|
appRouter.GET("/detail/:appId/:version/:type", baseApi.GetAppDetail)
|
||||||
|
appRouter.GET("/details/:id", baseApi.GetAppDetailByID)
|
||||||
appRouter.POST("/install", baseApi.InstallApp)
|
appRouter.POST("/install", baseApi.InstallApp)
|
||||||
appRouter.GET("/tags", baseApi.GetAppTags)
|
appRouter.GET("/tags", baseApi.GetAppTags)
|
||||||
appRouter.GET("/installed/:appInstallId/versions", baseApi.GetUpdateVersions)
|
appRouter.GET("/installed/:appInstallId/versions", baseApi.GetUpdateVersions)
|
||||||
|
|||||||
@@ -252,19 +252,15 @@ func (f FileOp) Copy(src, dst string) error {
|
|||||||
if src = path.Clean("/" + src); src == "" {
|
if src = path.Clean("/" + src); src == "" {
|
||||||
return os.ErrNotExist
|
return os.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
if dst = path.Clean("/" + dst); dst == "" {
|
if dst = path.Clean("/" + dst); dst == "" {
|
||||||
return os.ErrNotExist
|
return os.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
if src == "/" || dst == "/" {
|
if src == "/" || dst == "/" {
|
||||||
return os.ErrInvalid
|
return os.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
if dst == src {
|
if dst == src {
|
||||||
return os.ErrInvalid
|
return os.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := f.Fs.Stat(src)
|
info, err := f.Fs.Stat(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -272,7 +268,6 @@ func (f FileOp) Copy(src, dst string) error {
|
|||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return f.CopyDir(src, dst)
|
return f.CopyDir(src, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
return f.CopyFile(src, dst)
|
return f.CopyFile(src, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -237,6 +237,29 @@ func (s *Server) UpdateRootProxy(proxy []string) {
|
|||||||
s.UpdateDirectiveBySecondKey("location", "/", newDir)
|
s.UpdateDirectiveBySecondKey("location", "/", newDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) UpdatePHPProxy(proxy []string) {
|
||||||
|
newDir := Directive{
|
||||||
|
Name: "location",
|
||||||
|
Parameters: []string{"~ [^/]\\.php(/|$)"},
|
||||||
|
Block: &Block{},
|
||||||
|
}
|
||||||
|
block := &Block{}
|
||||||
|
block.Directives = append(block.Directives, &Directive{
|
||||||
|
Name: "fastcgi_pass",
|
||||||
|
Parameters: proxy,
|
||||||
|
})
|
||||||
|
block.Directives = append(block.Directives, &Directive{
|
||||||
|
Name: "include",
|
||||||
|
Parameters: []string{"fastcgi-php.conf"},
|
||||||
|
})
|
||||||
|
block.Directives = append(block.Directives, &Directive{
|
||||||
|
Name: "include",
|
||||||
|
Parameters: []string{"fastcgi_params"},
|
||||||
|
})
|
||||||
|
newDir.Block = block
|
||||||
|
s.UpdateDirectiveBySecondKey("location", "~ [^/]\\.php(/|$)", newDir)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) UpdateDirectiveBySecondKey(name string, key string, directive Directive) {
|
func (s *Server) UpdateDirectiveBySecondKey(name string, key string, directive Directive) {
|
||||||
directives := s.Directives
|
directives := s.Directives
|
||||||
index := -1
|
index := -1
|
||||||
|
|||||||
25
cmd/server/nginx_conf/index.php
Normal file
25
cmd/server/nginx_conf/index.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
|
||||||
|
echo '<h1 style="text-align: center;">欢迎使用 PHP!</h1>';
|
||||||
|
echo '<h2>版本信息</h2>';
|
||||||
|
|
||||||
|
echo '<ul>';
|
||||||
|
echo '<li>PHP版本:', PHP_VERSION, '</li>';
|
||||||
|
echo '</ul>';
|
||||||
|
|
||||||
|
echo '<h2>已安装扩展</h2>';
|
||||||
|
printExtensions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已安装扩展列表
|
||||||
|
*/
|
||||||
|
function printExtensions()
|
||||||
|
{
|
||||||
|
echo '<ol>';
|
||||||
|
foreach (get_loaded_extensions() as $i => $name) {
|
||||||
|
echo "<li>", $name, '=', phpversion($name), '</li>';
|
||||||
|
}
|
||||||
|
echo '</ol>';
|
||||||
|
}
|
||||||
@@ -12,3 +12,6 @@ var WebsiteDefault []byte
|
|||||||
|
|
||||||
//go:embed index.html
|
//go:embed index.html
|
||||||
var Index []byte
|
var Index []byte
|
||||||
|
|
||||||
|
//go:embed index.php
|
||||||
|
var IndexPHP []byte
|
||||||
|
|||||||
@@ -11,16 +11,16 @@ export namespace Runtime {
|
|||||||
params: string;
|
params: string;
|
||||||
type: string;
|
type: string;
|
||||||
resource: string;
|
resource: string;
|
||||||
|
version: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RuntimeReq extends ReqPage {
|
export interface RuntimeReq extends ReqPage {
|
||||||
name: string;
|
name?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RuntimeDTO extends Runtime {
|
export interface RuntimeDTO extends Runtime {
|
||||||
appParams: App.InstallParams[];
|
appParams: App.InstallParams[];
|
||||||
appId: number;
|
appId: number;
|
||||||
version: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RuntimeCreate {
|
export interface RuntimeCreate {
|
||||||
|
|||||||
@@ -22,8 +22,12 @@ export const GetAppTags = () => {
|
|||||||
return http.get<App.Tag[]>('apps/tags');
|
return http.get<App.Tag[]>('apps/tags');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const GetAppDetail = (id: number, version: string, type: string) => {
|
export const GetAppDetail = (appID: number, version: string, type: string) => {
|
||||||
return http.get<App.AppDetail>(`apps/detail/${id}/${version}/${type}`);
|
return http.get<App.AppDetail>(`apps/detail/${appID}/${version}/${type}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GetAppDetailByID = (id: number) => {
|
||||||
|
return http.get<App.AppDetail>(`apps/details/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const InstallApp = (install: App.AppInstall) => {
|
export const InstallApp = (install: App.AppInstall) => {
|
||||||
|
|||||||
@@ -1134,6 +1134,10 @@ const message = {
|
|||||||
websiteStatictHelper: 'Create a website directory on the host',
|
websiteStatictHelper: 'Create a website directory on the host',
|
||||||
websiteProxyHelper:
|
websiteProxyHelper:
|
||||||
'The proxy has existing services, for example, the machine has installed the halo service using port 8080, then the proxy address is http://127.0.0.1:8080',
|
'The proxy has existing services, for example, the machine has installed the halo service using port 8080, then the proxy address is http://127.0.0.1:8080',
|
||||||
|
runtimeProxyHelper: 'Use runtime created from 1Panel',
|
||||||
|
runtime: 'Runtime',
|
||||||
|
deleteRuntimeHelper:
|
||||||
|
'The Runtime application needs to be deleted together with the website, please handle it with caution',
|
||||||
},
|
},
|
||||||
nginx: {
|
nginx: {
|
||||||
serverNamesHashBucketSizeHelper: 'The hash table size of the server name',
|
serverNamesHashBucketSizeHelper: 'The hash table size of the server name',
|
||||||
|
|||||||
@@ -1133,6 +1133,9 @@ const message = {
|
|||||||
restoreHelper: '确认使用此备份恢复?',
|
restoreHelper: '确认使用此备份恢复?',
|
||||||
wafValueHelper: '值',
|
wafValueHelper: '值',
|
||||||
wafRemarkHelper: '描述',
|
wafRemarkHelper: '描述',
|
||||||
|
runtimeProxyHelper: '使用从 1Panel 创建的运行环境',
|
||||||
|
runtime: '运行环境',
|
||||||
|
deleteRuntimeHelper: '运行环境应用需要跟网站一并删除,请谨慎处理',
|
||||||
},
|
},
|
||||||
nginx: {
|
nginx: {
|
||||||
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
||||||
|
|||||||
@@ -22,15 +22,15 @@
|
|||||||
v-model="runtime.resource"
|
v-model="runtime.resource"
|
||||||
@change="changeResource(runtime.resource)"
|
@change="changeResource(runtime.resource)"
|
||||||
>
|
>
|
||||||
<el-radio :label="'AppStore'" :value="'AppStore'">
|
<el-radio :label="'appstore'">
|
||||||
{{ $t('runtime.appstore') }}
|
{{ $t('runtime.appstore') }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
<el-radio :label="'Local'" :value="'Local'">
|
<el-radio :label="'local'">
|
||||||
{{ $t('runtime.local') }}
|
{{ $t('runtime.local') }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div v-if="runtime.resource === 'AppStore'">
|
<div v-if="runtime.resource === 'appstore'">
|
||||||
<el-form-item :label="$t('runtime.app')" prop="appId">
|
<el-form-item :label="$t('runtime.app')" prop="appId">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@@ -134,7 +134,7 @@ const runtime = ref<Runtime.RuntimeCreate>({
|
|||||||
image: '',
|
image: '',
|
||||||
params: {},
|
params: {},
|
||||||
type: 'php',
|
type: 'php',
|
||||||
resource: 'AppStore',
|
resource: 'appstore',
|
||||||
});
|
});
|
||||||
let rules = ref<any>({
|
let rules = ref<any>({
|
||||||
name: [Rules.appName],
|
name: [Rules.appName],
|
||||||
@@ -152,7 +152,7 @@ const handleClose = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const changeResource = (resource: string) => {
|
const changeResource = (resource: string) => {
|
||||||
if (resource === 'Local') {
|
if (resource === 'local') {
|
||||||
runtime.value.appDetailId = undefined;
|
runtime.value.appDetailId = undefined;
|
||||||
runtime.value.version = '';
|
runtime.value.version = '';
|
||||||
runtime.value.params = {};
|
runtime.value.params = {};
|
||||||
@@ -257,7 +257,7 @@ const acceptParams = async (props: OperateRrops) => {
|
|||||||
image: '',
|
image: '',
|
||||||
params: {},
|
params: {},
|
||||||
type: props.type,
|
type: props.type,
|
||||||
resource: 'AppStore',
|
resource: 'appstore',
|
||||||
};
|
};
|
||||||
searchApp(null);
|
searchApp(null);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()">
|
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()">
|
||||||
<el-table-column :label="$t('commons.table.name')" fix prop="name" min-width="120px">
|
<el-table-column :label="$t('commons.table.name')" fix prop="name" min-width="120px">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<Tooltip :text="row.name" />
|
<Tooltip :text="row.name" @click="openDetail(row)" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('runtime.resource')" prop="resource">
|
<el-table-column :label="$t('runtime.resource')" prop="resource">
|
||||||
|
|||||||
@@ -18,6 +18,10 @@
|
|||||||
label: i18n.global.t('website.proxy'),
|
label: i18n.global.t('website.proxy'),
|
||||||
value: 'proxy',
|
value: 'proxy',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: i18n.global.t('runtime.runtime'),
|
||||||
|
value: 'runtime',
|
||||||
|
},
|
||||||
]"
|
]"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
>
|
>
|
||||||
@@ -56,6 +60,12 @@
|
|||||||
type="info"
|
type="info"
|
||||||
:closable="false"
|
:closable="false"
|
||||||
/>
|
/>
|
||||||
|
<el-alert
|
||||||
|
v-if="website.type == 'runtime'"
|
||||||
|
:title="$t('website.runtimeProxyHelper')"
|
||||||
|
type="info"
|
||||||
|
:closable="false"
|
||||||
|
/>
|
||||||
<br />
|
<br />
|
||||||
<el-form
|
<el-form
|
||||||
ref="websiteForm"
|
ref="websiteForm"
|
||||||
@@ -140,6 +150,25 @@
|
|||||||
></Params>
|
></Params>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="website.type === 'runtime'">
|
||||||
|
<el-form-item :label="$t('runtime.runtime')" prop="runtimeID">
|
||||||
|
<el-select v-model="website.runtimeID" @change="changeApp()">
|
||||||
|
<el-option
|
||||||
|
v-for="(runtime, index) in runtimes"
|
||||||
|
:key="index"
|
||||||
|
:label="runtime.name"
|
||||||
|
:value="runtime.id"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<Params
|
||||||
|
:key="paramKey"
|
||||||
|
v-model:form="website.appinstall.params"
|
||||||
|
v-model:rules="rules.appinstall.params"
|
||||||
|
:params="appParams"
|
||||||
|
:propStart="'appinstall.params.'"
|
||||||
|
></Params>
|
||||||
|
</div>
|
||||||
<el-form-item :label="$t('website.primaryDomain')" prop="primaryDomain">
|
<el-form-item :label="$t('website.primaryDomain')" prop="primaryDomain">
|
||||||
<el-input
|
<el-input
|
||||||
v-model.trim="website.primaryDomain"
|
v-model.trim="website.primaryDomain"
|
||||||
@@ -187,7 +216,7 @@
|
|||||||
<script lang="ts" setup name="CreateWebSite">
|
<script lang="ts" setup name="CreateWebSite">
|
||||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
import { App } from '@/api/interface/app';
|
import { App } from '@/api/interface/app';
|
||||||
import { GetApp, GetAppDetail, SearchApp, GetAppInstalled } from '@/api/modules/app';
|
import { GetApp, GetAppDetail, SearchApp, GetAppInstalled, GetAppDetailByID } from '@/api/modules/app';
|
||||||
import { CreateWebsite, PreCheck } from '@/api/modules/website';
|
import { CreateWebsite, PreCheck } from '@/api/modules/website';
|
||||||
import { Rules } from '@/global/form-rules';
|
import { Rules } from '@/global/form-rules';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
@@ -198,6 +227,8 @@ import Check from '../check/index.vue';
|
|||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
import { GetGroupList } from '@/api/modules/group';
|
import { GetGroupList } from '@/api/modules/group';
|
||||||
import { Group } from '@/api/interface/group';
|
import { Group } from '@/api/interface/group';
|
||||||
|
import { SearchRuntimes } from '@/api/modules/runtime';
|
||||||
|
import { Runtime } from '@/api/interface/runtime';
|
||||||
|
|
||||||
const websiteForm = ref<FormInstance>();
|
const websiteForm = ref<FormInstance>();
|
||||||
const website = ref({
|
const website = ref({
|
||||||
@@ -210,6 +241,7 @@ const website = ref({
|
|||||||
webSiteGroupId: 1,
|
webSiteGroupId: 1,
|
||||||
otherDomains: '',
|
otherDomains: '',
|
||||||
proxy: '',
|
proxy: '',
|
||||||
|
runtimeID: undefined,
|
||||||
appinstall: {
|
appinstall: {
|
||||||
appId: 0,
|
appId: 0,
|
||||||
name: '',
|
name: '',
|
||||||
@@ -227,6 +259,7 @@ let rules = ref<any>({
|
|||||||
appInstallId: [Rules.requiredSelectBusiness],
|
appInstallId: [Rules.requiredSelectBusiness],
|
||||||
appType: [Rules.requiredInput],
|
appType: [Rules.requiredInput],
|
||||||
proxy: [Rules.requiredInput],
|
proxy: [Rules.requiredInput],
|
||||||
|
runtimeID: [Rules.requiredSelectBusiness],
|
||||||
appinstall: {
|
appinstall: {
|
||||||
name: [Rules.appName],
|
name: [Rules.appName],
|
||||||
appId: [Rules.requiredSelectBusiness],
|
appId: [Rules.requiredSelectBusiness],
|
||||||
@@ -251,6 +284,11 @@ let appParams = ref<App.AppParams>();
|
|||||||
let paramKey = ref(1);
|
let paramKey = ref(1);
|
||||||
let preCheckRef = ref();
|
let preCheckRef = ref();
|
||||||
let staticPath = ref('');
|
let staticPath = ref('');
|
||||||
|
const runtimeReq = ref<Runtime.RuntimeReq>({
|
||||||
|
page: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
});
|
||||||
|
const runtimes = ref<Runtime.RuntimeDTO[]>([]);
|
||||||
|
|
||||||
const em = defineEmits(['close']);
|
const em = defineEmits(['close']);
|
||||||
|
|
||||||
@@ -264,6 +302,8 @@ const changeType = (type: string) => {
|
|||||||
if (appInstalles.value && appInstalles.value.length > 0) {
|
if (appInstalles.value && appInstalles.value.length > 0) {
|
||||||
website.value.appInstallId = appInstalles.value[0].id;
|
website.value.appInstallId = appInstalles.value[0].id;
|
||||||
}
|
}
|
||||||
|
} else if (type == 'runtime') {
|
||||||
|
getRuntimes();
|
||||||
} else {
|
} else {
|
||||||
website.value.appInstallId = undefined;
|
website.value.appInstallId = undefined;
|
||||||
}
|
}
|
||||||
@@ -273,7 +313,7 @@ const changeType = (type: string) => {
|
|||||||
const searchAppInstalled = () => {
|
const searchAppInstalled = () => {
|
||||||
GetAppInstalled({ type: 'website', unused: true }).then((res) => {
|
GetAppInstalled({ type: 'website', unused: true }).then((res) => {
|
||||||
appInstalles.value = res.data;
|
appInstalles.value = res.data;
|
||||||
if (res.data.length > 0) {
|
if (res.data && res.data.length > 0) {
|
||||||
website.value.appInstallId = res.data[0].id;
|
website.value.appInstallId = res.data[0].id;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -318,6 +358,27 @@ const getAppDetail = (version: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getAppDetailByID = (id: number) => {
|
||||||
|
GetAppDetailByID(id).then((res) => {
|
||||||
|
website.value.appinstall.appDetailId = res.data.id;
|
||||||
|
appDetail.value = res.data;
|
||||||
|
appParams.value = res.data.params;
|
||||||
|
paramKey.value++;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getRuntimes = async () => {
|
||||||
|
try {
|
||||||
|
const res = await SearchRuntimes(runtimeReq.value);
|
||||||
|
runtimes.value = res.data.items || [];
|
||||||
|
if (runtimes.value.length > 0) {
|
||||||
|
const first = runtimes.value[0];
|
||||||
|
website.value.runtimeID = first.id;
|
||||||
|
getAppDetailByID(first.appDetailId);
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
const acceptParams = async (installPath: string) => {
|
const acceptParams = async (installPath: string) => {
|
||||||
if (websiteForm.value) {
|
if (websiteForm.value) {
|
||||||
websiteForm.value.resetFields();
|
websiteForm.value.resetFields();
|
||||||
@@ -328,7 +389,7 @@ const acceptParams = async (installPath: string) => {
|
|||||||
groups.value = res.data;
|
groups.value = res.data;
|
||||||
open.value = true;
|
open.value = true;
|
||||||
website.value.webSiteGroupId = res.data[0].id;
|
website.value.webSiteGroupId = res.data[0].id;
|
||||||
|
website.value.type = 'deployment';
|
||||||
searchAppInstalled();
|
searchAppInstalled();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,18 @@
|
|||||||
{{ $t('website.forceDeleteHelper') }}
|
{{ $t('website.forceDeleteHelper') }}
|
||||||
</span>
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="type === 'deployment'">
|
<el-form-item v-if="type === 'deployment' || runtimeApp">
|
||||||
<el-checkbox v-model="deleteReq.deleteApp" :label="$t('website.deleteApp')" />
|
<el-checkbox
|
||||||
|
v-model="deleteReq.deleteApp"
|
||||||
|
:disabled="runtimeApp"
|
||||||
|
:label="$t('website.deleteApp')"
|
||||||
|
/>
|
||||||
<span class="input-help">
|
<span class="input-help">
|
||||||
{{ $t('website.deleteAppHelper') }}
|
{{ $t('website.deleteAppHelper') }}
|
||||||
</span>
|
</span>
|
||||||
|
<span class="input-help" style="color: red">
|
||||||
|
{{ $t('website.deleteRuntimeHelper') }}
|
||||||
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-checkbox v-model="deleteReq.deleteBackup" :label="$t('website.deleteBackup')" />
|
<el-checkbox v-model="deleteReq.deleteBackup" :label="$t('website.deleteBackup')" />
|
||||||
@@ -66,6 +73,7 @@ const deleteForm = ref<FormInstance>();
|
|||||||
let deleteInfo = ref('');
|
let deleteInfo = ref('');
|
||||||
let websiteName = ref('');
|
let websiteName = ref('');
|
||||||
let deleteHelper = ref('');
|
let deleteHelper = ref('');
|
||||||
|
const runtimeApp = ref(false);
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
open.value = false;
|
open.value = false;
|
||||||
@@ -79,6 +87,10 @@ const acceptParams = async (website: Website.Website) => {
|
|||||||
deleteBackup: false,
|
deleteBackup: false,
|
||||||
forceDelete: false,
|
forceDelete: false,
|
||||||
};
|
};
|
||||||
|
if (website.type === 'runtime' && website.appInstallId > 0) {
|
||||||
|
runtimeApp.value = true;
|
||||||
|
deleteReq.value.deleteApp = true;
|
||||||
|
}
|
||||||
deleteInfo.value = '';
|
deleteInfo.value = '';
|
||||||
deleteReq.value.id = website.id;
|
deleteReq.value.id = website.id;
|
||||||
websiteName.value = website.primaryDomain;
|
websiteName.value = website.primaryDomain;
|
||||||
|
|||||||
Reference in New Issue
Block a user