diff --git a/backend/app/api/v1/app.go b/backend/app/api/v1/app.go index 4e2d1ffe2..882ee59ba 100644 --- a/backend/app/api/v1/app.go +++ b/backend/app/api/v1/app.go @@ -76,9 +76,10 @@ func (b *BaseApi) GetApp(c *gin.Context) { // @Accept json // @Param appId path integer true "app id" // @Param version path string true "app 版本" +// @Param version path string true "app 类型" // @Success 200 {object} response.AppDetailDTO // @Security ApiKeyAuth -// @Router /apps/detail/:appId/:version [get] +// @Router /apps/detail/:appId/:version/:type [get] func (b *BaseApi) GetAppDetail(c *gin.Context) { appId, err := helper.GetIntParamByKey(c, "appId") if err != nil { @@ -86,7 +87,8 @@ func (b *BaseApi) GetAppDetail(c *gin.Context) { return } version := c.Param("version") - appDetailDTO, err := appService.GetAppDetail(appId, version) + appType := c.Param("type") + appDetailDTO, err := appService.GetAppDetail(appId, version, appType) if err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return diff --git a/backend/app/api/v1/runtime.go b/backend/app/api/v1/runtime.go index c72398c0e..863582e7f 100644 --- a/backend/app/api/v1/runtime.go +++ b/backend/app/api/v1/runtime.go @@ -32,3 +32,25 @@ func (b *BaseApi) SearchRuntimes(c *gin.Context) { Items: items, }) } + +// @Tags Runtime +// @Summary Create runtime +// @Description 创建运行环境 +// @Accept json +// @Param request body request.RuntimeCreate true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Router /runtimes [post] +// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建运行环境 [name]","formatEN":"Create runtime [name]"} +func (b *BaseApi) CreateRuntime(c *gin.Context) { + var req request.RuntimeCreate + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + if err := runtimeService.Create(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, nil) +} diff --git a/backend/app/dto/request/runtime.go b/backend/app/dto/request/runtime.go index 3fac16d0f..6ed5f6dfd 100644 --- a/backend/app/dto/request/runtime.go +++ b/backend/app/dto/request/runtime.go @@ -7,3 +7,13 @@ type RuntimeSearch struct { Type string `json:"type"` Name string `json:"name"` } + +type RuntimeCreate struct { + AppDetailID uint `json:"appDetailId"` + Name string `json:"name"` + Params map[string]interface{} `json:"params"` + Resource string `json:"resource"` + Image string `json:"image"` + Type string `json:"type"` + Version string `json:"version"` +} diff --git a/backend/app/model/runtime.go b/backend/app/model/runtime.go index 3892623fe..de2e002f6 100644 --- a/backend/app/model/runtime.go +++ b/backend/app/model/runtime.go @@ -4,10 +4,14 @@ type Runtime struct { BaseModel Name string `gorm:"type:varchar;not null" json:"name"` AppDetailID uint `gorm:"type:integer" json:"appDetailId"` - Image string `gorm:"type:varchar;not null" json:"image"` - WorkDir string `gorm:"type:varchar;not null" json:"workDir"` - DockerCompose string `gorm:"type:varchar;not null" json:"dockerCompose"` - Env string `gorm:"type:varchar;not null" json:"env"` - Params string `gorm:"type:varchar;not null" json:"params"` + Image string `gorm:"type:varchar" json:"image"` + WorkDir string `gorm:"type:varchar" json:"workDir"` + DockerCompose string `gorm:"type:varchar" json:"dockerCompose"` + Env string `gorm:"type:varchar" json:"env"` + Params string `gorm:"type:varchar" json:"params"` + Version string `gorm:"type:varchar;not null" json:"version"` Type string `gorm:"type:varchar;not null" json:"type"` + Status string `gorm:"type:varchar;not null" json:"status"` + Resource string `gorm:"type:varchar;not null" json:"resource"` + Message string `gorm:"type:longtext;" json:"message"` } diff --git a/backend/app/repo/app.go b/backend/app/repo/app.go index 9fc34f790..b3810f8d7 100644 --- a/backend/app/repo/app.go +++ b/backend/app/repo/app.go @@ -58,7 +58,7 @@ func (a AppRepo) Page(page, size int, opts ...DBOption) (int64, []model.App, err db := getDb(opts...).Model(&model.App{}) count := int64(0) db = db.Count(&count) - err := db.Limit(size).Offset(size * (page - 1)).Preload("AppTags").Find(&apps).Error + err := db.Debug().Limit(size).Offset(size * (page - 1)).Preload("AppTags").Find(&apps).Error return count, apps, err } diff --git a/backend/app/service/app.go b/backend/app/service/app.go index c75c104d5..2a77fa9e8 100644 --- a/backend/app/service/app.go +++ b/backend/app/service/app.go @@ -32,7 +32,7 @@ type IAppService interface { PageApp(req request.AppSearch) (interface{}, error) GetAppTags() ([]response.TagDTO, error) GetApp(key string) (*response.AppDTO, error) - GetAppDetail(appId uint, version string) (response.AppDetailDTO, error) + GetAppDetail(appId uint, version, appType string) (response.AppDetailDTO, error) Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error) SyncAppList() error GetAppUpdate() (*response.AppUpdateRes, error) @@ -138,7 +138,7 @@ func (a AppService) GetApp(key string) (*response.AppDTO, error) { return &appDTO, nil } -func (a AppService) GetAppDetail(appId uint, version string) (response.AppDetailDTO, error) { +func (a AppService) GetAppDetail(appId uint, version, appType string) (response.AppDetailDTO, error) { var ( appDetailDTO response.AppDetailDTO opts []repo.DBOption @@ -148,14 +148,36 @@ func (a AppService) GetAppDetail(appId uint, version string) (response.AppDetail if err != nil { return appDetailDTO, err } - paramMap := make(map[string]interface{}) - if err := json.Unmarshal([]byte(detail.Params), ¶mMap); err != nil { - return appDetailDTO, err - } appDetailDTO.AppDetail = detail - appDetailDTO.Params = paramMap appDetailDTO.Enable = true + if appType == "runtime" { + app, err := appRepo.GetFirst(commonRepo.WithByID(appId)) + if err != nil { + return appDetailDTO, err + } + paramsPath := path.Join(constant.AppResourceDir, app.Key, "versions", detail.Version, "build", "config.json") + fileOp := files.NewFileOp() + if !fileOp.Stat(paramsPath) { + return appDetailDTO, buserr.New(constant.ErrFileNotExist) + } + param, err := fileOp.GetContent(paramsPath) + if err != nil { + return appDetailDTO, err + } + paramMap := make(map[string]interface{}) + if err := json.Unmarshal(param, ¶mMap); err != nil { + return appDetailDTO, err + } + appDetailDTO.Params = paramMap + } else { + paramMap := make(map[string]interface{}) + if err := json.Unmarshal([]byte(detail.Params), ¶mMap); err != nil { + return appDetailDTO, err + } + appDetailDTO.Params = paramMap + } + app, err := appRepo.GetFirst(commonRepo.WithByID(detail.AppId)) if err != nil { return appDetailDTO, err diff --git a/backend/app/service/runtime.go b/backend/app/service/runtime.go index e2908e040..e79f797f5 100644 --- a/backend/app/service/runtime.go +++ b/backend/app/service/runtime.go @@ -1,9 +1,17 @@ package service import ( + "context" "github.com/1Panel-dev/1Panel/backend/app/dto/request" "github.com/1Panel-dev/1Panel/backend/app/dto/response" + "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/app/repo" + "github.com/1Panel-dev/1Panel/backend/buserr" + "github.com/1Panel-dev/1Panel/backend/constant" + "github.com/1Panel-dev/1Panel/backend/utils/docker" + "github.com/1Panel-dev/1Panel/backend/utils/files" + "github.com/subosito/gotenv" + "path" ) type RuntimeService struct { @@ -11,14 +19,96 @@ type RuntimeService struct { type IRuntimeService interface { Page(req request.RuntimeSearch) (int64, []response.RuntimeRes, error) + Create(create request.RuntimeCreate) error } func NewRuntimeService() IRuntimeService { return &RuntimeService{} } -func (r *RuntimeService) Create() { - +func (r *RuntimeService) Create(create request.RuntimeCreate) error { + if create.Resource == constant.ResourceLocal { + runtime := &model.Runtime{ + Name: create.Name, + Resource: create.Resource, + Type: create.Type, + Status: constant.RuntimeNormal, + } + return runtimeRepo.Create(context.Background(), runtime) + } + var err error + appDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(create.AppDetailID)) + if err != nil { + return err + } + app, err := appRepo.GetFirst(commonRepo.WithByID(appDetail.AppId)) + if err != nil { + return err + } + fileOp := files.NewFileOp() + buildDir := path.Join(constant.AppResourceDir, app.Key, "versions", appDetail.Version, "build") + if !fileOp.Stat(buildDir) { + return buserr.New(constant.ErrDirNotFound) + } + tempDir := path.Join(constant.RuntimeDir, app.Key) + if err := fileOp.CopyDir(buildDir, tempDir); err != nil { + return err + } + oldDir := path.Join(tempDir, "build") + newNameDir := path.Join(tempDir, create.Name) + defer func(defErr *error) { + if defErr != nil { + _ = fileOp.DeleteDir(newNameDir) + } + }(&err) + if oldDir != newNameDir { + if err := fileOp.Rename(oldDir, newNameDir); err != nil { + return err + } + } + composeFile, err := fileOp.GetContent(path.Join(newNameDir, "docker-compose.yml")) + if err != nil { + return err + } + env, err := gotenv.Read(path.Join(newNameDir, ".env")) + if err != nil { + return err + } + newMap := make(map[string]string) + handleMap(create.Params, newMap) + for k, v := range newMap { + env[k] = v + } + envStr, err := gotenv.Marshal(env) + if err != nil { + return err + } + if err := gotenv.Write(env, path.Join(newNameDir, ".env")); err != nil { + return err + } + project, err := docker.GetComposeProject(create.Name, newNameDir, composeFile, []byte(envStr)) + if err != nil { + return err + } + composeService, err := docker.NewComposeService() + if err != nil { + return err + } + composeService.SetProject(project) + if err := composeService.ComposeBuild(); err != nil { + return err + } + runtime := &model.Runtime{ + Name: create.Name, + DockerCompose: string(composeFile), + Env: envStr, + AppDetailID: create.AppDetailID, + Type: create.Type, + Image: create.Image, + Resource: create.Resource, + Status: constant.RuntimeNormal, + } + return runtimeRepo.Create(context.Background(), runtime) } func (r *RuntimeService) Page(req request.RuntimeSearch) (int64, []response.RuntimeRes, error) { diff --git a/backend/app/service/runtime_utils.go b/backend/app/service/runtime_utils.go new file mode 100644 index 000000000..6d43c3366 --- /dev/null +++ b/backend/app/service/runtime_utils.go @@ -0,0 +1 @@ +package service diff --git a/backend/constant/errs.go b/backend/constant/errs.go index c87c5ed00..4734c6b6b 100644 --- a/backend/constant/errs.go +++ b/backend/constant/errs.go @@ -62,7 +62,7 @@ var ( Err1PanelNetworkFailed = "Err1PanelNetworkFailed" ) -//website +// website var ( ErrDomainIsExist = "ErrDomainIsExist" ErrAliasIsExist = "ErrAliasIsExist" @@ -70,7 +70,7 @@ var ( ErrGroupIsUsed = "ErrGroupIsUsed" ) -//ssl +// ssl var ( ErrSSLCannotDelete = "ErrSSLCannotDelete" ErrAccountCannotDelete = "ErrAccountCannotDelete" @@ -78,7 +78,7 @@ var ( ErrEmailIsExist = "ErrEmailIsExist" ) -//file +// file var ( ErrPathNotFound = "ErrPathNotFound" ErrMovePathFailed = "ErrMovePathFailed" @@ -87,19 +87,26 @@ var ( ErrFileUpload = "ErrFileUpload" ) -//mysql +// mysql var ( ErrUserIsExist = "ErrUserIsExist" ErrDatabaseIsExist = "ErrDatabaseIsExist" ) -//redis +// redis var ( ErrTypeOfRedis = "ErrTypeOfRedis" ) -//container +// container var ( ErrInUsed = "ErrInUsed" ErrObjectInUsed = "ErrObjectInUsed" ) + +//runtime + +var ( + ErrDirNotFound = "ErrDirNotFound" + ErrFileNotExist = "ErrFileNotExist" +) diff --git a/backend/constant/runtime.go b/backend/constant/runtime.go new file mode 100644 index 000000000..1363a0db7 --- /dev/null +++ b/backend/constant/runtime.go @@ -0,0 +1,10 @@ +package constant + +const ( + ResourceLocal = "Local" + ResourceAppstore = "Appstore" + + RuntimeNormal = "Normal" + RuntimeBuildSuccess = "BuildSuccess" + RuntimeBuildFailed = "BuildFailed" +) diff --git a/backend/i18n/lang/en.yaml b/backend/i18n/lang/en.yaml index dc9a4c41a..68d098ec0 100644 --- a/backend/i18n/lang/en.yaml +++ b/backend/i18n/lang/en.yaml @@ -58,4 +58,8 @@ ErrTypeOfRedis: "The recovery file type does not match the current persistence m #container ErrInUsed: "{{ .detail }} is in use and cannot be deleted" -ErrObjectInUsed: "This object is in use and cannot be deleted" \ No newline at end of file +ErrObjectInUsed: "This object is in use and cannot be deleted" + +#runtime +ErrDirNotFound: "The build folder does not exist! Please check file integrity!" +ErrFileNotExist: "{{ .detail }} file does not exist! Please check source file integrity!" \ No newline at end of file diff --git a/backend/i18n/lang/zh.yaml b/backend/i18n/lang/zh.yaml index 62b34afb6..de2f02f1c 100644 --- a/backend/i18n/lang/zh.yaml +++ b/backend/i18n/lang/zh.yaml @@ -58,4 +58,8 @@ ErrTypeOfRedis: "恢复文件类型与当前持久化方式不符,请修改后 #container ErrInUsed: "{{ .detail }} 正被使用,无法删除" -ErrObjectInUsed: "该对象正被使用,无法删除" \ No newline at end of file +ErrObjectInUsed: "该对象正被使用,无法删除" + +#runtime +ErrDirNotFound: "build 文件夹不存在!请检查文件完整性!" +ErrFileNotExist: "{{ .detail }} 文件不存在!请检查源文件完整性!" \ No newline at end of file diff --git a/backend/init/app/app.go b/backend/init/app/app.go index ce4ae65c6..8fea7bcca 100644 --- a/backend/init/app/app.go +++ b/backend/init/app/app.go @@ -14,8 +14,9 @@ func Init() { constant.ResourceDir = path.Join(constant.DataDir, "resource") constant.AppResourceDir = path.Join(constant.ResourceDir, "apps") constant.AppInstallDir = path.Join(constant.DataDir, "apps") + constant.RuntimeDir = path.Join(constant.DataDir, "runtime") - dirs := []string{constant.DataDir, constant.ResourceDir, constant.AppResourceDir, constant.AppInstallDir, global.CONF.System.Backup} + dirs := []string{constant.DataDir, constant.ResourceDir, constant.AppResourceDir, constant.AppInstallDir, global.CONF.System.Backup, constant.RuntimeDir} fileOp := files.NewFileOp() for _, dir := range dirs { diff --git a/backend/init/migration/migrations/init.go b/backend/init/migration/migrations/init.go index 6329fdaee..6c5919960 100644 --- a/backend/init/migration/migrations/init.go +++ b/backend/init/migration/migrations/init.go @@ -249,7 +249,7 @@ var AddDefaultGroup = &gormigrate.Migration{ } var AddTableRuntime = &gormigrate.Migration{ - ID: "20230328-add-table-runtime", + ID: "20230330-add-table-runtime", Migrate: func(tx *gorm.DB) error { return tx.AutoMigrate(&model.Runtime{}) }, diff --git a/backend/router/ro_app.go b/backend/router/ro_app.go index 66bc9e251..9c253cbe4 100644 --- a/backend/router/ro_app.go +++ b/backend/router/ro_app.go @@ -19,7 +19,7 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) { appRouter.GET("/checkupdate", baseApi.GetAppListUpdate) appRouter.POST("/search", baseApi.SearchApp) appRouter.GET("/:key", baseApi.GetApp) - appRouter.GET("/detail/:appId/:version", baseApi.GetAppDetail) + appRouter.GET("/detail/:appId/:version/:type", baseApi.GetAppDetail) appRouter.POST("/install", baseApi.InstallApp) appRouter.GET("/tags", baseApi.GetAppTags) appRouter.GET("/installed/:appInstallId/versions", baseApi.GetUpdateVersions) diff --git a/backend/router/ro_runtime.go b/backend/router/ro_runtime.go index 6d2928aec..d8755c36e 100644 --- a/backend/router/ro_runtime.go +++ b/backend/router/ro_runtime.go @@ -16,5 +16,6 @@ func (r *RuntimeRouter) InitRuntimeRouter(Router *gin.RouterGroup) { baseApi := v1.ApiGroupApp.BaseApi { groupRouter.POST("/search", baseApi.SearchRuntimes) + groupRouter.POST("", baseApi.CreateRuntime) } } diff --git a/backend/utils/docker/compose.go b/backend/utils/docker/compose.go index 882ea5bdd..882124999 100644 --- a/backend/utils/docker/compose.go +++ b/backend/utils/docker/compose.go @@ -83,6 +83,10 @@ func (s *ComposeService) ComposeCreate() error { return s.Create(context.Background(), s.project, api.CreateOptions{}) } +func (s *ComposeService) ComposeBuild() error { + return s.Build(context.Background(), s.project, api.BuildOptions{}) +} + func GetComposeProject(projectName, workDir string, yml []byte, env []byte) (*types.Project, error) { var configFiles []types.ConfigFile configFiles = append(configFiles, types.ConfigFile{ diff --git a/backend/utils/files/file_op.go b/backend/utils/files/file_op.go index cb3b18564..c6bb227c9 100644 --- a/backend/utils/files/file_op.go +++ b/backend/utils/files/file_op.go @@ -37,6 +37,15 @@ func (f FileOp) OpenFile(dst string) (fs.File, error) { return f.Fs.Open(dst) } +func (f FileOp) GetContent(dst string) ([]byte, error) { + afs := &afero.Afero{Fs: f.Fs} + cByte, err := afs.ReadFile(dst) + if err != nil { + return nil, err + } + return cByte, nil +} + func (f FileOp) CreateDir(dst string, mode fs.FileMode) error { return f.Fs.MkdirAll(dst, mode) } diff --git a/frontend/src/api/interface/app.ts b/frontend/src/api/interface/app.ts index cc2372251..67a0c32ee 100644 --- a/frontend/src/api/interface/app.ts +++ b/frontend/src/api/interface/app.ts @@ -64,6 +64,7 @@ export namespace App { values?: ServiceParam[]; child?: FromFieldChild; params?: FromParam[]; + multiple?: boolean; } export interface FromFieldChild extends FromField { diff --git a/frontend/src/api/interface/runtime.ts b/frontend/src/api/interface/runtime.ts index aa7721482..bdaa52008 100644 --- a/frontend/src/api/interface/runtime.ts +++ b/frontend/src/api/interface/runtime.ts @@ -18,4 +18,15 @@ export namespace Runtime { export interface RuntimeDTO extends Runtime { websites: string[]; } + + export interface RuntimeCreate { + name: string; + appDetailId: number; + image: string; + params: object; + type: string; + resource: string; + appId?: number; + version?: string; + } } diff --git a/frontend/src/api/modules/app.ts b/frontend/src/api/modules/app.ts index 0b39fee46..543a6af75 100644 --- a/frontend/src/api/modules/app.ts +++ b/frontend/src/api/modules/app.ts @@ -22,8 +22,8 @@ export const GetAppTags = () => { return http.get('apps/tags'); }; -export const GetAppDetail = (id: number, version: string) => { - return http.get(`apps/detail/${id}/${version}`); +export const GetAppDetail = (id: number, version: string, type: string) => { + return http.get(`apps/detail/${id}/${version}/${type}`); }; export const InstallApp = (install: App.AppInstall) => { diff --git a/frontend/src/api/modules/runtime.ts b/frontend/src/api/modules/runtime.ts index 319410b28..076cbadb4 100644 --- a/frontend/src/api/modules/runtime.ts +++ b/frontend/src/api/modules/runtime.ts @@ -5,3 +5,7 @@ import { Runtime } from '../interface/runtime'; export const SearchRuntimes = (req: Runtime.RuntimeReq) => { return http.post>(`/runtimes/search`, req); }; + +export const CreateRuntime = (req: Runtime.RuntimeCreate) => { + return http.post(`/runtimes`, req); +}; diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 13f4002ab..0c1192b9a 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1228,6 +1228,14 @@ const message = { runtime: '运行环境', image: '镜像', workDir: '工作目录', + create: '创建运行环境', + name: '名称', + resource: '来源', + appStore: '应用商店', + local: '本地', + app: '应用', + localHelper: '本地运行环境需要自行安装', + version: '版本', }, }; export default { diff --git a/frontend/src/routers/modules/website.ts b/frontend/src/routers/modules/website.ts index e48dbcf66..2e8a22aba 100644 --- a/frontend/src/routers/modules/website.ts +++ b/frontend/src/routers/modules/website.ts @@ -40,7 +40,7 @@ const webSiteRouter = { }, }, { - path: '/websites/runtime', + path: '/websites/runtime/php', name: 'Runtime', component: () => import('@/views/website/runtime/index.vue'), meta: { diff --git a/frontend/src/views/app-store/detail/index.vue b/frontend/src/views/app-store/detail/index.vue index 31ff68036..5e9ec2f66 100644 --- a/frontend/src/views/app-store/detail/index.vue +++ b/frontend/src/views/app-store/detail/index.vue @@ -131,7 +131,7 @@ const getApp = async () => { const getDetail = async (id: number, version: string) => { loadingDetail.value = true; try { - const res = await GetAppDetail(id, version); + const res = await GetAppDetail(id, version, 'app'); appDetail.value = res.data; } finally { loadingDetail.value = false; diff --git a/frontend/src/views/website/runtime/create/index.vue b/frontend/src/views/website/runtime/create/index.vue new file mode 100644 index 000000000..635f3c6f2 --- /dev/null +++ b/frontend/src/views/website/runtime/create/index.vue @@ -0,0 +1,190 @@ + + + diff --git a/frontend/src/views/website/runtime/index.vue b/frontend/src/views/website/runtime/index.vue index 9595b3296..2bb80a56f 100644 --- a/frontend/src/views/website/runtime/index.vue +++ b/frontend/src/views/website/runtime/index.vue @@ -4,12 +4,16 @@ :buttons="[ { label: 'PHP', - path: '/runtimes', + path: '/runtimes/php', }, ]" /> - + + @@ -35,10 +40,11 @@ import { onMounted, reactive, ref } from 'vue'; import { Runtime } from '@/api/interface/runtime'; import { SearchRuntimes } from '@/api/modules/runtime'; +import { dateFormat } from '@/utils/util'; import RouterButton from '@/components/router-button/index.vue'; import ComplexTable from '@/components/complex-table/index.vue'; import LayoutContent from '@/layout/layout-content.vue'; -import { dateFormat } from '@/utils/util'; +import CreateRuntime from '@/views/website/runtime/create/index.vue'; const paginationConfig = reactive({ currentPage: 1, @@ -52,6 +58,7 @@ let req = reactive({ }); const loading = ref(false); const items = ref([]); +const createRef = ref(); const search = async () => { req.page = paginationConfig.currentPage; @@ -67,6 +74,10 @@ const search = async () => { } }; +const openCreate = () => { + createRef.value.acceptParams(); +}; + onMounted(() => { search(); }); diff --git a/frontend/src/views/website/runtime/param/index.vue b/frontend/src/views/website/runtime/param/index.vue new file mode 100644 index 000000000..3d9929d90 --- /dev/null +++ b/frontend/src/views/website/runtime/param/index.vue @@ -0,0 +1,94 @@ + + + diff --git a/frontend/src/views/website/website/create/index.vue b/frontend/src/views/website/website/create/index.vue index 55188a9ac..56f563eeb 100644 --- a/frontend/src/views/website/website/create/index.vue +++ b/frontend/src/views/website/website/create/index.vue @@ -310,7 +310,7 @@ const getApp = () => { }; const getAppDetail = (version: string) => { - GetAppDetail(website.value.appinstall.appId, version).then((res) => { + GetAppDetail(website.value.appinstall.appId, version, 'app').then((res) => { website.value.appinstall.appDetailId = res.data.id; appDetail.value = res.data; appParams.value = res.data.params;