feat: 增加配置 php 配置文件功能

This commit is contained in:
zhengkunwang223 2023-04-04 18:54:04 +08:00 committed by zhengkunwang223
parent c629fa9575
commit 04a76fd94d
19 changed files with 295 additions and 46 deletions

View File

@ -166,10 +166,13 @@ func (b *BaseApi) OperateInstalled(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := appInstallService.Operate(req); err != nil {
tx, ctx := helper.GetTxAndContext()
if err := appInstallService.Operate(ctx, req); err != nil {
tx.Rollback()
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
tx.Commit()
helper.SuccessWithData(c, nil)
}

View File

@ -189,14 +189,16 @@ func (b *BaseApi) GetWebsite(c *gin.Context) {
// @Param id path integer true "request"
// @Success 200 {object} response.FileInfo
// @Security ApiKeyAuth
// @Router /websites/:id/nginx [get]
// @Router /websites/:id/config/:type [get]
func (b *BaseApi) GetWebsiteNginx(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
fileInfo, err := websiteService.GetWebsiteNginxConfig(id)
configType := c.Param("type")
fileInfo, err := websiteService.GetWebsiteNginxConfig(id, configType)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return

View File

@ -25,6 +25,12 @@ type WebsiteCreate struct {
AppInstallID uint `json:"appInstallID"`
RuntimeID uint `json:"runtimeID"`
RuntimeConfig
}
type RuntimeConfig struct {
ProxyType string `json:"proxyType"`
Port int `json:"port"`
}
type NewAppInstall struct {

View File

@ -29,6 +29,7 @@ type IAppInstallRepo interface {
Page(page, size int, opts ...DBOption) (int64, []model.AppInstall, error)
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
LoadBaseInfo(key string, name string) (*RootInfo, error)
GetFirstByCtx(ctx context.Context, opts ...DBOption) (model.AppInstall, error)
}
func NewIAppInstallRepo() IAppInstallRepo {
@ -97,6 +98,13 @@ func (a *AppInstallRepo) GetFirst(opts ...DBOption) (model.AppInstall, error) {
return install, err
}
func (a *AppInstallRepo) GetFirstByCtx(ctx context.Context, opts ...DBOption) (model.AppInstall, error) {
var install model.AppInstall
db := getTx(ctx, opts...).Model(&model.AppInstall{})
err := db.Preload("App").First(&install).Error
return install, err
}
func (a *AppInstallRepo) Create(ctx context.Context, install *model.AppInstall) error {
db := getTx(ctx).Model(&model.AppInstall{})
return db.Create(&install).Error

View File

@ -1,6 +1,7 @@
package service
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
@ -40,7 +41,7 @@ type IAppInstallService interface {
LoadPort(key string) (int64, error)
LoadPassword(key string) (string, error)
SearchForWebsite(req request.AppInstalledSearch) ([]response.AppInstalledDTO, error)
Operate(req request.AppInstalledOperate) error
Operate(ctx context.Context, req request.AppInstalledOperate) error
Update(req request.AppInstalledUpdate) error
SyncAll(systemInit bool) error
GetServices(key string) ([]response.AppService, error)
@ -174,8 +175,8 @@ func (a *AppInstallService) SearchForWebsite(req request.AppInstalledSearch) ([]
return handleInstalled(installs, false)
}
func (a *AppInstallService) Operate(req request.AppInstalledOperate) error {
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallId))
func (a *AppInstallService) Operate(ctx context.Context, req request.AppInstalledOperate) error {
install, err := appInstallRepo.GetFirstByCtx(ctx, commonRepo.WithByID(req.InstallId))
if err != nil {
return err
}
@ -202,12 +203,9 @@ func (a *AppInstallService) Operate(req request.AppInstalledOperate) error {
}
return syncById(install.ID)
case constant.Delete:
tx, ctx := getTxAndContext()
if err := deleteAppInstall(ctx, install, req.DeleteBackup, req.ForceDelete, req.DeleteDB); err != nil && !req.ForceDelete {
tx.Rollback()
return err
}
tx.Commit()
return nil
case constant.Sync:
return syncById(install.ID)

View File

@ -8,6 +8,7 @@ import (
"os"
"path"
"reflect"
"regexp"
"strings"
"time"
@ -42,7 +43,7 @@ type IWebsiteService interface {
DeleteWebsiteDomain(domainId uint) error
GetNginxConfigByScope(req request.NginxScopeReq) (*response.WebsiteNginxConfig, error)
UpdateNginxConfigByScope(req request.NginxConfigUpdate) error
GetWebsiteNginxConfig(websiteId uint) (response.FileInfo, error)
GetWebsiteNginxConfig(websiteId uint, configType string) (response.FileInfo, error)
GetWebsiteHTTPS(websiteId uint) (response.WebsiteHTTPS, error)
OpWebsiteHTTPS(ctx context.Context, req request.WebsiteHTTPSOp) (response.WebsiteHTTPS, error)
PreInstallCheck(req request.WebsiteInstallCheckReq) ([]response.WebsitePreInstallCheck, error)
@ -104,7 +105,7 @@ func (w WebsiteService) GetWebsites() ([]response.WebsiteDTO, error) {
return websiteDTOs, nil
}
func (w WebsiteService) CreateWebsite(ctx context.Context, create request.WebsiteCreate) error {
func (w WebsiteService) CreateWebsite(ctx context.Context, create request.WebsiteCreate) (err error) {
if exist, _ := websiteRepo.GetBy(websiteRepo.WithDomain(create.PrimaryDomain)); len(exist) > 0 {
return buserr.New(constant.ErrDomainIsExist)
}
@ -125,6 +126,7 @@ func (w WebsiteService) CreateWebsite(ctx context.Context, create request.Websit
ExpireDate: defaultDate,
AppInstallID: create.AppInstallID,
WebsiteGroupID: create.WebsiteGroupID,
RuntimeID: create.RuntimeID,
Protocol: constant.ProtocolHTTP,
Proxy: create.Proxy,
AccessLog: true,
@ -135,6 +137,22 @@ func (w WebsiteService) CreateWebsite(ctx context.Context, create request.Websit
appInstall *model.AppInstall
runtime *model.Runtime
)
defer func() {
if err != nil {
if website.AppInstallID > 0 {
req := request.AppInstalledOperate{
InstallId: website.AppInstallID,
Operate: constant.Delete,
ForceDelete: true,
}
if err := NewIAppInstalledService().Operate(ctx, req); err != nil {
global.LOG.Errorf(err.Error())
}
}
}
}()
switch create.Type {
case constant.Deployment:
if create.AppType == constant.NewApp {
@ -164,7 +182,8 @@ func (w WebsiteService) CreateWebsite(ctx context.Context, create request.Websit
}
if runtime.Resource == constant.ResourceAppstore {
var req request.AppInstallCreate
req.Name = create.PrimaryDomain
reg, _ := regexp.Compile("[^a-z0-9_\\-]+")
req.Name = reg.ReplaceAllString(create.PrimaryDomain, "")
req.AppDetailId = create.AppInstall.AppDetailId
req.Params = create.AppInstall.Params
req.Params["IMAGE_NAME"] = runtime.Image
@ -182,7 +201,7 @@ func (w WebsiteService) CreateWebsite(ctx context.Context, create request.Websit
}
}
if err := websiteRepo.Create(ctx, website); err != nil {
if err = websiteRepo.Create(ctx, website); err != nil {
return err
}
var domains []model.WebsiteDomain
@ -203,11 +222,11 @@ func (w WebsiteService) CreateWebsite(ctx context.Context, create request.Websit
domains = append(domains, domainModel)
}
if len(domains) > 0 {
if err := websiteDomainRepo.BatchCreate(ctx, domains); err != nil {
if err = websiteDomainRepo.BatchCreate(ctx, domains); err != nil {
return err
}
}
return configDefaultNginx(website, domains, appInstall, runtime)
return configDefaultNginx(website, domains, appInstall, runtime, create.RuntimeConfig)
}
func (w WebsiteService) OpWebsite(req request.WebsiteOp) error {
@ -429,12 +448,14 @@ func (w WebsiteService) UpdateNginxConfigByScope(req request.NginxConfigUpdate)
return updateNginxConfig(constant.NginxScopeServer, params, &website)
}
func (w WebsiteService) GetWebsiteNginxConfig(websiteId uint) (response.FileInfo, error) {
func (w WebsiteService) GetWebsiteNginxConfig(websiteId uint, configType string) (response.FileInfo, error) {
website, err := websiteRepo.GetFirst(commonRepo.WithByID(websiteId))
if err != nil {
return response.FileInfo{}, err
}
configPath := ""
switch configType {
case constant.AppOpenresty:
nginxApp, err := appRepo.GetFirst(appRepo.WithKey(constant.AppOpenresty))
if err != nil {
return response.FileInfo{}, err
@ -443,9 +464,22 @@ func (w WebsiteService) GetWebsiteNginxConfig(websiteId uint) (response.FileInfo
if err != nil {
return response.FileInfo{}, err
}
configPath := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name, "conf", "conf.d", website.Alias+".conf")
configPath = path.Join(nginxInstall.GetPath(), "conf", "conf.d", website.Alias+".conf")
case constant.ConfigFPM:
runtimeInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
if err != nil {
return response.FileInfo{}, err
}
runtimeInstall.GetPath()
configPath = path.Join(runtimeInstall.GetPath(), "conf", "php-fpm.conf")
case constant.ConfigPHP:
runtimeInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
if err != nil {
return response.FileInfo{}, err
}
runtimeInstall.GetPath()
configPath = path.Join(runtimeInstall.GetPath(), "conf", "php.ini")
}
info, err := files.NewFileInfo(files.FileOption{
Path: configPath,
Expand: true,

View File

@ -105,6 +105,15 @@ func createWebsiteFolder(nginxInstall model.AppInstall, website *model.Website,
if err := fileOp.CreateDir(path.Join(siteFolder, "ssl"), 0755); err != nil {
return err
}
if runtime.Type == constant.RuntimePHP && runtime.Resource == constant.ResourceLocal {
phpPoolDir := path.Join(siteFolder, "php-pool")
if err := fileOp.CreateDir(phpPoolDir, 0755); err != nil {
return err
}
if err := fileOp.CreateFile(path.Join(phpPoolDir, "php-fpm.sock")); err != nil {
return err
}
}
if website.Type == constant.Static || website.Type == constant.Runtime {
if err := createIndexFile(website, runtime); err != nil {
return err
@ -114,7 +123,7 @@ func createWebsiteFolder(nginxInstall model.AppInstall, website *model.Website,
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, runtime *model.Runtime) error {
func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, appInstall *model.AppInstall, runtime *model.Runtime, runtimeConfig request.RuntimeConfig) error {
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return err
@ -147,25 +156,38 @@ func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, a
server.UpdateDirective("set", []string{"$RulePath", path.Join(siteFolder, "waf", "rules")})
server.UpdateDirective("set", []string{"$logdir", path.Join(siteFolder, "log")})
rootIndex := path.Join("/www/sites", website.Alias, "index")
switch website.Type {
case constant.Deployment:
proxy := fmt.Sprintf("http://127.0.0.1:%d", appInstall.HttpPort)
server.UpdateRootProxy([]string{proxy})
case constant.Static:
server.UpdateRoot(path.Join("/www/sites", website.Alias, "index"))
server.UpdateRoot(rootIndex)
//server.UpdateRootLocation()
case constant.Proxy:
server.UpdateRootProxy([]string{website.Proxy})
case constant.Runtime:
if runtime.Resource == constant.ResourceLocal {
server.UpdateRoot(path.Join("/www/sites", website.Alias, "index"))
switch runtime.Type {
case constant.RuntimePHP:
server.UpdateRoot(rootIndex)
proxy := ""
localPath := path.Join(nginxInstall.GetPath(), rootIndex, "index.php")
if runtimeConfig.ProxyType == constant.RuntimeProxyUnix {
proxy = fmt.Sprintf("unix:%s", path.Join("/www/sites", website.Alias, "php-pool", "php-fpm.sock"))
}
if runtimeConfig.ProxyType == constant.RuntimeProxyTcp {
proxy = fmt.Sprintf("127.0.0.1:%d", runtimeConfig.Port)
}
server.UpdatePHPProxy([]string{proxy}, localPath)
}
}
if runtime.Resource == constant.ResourceAppstore {
switch runtime.Type {
case constant.RuntimePHP:
server.UpdateRoot(path.Join("/www/sites", website.Alias, "index"))
server.UpdateRoot(rootIndex)
proxy := fmt.Sprintf("127.0.0.1:%d", appInstall.HttpPort)
server.UpdatePHPProxy([]string{proxy})
server.UpdatePHPProxy([]string{proxy}, "")
}
}
}

View File

@ -9,4 +9,7 @@ const (
RuntimeBuildIng = "building"
RuntimePHP = "php"
RuntimeProxyUnix = "unix"
RuntimeProxyTcp = "tcp"
)

View File

@ -41,4 +41,7 @@ const (
AccessLog = "access.log"
ErrorLog = "error.log"
ConfigPHP = "php"
ConfigFPM = "fpm"
)

View File

@ -31,7 +31,7 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) {
groupRouter.POST("/domains/del", baseApi.DeleteWebDomain)
groupRouter.POST("/domains", baseApi.CreateWebDomain)
groupRouter.GET("/:id/nginx", baseApi.GetWebsiteNginx)
groupRouter.GET("/:id/config/:type", baseApi.GetWebsiteNginx)
groupRouter.POST("/config", baseApi.GetNginxConfig)
groupRouter.POST("/config/update", baseApi.UpdateNginxConfig)
groupRouter.POST("/nginx/update", baseApi.UpdateWebsiteNginxConfig)

View File

@ -237,7 +237,7 @@ func (s *Server) UpdateRootProxy(proxy []string) {
s.UpdateDirectiveBySecondKey("location", "/", newDir)
}
func (s *Server) UpdatePHPProxy(proxy []string) {
func (s *Server) UpdatePHPProxy(proxy []string, localPath string) {
newDir := Directive{
Name: "location",
Parameters: []string{"~ [^/]\\.php(/|$)"},
@ -256,6 +256,17 @@ func (s *Server) UpdatePHPProxy(proxy []string) {
Name: "include",
Parameters: []string{"fastcgi_params"},
})
if localPath == "" {
block.Directives = append(block.Directives, &Directive{
Name: "fastcgi_param",
Parameters: []string{"SCRIPT_FILENAME", "$document_root$fastcgi_script_name"},
})
} else {
block.Directives = append(block.Directives, &Directive{
Name: "fastcgi_param",
Parameters: []string{"SCRIPT_FILENAME", localPath},
})
}
newDir.Block = block
s.UpdateDirectiveBySecondKey("location", "~ [^/]\\.php(/|$)", newDir)
}

View File

@ -16,6 +16,7 @@ export namespace Website {
autoRenew: boolean;
appinstall?: NewAppInstall;
webSiteSSL: SSL;
runtimeID: number;
}
export interface WebsiteDTO extends Website {

View File

@ -35,8 +35,8 @@ export const GetWebsiteOptions = () => {
return http.get<Array<string>>(`/websites/options`);
};
export const GetWebsiteNginx = (id: number) => {
return http.get<File.File>(`/websites/${id}/nginx`);
export const GetWebsiteConfig = (id: number, type: string) => {
return http.get<File.File>(`/websites/${id}/config/${type}`);
};
export const DeleteWebsite = (req: Website.WebSiteDel) => {

View File

@ -1138,6 +1138,7 @@ const message = {
runtime: 'Runtime',
deleteRuntimeHelper:
'The Runtime application needs to be deleted together with the website, please handle it with caution',
proxyType: 'Listening Network Type',
},
nginx: {
serverNamesHashBucketSizeHelper: 'The hash table size of the server name',

View File

@ -1136,6 +1136,11 @@ const message = {
runtimeProxyHelper: '使用从 1Panel 创建的运行环境',
runtime: '运行环境',
deleteRuntimeHelper: '运行环境应用需要跟网站一并删除请谨慎处理',
proxyType: '监听网络类型',
unix: 'Uinx 网络',
tcp: 'TCP/IP 网络',
phpFPM: 'FPM 配置文件',
phpConfig: 'PHP 配置文件',
},
nginx: {
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',

View File

@ -1,10 +1,23 @@
<template>
<Nginx :id="id"></Nginx>
<el-tabs tab-position="left" v-model="index">
<el-tab-pane :label="'OpenResty'" name="0">
<Nginx :id="id" v-if="index == '0'"></Nginx>
</el-tab-pane>
<el-tab-pane :label="'FPM'" name="1">
<PHP :id="id" v-if="index == '1'" :installId="installId" :type="'fpm'"></PHP>
</el-tab-pane>
<el-tab-pane :label="'PHP'" name="2">
<PHP :id="id" v-if="index == '2'" :installId="installId" :type="'php'"></PHP>
</el-tab-pane>
</el-tabs>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { GetRuntime } from '@/api/modules/runtime';
import { GetWebsite } from '@/api/modules/website';
import { computed, onMounted, ref } from 'vue';
import Nginx from './nginx/index.vue';
import PHP from './php-fpm/index.vue';
const props = defineProps({
id: {
@ -16,4 +29,23 @@ const props = defineProps({
const id = computed(() => {
return props.id;
});
let index = ref('0');
let configPHP = ref(false);
let installId = ref(0);
const getWebsiteDetail = async () => {
const res = await GetWebsite(props.id);
if (res.data.type === 'runtime') {
installId.value = res.data.appInstallId;
const runRes = await GetRuntime(res.data.runtimeID);
if (runRes.data.resource === 'appstore') {
configPHP.value = true;
}
}
};
onMounted(() => {
getWebsiteDetail();
});
</script>

View File

@ -23,7 +23,7 @@
<script lang="ts" setup>
import { Codemirror } from 'vue-codemirror';
import { oneDark } from '@codemirror/theme-one-dark';
import { GetWebsiteNginx, UpdateNginxFile } from '@/api/modules/website';
import { GetWebsiteConfig, UpdateNginxFile } from '@/api/modules/website';
import { computed, onMounted, ref } from 'vue';
import { File } from '@/api/interface/file';
import i18n from '@/lang';
@ -50,7 +50,7 @@ let content = ref('');
const get = () => {
loading.value = true;
GetWebsiteNginx(id.value)
GetWebsiteConfig(id.value, 'openresty')
.then((res) => {
data.value = res.data;
content.value = data.value.content;

View File

@ -0,0 +1,91 @@
<template>
<div v-loading="loading">
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; max-height: 700px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="content"
/>
<div style="margin-top: 10px">
<el-button type="primary" @click="submit()">
{{ $t('nginx.saveAndReload') }}
</el-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { Codemirror } from 'vue-codemirror';
import { oneDark } from '@codemirror/theme-one-dark';
import { GetWebsiteConfig } from '@/api/modules/website';
import { InstalledOp } from '@/api/modules/app';
import { computed, onMounted, ref } from 'vue';
import { File } from '@/api/interface/file';
import i18n from '@/lang';
import { StreamLanguage } from '@codemirror/language';
import { nginx } from '@codemirror/legacy-modes/mode/nginx';
import { MsgSuccess } from '@/utils/message';
const extensions = [StreamLanguage.define(nginx), oneDark];
const props = defineProps({
id: {
type: Number,
default: 0,
},
type: {
type: String,
default: 'fpm',
},
installId: {
type: Number,
default: 0,
},
});
const id = computed(() => {
return props.id;
});
let data = ref<File.File>();
let loading = ref(false);
let content = ref('');
const get = () => {
loading.value = true;
GetWebsiteConfig(id.value, props.type)
.then((res) => {
data.value = res.data;
content.value = data.value.content;
})
.finally(() => {
loading.value = false;
});
};
const submit = async () => {
loading.value = true;
let operateReq = {
installId: props.installId,
operate: 'restart',
};
await InstalledOp(operateReq)
.then(() => {
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
})
.catch(() => {})
.finally(() => {
loading.value = false;
});
};
onMounted(() => {
get();
});
</script>

View File

@ -139,7 +139,7 @@
</el-row>
</el-form-item>
<el-form-item :label="$t('app.name')" prop="appinstall.name">
<el-input v-model="website.appinstall.name"></el-input>
<el-input v-model.trim="website.appinstall.name"></el-input>
</el-form-item>
<Params
:key="paramKey"
@ -152,22 +152,34 @@
</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-select v-model="website.runtimeID" @change="changeRuntime(website.runtimeID)">
<el-option
v-for="(runtime, index) in runtimes"
v-for="(run, index) in runtimes"
:key="index"
:label="runtime.name"
:value="runtime.id"
:label="run.name + '(' + $t('runtime.' + run.resource) + ')'"
:value="run.id"
></el-option>
</el-select>
</el-form-item>
<Params
v-if="runtimeResource === 'appstore'"
:key="paramKey"
v-model:form="website.appinstall.params"
v-model:rules="rules.appinstall.params"
:params="appParams"
:propStart="'appinstall.params.'"
></Params>
<div v-else>
<el-form-item :label="$t('website.proxyType')" prop="proxyType">
<el-select v-model="website.proxyType">
<el-option :label="$t('website.tcp')" :value="'tcp'"></el-option>
<el-option :label="$t('website.unix')" :value="'unix'"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="website.proxyType === 'tcp'" :label="$t('website.port')" prop="port">
<el-input v-model.number="website.port"></el-input>
</el-form-item>
</div>
</div>
<el-form-item :label="$t('website.primaryDomain')" prop="primaryDomain">
<el-input
@ -250,6 +262,8 @@ const website = ref({
version: '',
appkey: '',
},
proxyType: 'tcp',
port: 9000,
});
let rules = ref<any>({
primaryDomain: [Rules.domain],
@ -265,6 +279,8 @@ let rules = ref<any>({
appId: [Rules.requiredSelectBusiness],
params: {},
},
proxyType: [Rules.requiredSelect],
port: [Rules.port],
});
let open = ref(false);
@ -284,6 +300,7 @@ let appParams = ref<App.AppParams>();
let paramKey = ref(1);
let preCheckRef = ref();
let staticPath = ref('');
let runtimeResource = ref('appstore');
const runtimeReq = ref<Runtime.RuntimeReq>({
page: 1,
pageSize: 20,
@ -367,6 +384,14 @@ const getAppDetailByID = (id: number) => {
});
};
const changeRuntime = (runID: number) => {
runtimes.value.forEach((item) => {
if (item.id === runID) {
runtimeResource.value = item.resource;
}
});
};
const getRuntimes = async () => {
try {
const res = await SearchRuntimes(runtimeReq.value);
@ -374,6 +399,7 @@ const getRuntimes = async () => {
if (runtimes.value.length > 0) {
const first = runtimes.value[0];
website.value.runtimeID = first.id;
runtimeResource.value = first.resource;
getAppDetailByID(first.appDetailId);
}
} catch (error) {}
@ -387,10 +413,13 @@ const acceptParams = async (installPath: string) => {
const res = await GetGroupList({ type: 'website' });
groups.value = res.data;
open.value = true;
website.value.webSiteGroupId = res.data[0].id;
website.value.type = 'deployment';
runtimeResource.value = 'appstore';
searchAppInstalled();
open.value = true;
};
const changeAppType = (type: string) => {